[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen master] x86/xsave: adjust state management
commit f9755488bf17c056111d1e442be394cfb63d7788 Author: Jan Beulich <jbeulich@xxxxxxxx> AuthorDate: Tue Jul 2 08:41:28 2013 +0200 Commit: Jan Beulich <jbeulich@xxxxxxxx> CommitDate: Tue Jul 2 08:41:28 2013 +0200 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 <jbeulich@xxxxxxxx> Acked-by: Keir Fraser <keir@xxxxxxx> --- xen/arch/x86/domain.c | 4 ++++ xen/arch/x86/hvm/hvm.c | 8 +++++++- xen/arch/x86/xstate.c | 6 +++++- xen/include/asm-x86/xstate.h | 1 + 4 files changed, 17 insertions(+), 2 deletions(-) diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c index 52c9040..874742c 100644 --- 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 ) { diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c index 43b6d05..1fcaed0 100644 --- a/xen/arch/x86/hvm/hvm.c +++ b/xen/arch/x86/hvm/hvm.c @@ -3466,6 +3466,7 @@ void hvm_vcpu_reset_state(struct vcpu *v, uint16_t cs, uint16_t ip) { 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); @@ -3479,7 +3480,12 @@ void hvm_vcpu_reset_state(struct vcpu *v, uint16_t cs, uint16_t ip) 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; diff --git a/xen/arch/x86/xstate.c b/xen/arch/x86/xstate.c index d52dbd7..608accf 100644 --- a/xen/arch/x86/xstate.c +++ b/xen/arch/x86/xstate.c @@ -204,9 +204,13 @@ int xstate_alloc_save_area(struct vcpu *v) 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; diff --git a/xen/include/asm-x86/xstate.h b/xen/include/asm-x86/xstate.h index 49168f3..dc3cb8e 100644 --- a/xen/include/asm-x86/xstate.h +++ b/xen/include/asm-x86/xstate.h @@ -11,6 +11,7 @@ #include <xen/types.h> #define FCW_DEFAULT 0x037f +#define FCW_RESET 0x0040 #define MXCSR_DEFAULT 0x1f80 #define XSTATE_CPUID 0x0000000d -- generated by git-patchbot for /home/xen/git/xen.git#master _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |