Signed-off-by: Richard Henderson <r...@twiddle.net> --- target-i386/cpu.c | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-)
diff --git a/target-i386/cpu.c b/target-i386/cpu.c index c19ff8a..2402c2a 100644 --- a/target-i386/cpu.c +++ b/target-i386/cpu.c @@ -2654,7 +2654,17 @@ static void x86_cpu_reset(CPUState *s) cpu_set_fpuc(env, 0x37f); env->mxcsr = 0x1f80; - env->xstate_bv = XSTATE_FP | XSTATE_SSE; + + /* ??? This variable is somewhat silly. Methinks KVM should be + using XCR0 to store into the XSTATE_BV field. Either that or + there's more missing information, e.g. the AVX bits. */ + env->xstate_bv = XSTATE_FP; + if (env->features[FEAT_1_EDX] & CPUID_SSE) { + env->xstate_bv |= XSTATE_SSE; + } + if (env->features[FEAT_7_0_EBX] & CPUID_7_0_EBX_MPX) { + env->xstate_bv |= XSTATE_BNDREGS | XSTATE_BNDCSR; + } env->pat = 0x0007040600070406ULL; env->msr_ia32_misc_enable = MSR_IA32_MISC_ENABLE_DEFAULT; @@ -2665,7 +2675,15 @@ static void x86_cpu_reset(CPUState *s) cpu_breakpoint_remove_all(s, BP_CPU); cpu_watchpoint_remove_all(s, BP_CPU); - env->xcr0 = 1; + env->xcr0 = XSTATE_FP; + +#ifdef CONFIG_USER_ONLY + /* Enable all the features for user-mode. */ + env->xcr0 = env->xstate_bv; + if (env->features[FEAT_1_ECX] & CPUID_EXT_XSAVE) { + cpu_x86_update_cr4(env, CR4_OSFXSR_MASK | CR4_OSXSAVE_MASK); + } +#endif /* * SDM 11.11.5 requires: -- 2.4.3