[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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.