From mboxrd@z Thu Jan 1 00:00:00 1970 From: Shuai Ruan Subject: [PATCH 2/6] x86/xsaves: enable xsaves/xrstors in xen Date: Fri, 17 Jul 2015 15:26:52 +0800 Message-ID: <1437118016-25547-3-git-send-email-shuai.ruan@intel.com> References: <1437118016-25547-1-git-send-email-shuai.ruan@intel.com> Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Return-path: In-Reply-To: <1437118016-25547-1-git-send-email-shuai.ruan@intel.com> List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Sender: xen-devel-bounces@lists.xen.org Errors-To: xen-devel-bounces@lists.xen.org To: xen-devel@lists.xen.org Cc: kevin.tian@intel.com, wei.liu2@citrix.com, Ian.Campbell@citrix.com, stefano.stabellini@eu.citrix.com, jun.nakajima@intel.com, andrew.cooper3@citrix.com, ian.jackson@eu.citrix.com, eddie.dong@intel.com, jbeulich@suse.com, keir@xen.org List-Id: xen-devel@lists.xenproject.org This patch uses xsaves/xrstors instead of xsaveopt/xrstor to perform the xsave_area switching so that xen itself can benefit from them when available. Please note that xsaves/xrstors only use compact format. Signed-off-by: Shuai Ruan --- xen/arch/x86/i387.c | 5 ++++ xen/arch/x86/xstate.c | 70 +++++++++++++++++++++++++------------------- xen/include/asm-x86/xstate.h | 4 ++- 3 files changed, 48 insertions(+), 31 deletions(-) diff --git a/xen/arch/x86/i387.c b/xen/arch/x86/i387.c index 14f2a79..9071374 100644 --- a/xen/arch/x86/i387.c +++ b/xen/arch/x86/i387.c @@ -309,7 +309,12 @@ int vcpu_init_fpu(struct vcpu *v) return rc; if ( v->arch.xsave_area ) + { v->arch.fpu_ctxt = &v->arch.xsave_area->fpu_sse; + + if ( cpu_has_xsaves ) + v->arch.xsave_area->xsave_hdr.xcomp_bv |= XSTATE_COMPACTION_ENABLED; + } else { v->arch.fpu_ctxt = _xzalloc(sizeof(v->arch.xsave_area->fpu_sse), 16); diff --git a/xen/arch/x86/xstate.c b/xen/arch/x86/xstate.c index e34eda3..571ce13 100644 --- a/xen/arch/x86/xstate.c +++ b/xen/arch/x86/xstate.c @@ -102,7 +102,9 @@ void xsave(struct vcpu *v, uint64_t mask) typeof(ptr->fpu_sse.fip.sel) fcs = ptr->fpu_sse.fip.sel; typeof(ptr->fpu_sse.fdp.sel) fds = ptr->fpu_sse.fdp.sel; - if ( cpu_has_xsaveopt ) + if ( cpu_has_xsaves ) + xsaves(lmask, hmask, ptr); + else if ( cpu_has_xsaveopt ) { /* * xsaveopt may not write the FPU portion even when the respective @@ -155,7 +157,9 @@ void xsave(struct vcpu *v, uint64_t mask) } else { - if ( cpu_has_xsaveopt ) + if ( cpu_has_xsaves ) + xsaves(lmask, hmask, ptr); + else if ( cpu_has_xsaveopt ) asm volatile ( ".byte 0x0f,0xae,0x37" : "=m" (*ptr) : "a" (lmask), "d" (hmask), "D" (ptr) ); @@ -198,36 +202,42 @@ void xrstor(struct vcpu *v, uint64_t mask) switch ( __builtin_expect(ptr->fpu_sse.x[FPU_WORD_SIZE_OFFSET], 8) ) { default: - asm volatile ( "1: .byte 0x48,0x0f,0xae,0x2f\n" - ".section .fixup,\"ax\" \n" - "2: mov %5,%%ecx \n" - " xor %1,%1 \n" - " rep stosb \n" - " lea %2,%0 \n" - " mov %3,%1 \n" - " jmp 1b \n" - ".previous \n" - _ASM_EXTABLE(1b, 2b) - : "+&D" (ptr), "+&a" (lmask) - : "m" (*ptr), "g" (lmask), "d" (hmask), - "m" (xsave_cntxt_size) - : "ecx" ); + if ( cpu_has_xsaves ) + xrstors(lmask, hmask, ptr); + else + asm volatile ( "1: .byte 0x48,0x0f,0xae,0x2f\n" + ".section .fixup,\"ax\" \n" + "2: mov %5,%%ecx \n" + " xor %1,%1 \n" + " rep stosb \n" + " lea %2,%0 \n" + " mov %3,%1 \n" + " jmp 1b \n" + ".previous \n" + _ASM_EXTABLE(1b, 2b) + : "+&D" (ptr), "+&a" (lmask) + : "m" (*ptr), "g" (lmask), "d" (hmask), + "m" (xsave_cntxt_size) + : "ecx" ); break; case 4: case 2: - asm volatile ( "1: .byte 0x0f,0xae,0x2f\n" - ".section .fixup,\"ax\" \n" - "2: mov %5,%%ecx \n" - " xor %1,%1 \n" - " rep stosb \n" - " lea %2,%0 \n" - " mov %3,%1 \n" - " jmp 1b \n" - ".previous \n" - _ASM_EXTABLE(1b, 2b) - : "+&D" (ptr), "+&a" (lmask) - : "m" (*ptr), "g" (lmask), "d" (hmask), - "m" (xsave_cntxt_size) - : "ecx" ); + if ( cpu_has_xsaves ) + xrstors(lmask, hmask, ptr); + else + asm volatile ( "1: .byte 0x48,0x0f,0xae,0x2f\n" + ".section .fixup,\"ax\" \n" + "2: mov %5,%%ecx \n" + " xor %1,%1 \n" + " rep stosb \n" + " lea %2,%0 \n" + " mov %3,%1 \n" + " jmp 1b \n" + ".previous \n" + _ASM_EXTABLE(1b, 2b) + : "+&D" (ptr), "+&a" (lmask) + : "m" (*ptr), "g" (lmask), "d" (hmask), + "m" (xsave_cntxt_size) + : "ecx" ); break; } } diff --git a/xen/include/asm-x86/xstate.h b/xen/include/asm-x86/xstate.h index 59c7156..47c2f59 100644 --- a/xen/include/asm-x86/xstate.h +++ b/xen/include/asm-x86/xstate.h @@ -41,6 +41,7 @@ #define XSTATE_ALL (~(1ULL << 63)) #define XSTATE_NONLAZY (XSTATE_LWP | XSTATE_BNDREGS | XSTATE_BNDCSR) #define XSTATE_LAZY (XSTATE_ALL & ~XSTATE_NONLAZY) +#define XSTATE_COMPACTION_ENABLED (1ULL << 63) extern u64 xfeature_mask; extern bool_t cpu_has_xsaves, cpu_has_xgetbv1; @@ -72,7 +73,8 @@ struct __packed __attribute__((aligned (64))) xsave_struct struct { u64 xstate_bv; - u64 reserved[7]; + u64 xcomp_bv; + u64 reserved[6]; } xsave_hdr; /* The 64-byte header */ struct { char x[XSTATE_YMM_SIZE]; } ymm; /* YMM */ -- 1.9.1