target/i386: Skip supervisor in xsave decompaction
Supervisor state should be skipped b/c there is no slot in standard format XSAVE buffer for it. CET State is being migrated via MSRs and other supervisor state isn't currently migrated. Fixes: 8612deb3f4 Signed-off-by: Magnus Kulke <magnuskulke@linux.microsoft.com> Reviewed-by: Doru Blânzeanu <dblanzeanu@linux.microsoft.com> Link: https://lore.kernel.org/r/20260702124746.450228-1-magnuskulke@linux.microsoft.com Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Magnus Kulke committed
Jul 2, 2026 at 14:47 UTC
654d4cd059a541f56091dbfe9220806fd9b51a07
2 files changed
+12
-3
target/i386/cpu.h
+2
@@ -655,9 +655,11 @@ typedef enum X86Seg {
655
656
#define XSTATE_DYNAMIC_MASK (XSTATE_XTILE_DATA_MASK)
657
658
+#define ESA_FEATURE_XSS_BIT 0
659
#define ESA_FEATURE_ALIGN64_BIT 1
660
#define ESA_FEATURE_XFD_BIT 2
661
662
+#define ESA_FEATURE_XSS_MASK (1U << ESA_FEATURE_XSS_BIT)
663
#define ESA_FEATURE_ALIGN64_MASK (1U << ESA_FEATURE_ALIGN64_BIT)
664
#define ESA_FEATURE_XFD_MASK (1U << ESA_FEATURE_XFD_BIT)
665
target/i386/xsave_helper.c
+10
-3
@@ -332,7 +332,7 @@ int decompact_xsave_area(const void *buf, size_t buflen, CPUX86State *env)
332
size_t i;
333
uint32_t eax, ebx, ecx, edx;
334
uint32_t size, dst_off;
335
- bool align64;
335
+ bool align64, supervisor;
336
uint64_t guest_xcr0, *xstate_bv;
337
338
compacted_xstate_bv = *(uint64_t *)(buf + XSAVE_XSTATE_BV_OFFSET);
@@ -383,6 +383,7 @@ int decompact_xsave_area(const void *buf, size_t buflen, CPUX86State *env)
383
size = eax;
384
dst_off = ebx;
385
align64 = (ecx & (1u << 1)) != 0;
386
+ supervisor = (ecx & ESA_FEATURE_XSS_MASK) != 0;
387
388
/* Component is in the layout but unknown to the guest CPUID model */
389
if (size == 0) {
@@ -433,8 +434,14 @@ int decompact_xsave_area(const void *buf, size_t buflen, CPUX86State *env)
434
return -E2BIG;
435
}
436
436
- /* Copy components marked present in XSTATE_BV to guest model */
437
- if (((compacted_xstate_bv >> i) & 1) != 0) {
437
+ /*
438
+ * Copy components marked present in XSTATE_BV to guest model.
439
+ *
440
+ * NB: Supervisor state is skipped b/c there is no slot in the
441
+ * standard format XSAVE buffer (CET state is migrated via MSRs,
442
+ * others supervisor state isn't migrated).
443
+ */
444
+ if (((compacted_xstate_bv >> i) & 1) != 0 && !supervisor) {
445
memcpy(env->xsave_buf + dst_off, buf + xsave_offset, size);
446
}
447