[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen master] x86/fxsave: bring in line with recent xsave adjustments
commit f6c8c791522d6a2ef5e6abd44d0ed005446242b5 Author: Jan Beulich <jbeulich@xxxxxxxx> AuthorDate: Tue Jul 2 08:42:49 2013 +0200 Commit: Jan Beulich <jbeulich@xxxxxxxx> CommitDate: Tue Jul 2 08:42:49 2013 +0200 x86/fxsave: bring in line with recent xsave adjustments Defer the FIP/FDP pointer reset needed on AMD CPUs to the restore path, and switch from using EMMS to FFREE here too (to be resistant against eventual future CPUs without MMX support). Also switch from using an almost typeless pointer in fpu_fxrstor() to a properly typed one, thus telling the compiler the truth about which memory gets accessed. Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx> Acked-by: Keir Fraser <keir@xxxxxxx> --- xen/arch/x86/i387.c | 47 +++++++++++++++++++++-------------------------- 1 files changed, 21 insertions(+), 26 deletions(-) diff --git a/xen/arch/x86/i387.c b/xen/arch/x86/i387.c index dbf24af..bd162a8 100644 --- a/xen/arch/x86/i387.c +++ b/xen/arch/x86/i387.c @@ -52,14 +52,30 @@ static inline void fpu_xrstor(struct vcpu *v, uint64_t mask) /* Restor x87 FPU, MMX, SSE and SSE2 state */ static inline void fpu_fxrstor(struct vcpu *v) { - const char *fpu_ctxt = v->arch.fpu_ctxt; + const typeof(v->arch.xsave_area->fpu_sse) *fpu_ctxt = v->arch.fpu_ctxt; + + /* + * AMD CPUs don't save/restore FDP/FIP/FOP unless an exception + * is pending. Clear the x87 state here by setting it to fixed + * values. The hypervisor data segment can be sometimes 0 and + * sometimes new user value. Both should be ok. Use the FPU saved + * data block as a safe address because it should be in L1. + */ + if ( !(fpu_ctxt->fsw & 0x0080) && + boot_cpu_data.x86_vendor == X86_VENDOR_AMD ) + { + asm volatile ( "fnclex\n\t" + "ffree %%st(7)\n\t" /* clear stack tag */ + "fildl %0" /* load to clear state */ + : : "m" (*fpu_ctxt) ); + } /* * FXRSTOR can fault if passed a corrupted data block. We handle this * possibility, which may occur if the block was passed to us by control * tools or through VCPUOP_initialise, by silently clearing the block. */ - switch ( __builtin_expect(fpu_ctxt[FPU_WORD_SIZE_OFFSET], 8) ) + switch ( __builtin_expect(fpu_ctxt->x[FPU_WORD_SIZE_OFFSET], 8) ) { default: asm volatile ( @@ -80,8 +96,7 @@ static inline void fpu_fxrstor(struct vcpu *v) ".previous \n" _ASM_EXTABLE(1b, 2b) : - : "m" (*fpu_ctxt), - "i" (sizeof(v->arch.xsave_area->fpu_sse) / 4), + : "m" (*fpu_ctxt), "i" (sizeof(*fpu_ctxt) / 4), "cdaSDb" (fpu_ctxt) ); break; case 4: case 2: @@ -102,8 +117,7 @@ static inline void fpu_fxrstor(struct vcpu *v) ".previous \n" _ASM_EXTABLE(1b, 2b) : - : "m" (*fpu_ctxt), - "i" (sizeof(v->arch.xsave_area->fpu_sse) / 4) ); + : "m" (*fpu_ctxt), "i" (sizeof(*fpu_ctxt) / 4) ); break; } } @@ -156,7 +170,7 @@ static inline void fpu_fxsave(struct vcpu *v) */ if ( !(fpu_ctxt->fsw & 0x0080) && boot_cpu_data.x86_vendor == X86_VENDOR_AMD ) - word_size = -1; + return; if ( word_size > 0 && !((fpu_ctxt->fip.addr | fpu_ctxt->fdp.addr) >> 32) ) @@ -177,25 +191,6 @@ static inline void fpu_fxsave(struct vcpu *v) if ( word_size >= 0 ) fpu_ctxt->x[FPU_WORD_SIZE_OFFSET] = word_size; - - /* Clear exception flags if FSW.ES is set. */ - if ( unlikely(fpu_ctxt->fsw & 0x0080) ) - asm volatile ("fnclex"); - - /* - * AMD CPUs don't save/restore FDP/FIP/FOP unless an exception - * is pending. Clear the x87 state here by setting it to fixed - * values. The hypervisor data segment can be sometimes 0 and - * sometimes new user value. Both should be ok. Use the FPU saved - * data block as a safe address because it should be in L1. - */ - if ( boot_cpu_data.x86_vendor == X86_VENDOR_AMD ) - { - asm volatile ( - "emms\n\t" /* clear stack tags */ - "fildl %0" /* load to clear state */ - : : "m" (*fpu_ctxt) ); - } } /* Save x87 FPU state */ -- 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 |