From 9646f4927faf68e8690588c2fd6dc9834c440b58 Mon Sep 17 00:00:00 2001 From: Eduardo Habkost Date: Thu, 22 Sep 2016 18:58:39 -0300 Subject: [PATCH] target-i386: Don't try to enable PT State xsave component The code that calculates the set of supported XSAVE components on CPUID looks at ext_save_areas to find out which components should be enabled. However, if there are zeroed entries in the ext_save_areas array, the ((env->features[esa->feature] & esa->bits) == esa->bits) check will always succeed and QEMU will unconditionally try to enable the component. Luckily this never caused any problems because the only missing entry in ext_save_areas is the PT State component (bit 8), and KVM currently doesn't support it (so it was cleared on ena_mask). But the code was still incorrect and would break if KVM starts returning CPUID[EAX=0xD,ECX=0].EAX[bit 8] as supported on GET_SUPPORTED_CPUID. Fix the problem by changing the code to not enable a XSAVE component if ExtSaveArea::bits is zero. Reviewed-by: Richard Henderson Signed-off-by: Eduardo Habkost --- target-i386/cpu.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/target-i386/cpu.c b/target-i386/cpu.c index cc07fdbf8b..25ab4f8b41 100644 --- a/target-i386/cpu.c +++ b/target-i386/cpu.c @@ -2514,7 +2514,7 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, *ecx = 0x240; for (i = 2; i < ARRAY_SIZE(x86_ext_save_areas); i++) { const ExtSaveArea *esa = &x86_ext_save_areas[i]; - if ((env->features[esa->feature] & esa->bits) == esa->bits + if ((env->features[esa->feature] & esa->bits) && ((ena_mask >> i) & 1) != 0) { if (i < 32) { *eax |= 1u << i; @@ -2530,7 +2530,7 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, *eax = env->features[FEAT_XSAVE]; } else if (count < ARRAY_SIZE(x86_ext_save_areas)) { const ExtSaveArea *esa = &x86_ext_save_areas[count]; - if ((env->features[esa->feature] & esa->bits) == esa->bits + if ((env->features[esa->feature] & esa->bits) && ((ena_mask >> count) & 1) != 0) { *eax = esa->size; *ebx = esa->offset; @@ -2766,7 +2766,7 @@ static void x86_cpu_reset(CPUState *s) } for (i = 2; i < ARRAY_SIZE(x86_ext_save_areas); i++) { const ExtSaveArea *esa = &x86_ext_save_areas[i]; - if ((env->features[esa->feature] & esa->bits) == esa->bits) { + if (env->features[esa->feature] & esa->bits) { xcr0 |= 1ull << i; } } -- GitLab