x86/xsave: adjust state management The initial state for a vCPU is using default values, so there's no need to force the XRSTOR to read the state from memory. This saves a couple of thousand restores from memory just during boot of Linux on my Sandy Bridge system (I didn't try to make further measurements). The above requires that arch_set_info_guest() updates the state flags in the save area when valid floating point state got passed in, but that would really have been needed even before in case XSAVE{,OPT} decided to clear one or both of the FP and SSE bits. Furthermore, hvm_vcpu_reset_state() shouldn't just clear out the FPU/ SSE area, but needs to re-initialized MXCSR and FCW. Signed-off-by: Jan Beulich --- a/xen/arch/x86/domain.c +++ b/xen/arch/x86/domain.c @@ -712,7 +712,11 @@ int arch_set_info_guest( v->arch.vgc_flags = flags; if ( flags & VGCF_I387_VALID ) + { memcpy(v->arch.fpu_ctxt, &c.nat->fpu_ctxt, sizeof(c.nat->fpu_ctxt)); + if ( v->arch.xsave_area ) + v->arch.xsave_area->xsave_hdr.xstate_bv = XSTATE_FP_SSE; + } if ( !compat ) { --- a/xen/arch/x86/hvm/hvm.c +++ b/xen/arch/x86/hvm/hvm.c @@ -3454,6 +3454,7 @@ void hvm_vcpu_reset_state(struct vcpu *v { struct domain *d = v->domain; struct segment_register reg; + typeof(v->arch.xsave_area->fpu_sse) *fpu_ctxt = v->arch.fpu_ctxt; domain_lock(d); @@ -3467,7 +3468,12 @@ void hvm_vcpu_reset_state(struct vcpu *v v->arch.guest_table = pagetable_null(); } - memset(v->arch.fpu_ctxt, 0, sizeof(v->arch.xsave_area->fpu_sse)); + memset(fpu_ctxt, 0, sizeof(*fpu_ctxt)); + fpu_ctxt->fcw = FCW_RESET; + fpu_ctxt->mxcsr = MXCSR_DEFAULT; + if ( v->arch.xsave_area ) + v->arch.xsave_area->xsave_hdr.xstate_bv = XSTATE_FP; + v->arch.vgc_flags = VGCF_online; memset(&v->arch.user_regs, 0, sizeof(v->arch.user_regs)); v->arch.user_regs.eflags = 2; --- a/xen/arch/x86/xstate.c +++ b/xen/arch/x86/xstate.c @@ -204,9 +204,13 @@ int xstate_alloc_save_area(struct vcpu * if ( save_area == NULL ) return -ENOMEM; + /* + * Set the memory image to default values, but don't force the context + * to be loaded from memory (i.e. keep save_area->xsave_hdr.xstate_bv + * clear). + */ save_area->fpu_sse.fcw = FCW_DEFAULT; save_area->fpu_sse.mxcsr = MXCSR_DEFAULT; - save_area->xsave_hdr.xstate_bv = XSTATE_FP_SSE; v->arch.xsave_area = save_area; v->arch.xcr0 = XSTATE_FP_SSE; --- a/xen/include/asm-x86/xstate.h +++ b/xen/include/asm-x86/xstate.h @@ -11,6 +11,7 @@ #include #define FCW_DEFAULT 0x037f +#define FCW_RESET 0x0040 #define MXCSR_DEFAULT 0x1f80 #define XSTATE_CPUID 0x0000000d