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

[Xen-changelog] [xen-unstable] x86: Avoid calling xsave_alloc_save_area before xsave_init



# HG changeset patch
# User Keir Fraser <keir@xxxxxxx>
# Date 1294994093 0
# Node ID 4b7cb21caf0e114c5f6ef8a74c17ca799873e83b
# Parent  93e7bf0e1845f1a82441fb740522a9b9cb32beda
x86: Avoid calling xsave_alloc_save_area before xsave_init

Currently, xsave_alloc_save_area will be called in
init_idle_domain->scheduler_init->alloc_vcpu->vcpu_initialise calls
with xsave_cntxt_size=0, it is earlier than xsave_init called in
identity_cpu(). This may causing buffer overflow on xmem_pool.

Idle domain isn't using FPU,SSE,AVX or any such extended state and
doesn't need it saved. xsave_{alloc,free}_save_area() should
test-and-exit on is_idle_vcpu(), and our context switch code should
not be doing XSAVE when switching out an idle vcpu.

Signed-off-by: Wei Gang <gang.wei@xxxxxxxxx>
Signed-off-by: Keir Fraser <keir@xxxxxxx>
---
 xen/arch/x86/i387.c        |   44 ++++++++++++++++++++++++++++++++++++++++++--
 xen/include/asm-x86/i387.h |   32 +-------------------------------
 2 files changed, 43 insertions(+), 33 deletions(-)

diff -r 93e7bf0e1845 -r 4b7cb21caf0e xen/arch/x86/i387.c
--- a/xen/arch/x86/i387.c       Fri Jan 14 08:11:46 2011 +0000
+++ b/xen/arch/x86/i387.c       Fri Jan 14 08:34:53 2011 +0000
@@ -16,6 +16,39 @@
 #include <asm/i387.h>
 #include <asm/asm_defns.h>
 
+void setup_fpu(struct vcpu *v)
+{
+    ASSERT(!is_idle_vcpu(v));
+
+    /* Avoid recursion. */
+    clts();
+
+    if ( !v->fpu_dirtied )
+    {
+        v->fpu_dirtied = 1;
+        if ( cpu_has_xsave )
+        {
+            if ( !v->fpu_initialised )
+                v->fpu_initialised = 1;
+
+            /* XCR0 normally represents what guest OS set. In case of Xen
+             * itself, we set all supported feature mask before doing
+             * save/restore.
+             */
+            set_xcr0(v->arch.xcr0_accum);
+            xrstor(v);
+            set_xcr0(v->arch.xcr0);
+        }
+        else
+        {
+            if ( v->fpu_initialised )
+                restore_fpu(v);
+            else
+                init_fpu();
+        }
+    }
+}
+
 void init_fpu(void)
 {
     asm volatile ( "fninit" );
@@ -28,6 +61,8 @@ void save_init_fpu(struct vcpu *v)
 {
     unsigned long cr0 = read_cr0();
     char *fpu_ctxt = v->arch.guest_context.fpu_ctxt.x;
+
+    ASSERT(!is_idle_vcpu(v));
 
     /* This can happen, if a paravirtualised guest OS has set its CR0.TS. */
     if ( cr0 & X86_CR0_TS )
@@ -138,6 +173,7 @@ void restore_fpu(struct vcpu *v)
 }
 
 #define XSTATE_CPUID 0xd
+#define XSAVE_AREA_MIN_SIZE (512 + 64) /* FP/SSE + XSAVE.HEADER */
 
 /*
  * Maximum size (in byte) of the XSAVE/XRSTOR save area required by all
@@ -177,7 +213,9 @@ void xsave_init(void)
     }
 
     /* FP/SSE, XSAVE.HEADER, YMM */
-    min_size =  512 + 64 + ((eax & XSTATE_YMM) ? XSTATE_YMM_SIZE : 0);
+    min_size =  XSAVE_AREA_MIN_SIZE;
+    if ( eax & XSTATE_YMM )
+        min_size += XSTATE_YMM_SIZE;
     BUG_ON(ecx < min_size);
 
     /*
@@ -214,8 +252,10 @@ int xsave_alloc_save_area(struct vcpu *v
 {
     void *save_area;
 
-    if ( !cpu_has_xsave )
+    if ( !cpu_has_xsave || is_idle_vcpu(v) )
         return 0;
+
+    BUG_ON(xsave_cntxt_size < XSAVE_AREA_MIN_SIZE);
 
     /* XSAVE/XRSTOR requires the save area be 64-byte-boundary aligned. */
     save_area = _xmalloc(xsave_cntxt_size, 64);
diff -r 93e7bf0e1845 -r 4b7cb21caf0e xen/include/asm-x86/i387.h
--- a/xen/include/asm-x86/i387.h        Fri Jan 14 08:11:46 2011 +0000
+++ b/xen/include/asm-x86/i387.h        Fri Jan 14 08:34:53 2011 +0000
@@ -110,6 +110,7 @@ static inline void xrstor(struct vcpu *v
         : "m" (*ptr), "a" (-1), "d" (-1), "D"(ptr));
 }
 
+extern void setup_fpu(struct vcpu *v);
 extern void init_fpu(void);
 extern void save_init_fpu(struct vcpu *v);
 extern void restore_fpu(struct vcpu *v);
@@ -124,35 +125,4 @@ extern void restore_fpu(struct vcpu *v);
     __asm__ __volatile__ ( "ldmxcsr %0" : : "m" (__mxcsr) );    \
 } while ( 0 )
 
-static inline void setup_fpu(struct vcpu *v)
-{
-    /* Avoid recursion. */
-    clts();
-
-    if ( !v->fpu_dirtied )
-    {
-        v->fpu_dirtied = 1;
-        if ( cpu_has_xsave )
-        {
-            if ( !v->fpu_initialised )
-                v->fpu_initialised = 1;
-
-            /* XCR0 normally represents what guest OS set. In case of Xen
-             * itself, we set all supported feature mask before doing
-             * save/restore.
-             */
-            set_xcr0(v->arch.xcr0_accum);
-            xrstor(v);
-            set_xcr0(v->arch.xcr0);
-        }
-        else
-        {
-            if ( v->fpu_initialised )
-                restore_fpu(v);
-            else
-                init_fpu();
-        }
-    }
-}
-
 #endif /* __ASM_I386_I387_H */

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
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®.