From 6df46774aa41872a706f1a535d5c547a8ef73556 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Thu, 31 Oct 2024 16:52:27 +0800 Subject: [PATCH 31/38] target/i386: do not rely on ExtSaveArea for accelerator-supported XCR0 bits RH-Author: Paolo Bonzini RH-MergeRequest: 280: Add support for the AVX10.1, SHA512, SM3 and SM4 instruction sets RH-Jira: RHEL-30315 RHEL-45110 RH-Acked-by: Vitaly Kuznetsov RH-Acked-by: Miroslav Rezanina RH-Commit: [2/9] 70d54c2101fd1d30a891a414a8c50566c2ddef67 (bonzini/rhel-qemu-kvm) Right now, QEMU is using the "feature" and "bits" fields of ExtSaveArea to query the accelerator for the support status of extended save areas. This is a problem for AVX10, which attaches two feature bits (AVX512F and AVX10) to the same extended save states. To keep the AVX10 hacks to the minimum, limit usage of esa->features and esa->bits. Instead, just query the accelerator for the 0xD leaf. Do it in common code and clear esa->size if an extended save state is unsupported. Signed-off-by: Paolo Bonzini Reviewed-by: Zhao Liu Link: https://lore.kernel.org/r/20241031085233.425388-3-tao1.su@linux.intel.com Signed-off-by: Paolo Bonzini (cherry picked from commit b888c7807049cc044d10d70139cb945202fb7cd2) Signed-off-by: Paolo Bonzini --- target/i386/cpu.c | 33 +++++++++++++++++++++++++++++++-- target/i386/kvm/kvm-cpu.c | 4 ---- 2 files changed, 31 insertions(+), 6 deletions(-) diff --git a/target/i386/cpu.c b/target/i386/cpu.c index dbdab0f821..d23f15e99a 100644 --- a/target/i386/cpu.c +++ b/target/i386/cpu.c @@ -7086,6 +7086,15 @@ static void x86_cpu_set_sgxlepubkeyhash(CPUX86State *env) #endif } +static bool cpuid_has_xsave_feature(CPUX86State *env, const ExtSaveArea *esa) +{ + if (!esa->size) { + return false; + } + + return (env->features[esa->feature] & esa->bits); +} + static void x86_cpu_reset_hold(Object *obj, ResetType type) { CPUState *cs = CPU(obj); @@ -7194,7 +7203,7 @@ static void x86_cpu_reset_hold(Object *obj, ResetType type) if (!((1 << i) & CPUID_XSTATE_XCR0_MASK)) { continue; } - if (env->features[esa->feature] & esa->bits) { + if (cpuid_has_xsave_feature(env, esa)) { xcr0 |= 1ull << i; } } @@ -7332,7 +7341,7 @@ static void x86_cpu_enable_xsave_components(X86CPU *cpu) mask = 0; for (i = 0; i < ARRAY_SIZE(x86_ext_save_areas); i++) { const ExtSaveArea *esa = &x86_ext_save_areas[i]; - if (env->features[esa->feature] & esa->bits) { + if (cpuid_has_xsave_feature(env, esa)) { mask |= (1ULL << i); } } @@ -8003,6 +8012,26 @@ static void x86_cpu_register_feature_bit_props(X86CPUClass *xcc, static void x86_cpu_post_initfn(Object *obj) { + static bool first = true; + uint64_t supported_xcr0; + int i; + + if (first) { + first = false; + + supported_xcr0 = + ((uint64_t) x86_cpu_get_supported_feature_word(NULL, FEAT_XSAVE_XCR0_HI) << 32) | + x86_cpu_get_supported_feature_word(NULL, FEAT_XSAVE_XCR0_LO); + + for (i = XSTATE_SSE_BIT + 1; i < XSAVE_STATE_AREA_COUNT; i++) { + ExtSaveArea *esa = &x86_ext_save_areas[i]; + + if (!(supported_xcr0 & (1 << i))) { + esa->size = 0; + } + } + } + accel_cpu_instance_init(CPU(obj)); } diff --git a/target/i386/kvm/kvm-cpu.c b/target/i386/kvm/kvm-cpu.c index 684e731cbc..961b87e98e 100644 --- a/target/i386/kvm/kvm-cpu.c +++ b/target/i386/kvm/kvm-cpu.c @@ -143,10 +143,6 @@ static void kvm_cpu_xsave_init(void) if (!esa->size) { continue; } - if ((x86_cpu_get_supported_feature_word(NULL, esa->feature) & esa->bits) - != esa->bits) { - continue; - } host_cpuid(0xd, i, &eax, &ebx, &ecx, &edx); if (eax != 0) { assert(esa->size == eax); -- 2.39.3