target/i386: do not rely on ExtSaveArea for accelerator-supported XCR0 bits

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 <pbonzini@redhat.com>
Reviewed-by: Zhao Liu <zhao1.liu@intel.com>
Link: https://lore.kernel.org/r/20241031085233.425388-3-tao1.su@linux.intel.com
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
Paolo Bonzini 2024-10-31 16:52:27 +08:00
parent 33098002a8
commit b888c78070
2 changed files with 31 additions and 6 deletions

View File

@ -7102,6 +7102,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);
@ -7210,7 +7219,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;
}
}
@ -7348,7 +7357,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);
}
}
@ -8020,6 +8029,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));
}

View File

@ -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);