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 <[email protected]>
> ---
>  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 <[email protected]>

Reply via email to