[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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |