[PATCH] target/i386: Skip supervisor in xsave decompaction

Magnus Kulke posted 1 patch 3 weeks, 2 days ago
Patches applied successfully (tree, apply log)
git fetch https://github.com/patchew-project/qemu tags/patchew/20260702124746.450228-1-magnuskulke@linux.microsoft.com
Maintainers: Paolo Bonzini <pbonzini@redhat.com>, Zhao Liu <zhao1.liu@intel.com>
target/i386/cpu.h          |  2 ++
target/i386/xsave_helper.c | 13 ++++++++++---
2 files changed, 12 insertions(+), 3 deletions(-)
[PATCH] target/i386: Skip supervisor in xsave decompaction
Posted by Magnus Kulke 3 weeks, 2 days ago
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>
---
 target/i386/cpu.h          |  2 ++
 target/i386/xsave_helper.c | 13 ++++++++++---
 2 files changed, 12 insertions(+), 3 deletions(-)

diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index e6a197602d..fff701c6c4 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -655,9 +655,11 @@ typedef enum X86Seg {
 
 #define XSTATE_DYNAMIC_MASK             (XSTATE_XTILE_DATA_MASK)
 
+#define ESA_FEATURE_XSS_BIT             0
 #define ESA_FEATURE_ALIGN64_BIT         1
 #define ESA_FEATURE_XFD_BIT             2
 
+#define ESA_FEATURE_XSS_MASK            (1U << ESA_FEATURE_XSS_BIT)
 #define ESA_FEATURE_ALIGN64_MASK        (1U << ESA_FEATURE_ALIGN64_BIT)
 #define ESA_FEATURE_XFD_MASK            (1U << ESA_FEATURE_XFD_BIT)
 
diff --git a/target/i386/xsave_helper.c b/target/i386/xsave_helper.c
index 625bae103a..1fa3133b1a 100644
--- a/target/i386/xsave_helper.c
+++ b/target/i386/xsave_helper.c
@@ -332,7 +332,7 @@ int decompact_xsave_area(const void *buf, size_t buflen, CPUX86State *env)
     size_t i;
     uint32_t eax, ebx, ecx, edx;
     uint32_t size, dst_off;
-    bool align64;
+    bool align64, supervisor;
     uint64_t guest_xcr0, *xstate_bv;
 
     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)
         size = eax;
         dst_off = ebx;
         align64 = (ecx & (1u << 1)) != 0;
+        supervisor = (ecx & ESA_FEATURE_XSS_MASK) != 0;
 
         /* Component is in the layout but unknown to the guest CPUID model */
         if (size == 0) {
@@ -433,8 +434,14 @@ int decompact_xsave_area(const void *buf, size_t buflen, CPUX86State *env)
             return -E2BIG;
         }
 
-        /* Copy components marked present in XSTATE_BV to guest model */
-        if (((compacted_xstate_bv >> i) & 1) != 0) {
+        /*
+         * Copy components marked present in XSTATE_BV to guest model.
+         *
+         * NB: Supervisor state is skipped b/c there is no slot in the
+         * standard format XSAVE buffer (CET state is migrated via MSRs,
+         * others supervisor state isn't migrated).
+         */
+        if (((compacted_xstate_bv >> i) & 1) != 0 && !supervisor) {
             memcpy(env->xsave_buf + dst_off, buf + xsave_offset, size);
         }
 
-- 
2.34.1
Re: [PATCH] target/i386: Skip supervisor in xsave decompaction
Posted by Doru Blânzeanu 3 weeks, 2 days ago
On Thu, Jul 02, 2026 at 02:47:46PM +0200, Magnus Kulke wrote:
> 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>
> ---
>  target/i386/cpu.h          |  2 ++
>  target/i386/xsave_helper.c | 13 ++++++++++---
>  2 files changed, 12 insertions(+), 3 deletions(-)
> 
> diff --git a/target/i386/cpu.h b/target/i386/cpu.h
> index e6a197602d..fff701c6c4 100644
> --- a/target/i386/cpu.h
> +++ b/target/i386/cpu.h
> @@ -655,9 +655,11 @@ typedef enum X86Seg {
>  
>  #define XSTATE_DYNAMIC_MASK             (XSTATE_XTILE_DATA_MASK)
>  
> +#define ESA_FEATURE_XSS_BIT             0
>  #define ESA_FEATURE_ALIGN64_BIT         1
>  #define ESA_FEATURE_XFD_BIT             2
>  
> +#define ESA_FEATURE_XSS_MASK            (1U << ESA_FEATURE_XSS_BIT)
>  #define ESA_FEATURE_ALIGN64_MASK        (1U << ESA_FEATURE_ALIGN64_BIT)
>  #define ESA_FEATURE_XFD_MASK            (1U << ESA_FEATURE_XFD_BIT)
>  
> diff --git a/target/i386/xsave_helper.c b/target/i386/xsave_helper.c
> index 625bae103a..1fa3133b1a 100644
> --- a/target/i386/xsave_helper.c
> +++ b/target/i386/xsave_helper.c
> @@ -332,7 +332,7 @@ int decompact_xsave_area(const void *buf, size_t buflen, CPUX86State *env)
>      size_t i;
>      uint32_t eax, ebx, ecx, edx;
>      uint32_t size, dst_off;
> -    bool align64;
> +    bool align64, supervisor;
>      uint64_t guest_xcr0, *xstate_bv;
>  
>      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)
>          size = eax;
>          dst_off = ebx;
>          align64 = (ecx & (1u << 1)) != 0;
> +        supervisor = (ecx & ESA_FEATURE_XSS_MASK) != 0;
>  
>          /* Component is in the layout but unknown to the guest CPUID model */
>          if (size == 0) {
> @@ -433,8 +434,14 @@ int decompact_xsave_area(const void *buf, size_t buflen, CPUX86State *env)
>              return -E2BIG;
>          }
>  
> -        /* Copy components marked present in XSTATE_BV to guest model */
> -        if (((compacted_xstate_bv >> i) & 1) != 0) {
> +        /*
> +         * Copy components marked present in XSTATE_BV to guest model.
> +         *
> +         * NB: Supervisor state is skipped b/c there is no slot in the
> +         * standard format XSAVE buffer (CET state is migrated via MSRs,
> +         * others supervisor state isn't migrated).
> +         */
> +        if (((compacted_xstate_bv >> i) & 1) != 0 && !supervisor) {
>              memcpy(env->xsave_buf + dst_off, buf + xsave_offset, size);
>          }
>  
> -- 
> 2.34.1

Reviewed-by: Doru Blânzeanu <dblanzeanu@linux.microsoft.com>