File xsa165.patch of Package xen.openSUSE_13.1_Update

x86: don't leak ST(n)/XMMn values to domains first using them

FNINIT doesn't alter these registers, and hence using it is
insufficient to initialize a guest's initial state.

This is XSA-165.

Signed-off-by: Jan Beulich <jbeulich@suse.com>

Index: xen-4.3.4-testing/xen/arch/x86/domain.c
===================================================================
--- xen-4.3.4-testing.orig/xen/arch/x86/domain.c
+++ xen-4.3.4-testing/xen/arch/x86/domain.c
@@ -730,6 +730,25 @@ int arch_set_info_guest(
 
     if ( flags & VGCF_I387_VALID )
         memcpy(v->arch.fpu_ctxt, &c.nat->fpu_ctxt, sizeof(c.nat->fpu_ctxt));
+    else if ( v->arch.xsave_area )
+        memset(&v->arch.xsave_area->xsave_hdr, 0,
+               sizeof(v->arch.xsave_area->xsave_hdr));
+    else if ( cpu_has_fxsr )
+    {
+        typeof(v->arch.xsave_area->fpu_sse) *fpu_sse = v->arch.fpu_ctxt;
+
+        memset(fpu_sse, 0, sizeof(*fpu_sse));
+        fpu_sse->fcw = FCW_DEFAULT;
+        fpu_sse->mxcsr = MXCSR_DEFAULT;
+    }
+    else
+    {
+        struct ix87_state *fpu = v->arch.fpu_ctxt;
+
+        memset(fpu, 0, sizeof(*fpu));
+        fpu->env.fcw = FCW_DEFAULT;
+        fpu->env.ftw = 0xffff;
+    }
 
     if ( !compat )
     {
Index: xen-4.3.4-testing/xen/arch/x86/i387.c
===================================================================
--- xen-4.3.4-testing.orig/xen/arch/x86/i387.c
+++ xen-4.3.4-testing/xen/arch/x86/i387.c
@@ -17,19 +17,6 @@
 #include <asm/xstate.h>
 #include <asm/asm_defns.h>
 
-static void fpu_init(void)
-{
-    unsigned long val;
-    
-    asm volatile ( "fninit" );
-    if ( cpu_has_xmm )
-    {
-        /* load default value into MXCSR control/status register */
-        val = MXCSR_DEFAULT;
-        asm volatile ( "ldmxcsr %0" : : "m" (val) );
-    }
-}
-
 /*******************************/
 /*     FPU Restore Functions   */
 /*******************************/
@@ -254,15 +241,10 @@ void vcpu_restore_fpu_lazy(struct vcpu *
 
     if ( cpu_has_xsave )
         fpu_xrstor(v, XSTATE_LAZY);
-    else if ( v->fpu_initialised )
-    {
-        if ( cpu_has_fxsr )
-            fpu_fxrstor(v);
-        else
-            fpu_frstor(v);
-    }
+    else if ( cpu_has_fxsr )
+        fpu_fxrstor(v);
     else
-        fpu_init();
+        fpu_frstor(v);
 
     v->fpu_initialised = 1;
     v->fpu_dirtied = 1;
@@ -328,6 +310,21 @@ int vcpu_init_fpu(struct vcpu *v)
             rc = -ENOMEM;
             goto done;
         }
+
+        if ( cpu_has_fxsr )
+        {
+            typeof(v->arch.xsave_area->fpu_sse) *fpu_sse = v->arch.fpu_ctxt;
+
+            fpu_sse->fcw = FCW_DEFAULT;
+            fpu_sse->mxcsr = MXCSR_DEFAULT;
+        }
+        else
+        {
+            struct ix87_state *fpu = v->arch.fpu_ctxt;
+
+            fpu->env.fcw = FCW_DEFAULT;
+            fpu->env.ftw = 0xffff;
+        }
     }
 
 done:
openSUSE Build Service is sponsored by