[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH 4/4] 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>

--- a/xen/arch/x86/i387.c
+++ b/xen/arch/x86/i387.c
@@ -52,14 +52,30 @@ static inline void fpu_xrstor(struct vcp
 /* 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 vc
             ".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 vc
             ".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 vcp
          */
         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 vcp
 
     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 */



Attachment: x86-fxrstor-reset-ptrs.patch
Description: Text document

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel

 


Rackspace

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