# HG changeset patch # User Wei Huang # Date 1304447821 18000 # Node ID cf78dad029ac3a8a9c0bf7300b275da09a94b48c # Parent a2f5b9631b2f61be37127ef5d5b810d6ce71e858 FPU: create FPU init and destroy functions Extract FPU initialization and destroy code into two functions. These functions handle memory allocation/deallocation for FPU context. Signed-off-by: Wei Huang diff -r a2f5b9631b2f -r cf78dad029ac xen/arch/x86/domain.c --- a/xen/arch/x86/domain.c Tue May 03 13:34:11 2011 -0500 +++ b/xen/arch/x86/domain.c Tue May 03 13:37:01 2011 -0500 @@ -420,20 +420,8 @@ v->arch.perdomain_ptes = perdomain_ptes(d, v); - if ( (rc = xstate_alloc_save_area(v)) != 0 ) + if ( (rc = vcpu_init_fpu(v)) != 0 ) return rc; - if ( v->arch.xsave_area ) - v->arch.fpu_ctxt = &v->arch.xsave_area->fpu_sse; - else if ( !is_idle_domain(d) ) - { - v->arch.fpu_ctxt = _xmalloc(sizeof(v->arch.xsave_area->fpu_sse), 16); - if ( !v->arch.fpu_ctxt ) - { - rc = -ENOMEM; - goto done; - } - memset(v->arch.fpu_ctxt, 0, sizeof(v->arch.xsave_area->fpu_sse)); - } if ( is_hvm_domain(d) ) { @@ -485,10 +473,8 @@ done: if ( rc ) { - if ( v->arch.xsave_area ) - xstate_free_save_area(v); - else - xfree(v->arch.fpu_ctxt); + vcpu_destroy_fpu(v); + if ( !is_hvm_domain(d) && standalone_trap_ctxt(v) ) free_xenheap_page(v->arch.pv_vcpu.trap_ctxt); } @@ -501,10 +487,7 @@ if ( is_pv_32on64_vcpu(v) ) release_compat_l4(v); - if ( v->arch.xsave_area ) - xstate_free_save_area(v); - else - xfree(v->arch.fpu_ctxt); + vcpu_destroy_fpu(v); if ( is_hvm_vcpu(v) ) hvm_vcpu_destroy(v); diff -r a2f5b9631b2f -r cf78dad029ac xen/arch/x86/i387.c --- a/xen/arch/x86/i387.c Tue May 03 13:34:11 2011 -0500 +++ b/xen/arch/x86/i387.c Tue May 03 13:37:01 2011 -0500 @@ -184,6 +184,47 @@ } } +/*******************************/ +/* VCPU FPU Functions */ +/*******************************/ +/* Initialize FPU's context save area */ +int vcpu_init_fpu(struct vcpu *v) +{ + int rc = 0; + + /* Idle domain doesn't have FPU state allocated */ + if ( is_idle_vcpu(v) ) + goto done; + + if ( (rc = xstate_alloc_save_area(v)) != 0 ) + return rc; + + if ( v->arch.xsave_area ) + v->arch.fpu_ctxt = &v->arch.xsave_area->fpu_sse; + else + { + v->arch.fpu_ctxt = _xmalloc(sizeof(v->arch.xsave_area->fpu_sse), 16); + if ( !v->arch.fpu_ctxt ) + { + rc = -ENOMEM; + goto done; + } + memset(v->arch.fpu_ctxt, 0, sizeof(v->arch.xsave_area->fpu_sse)); + } + +done: + return rc; +} + +/* Free FPU's context save area */ +void vcpu_destroy_fpu(struct vcpu *v) +{ + if ( v->arch.xsave_area ) + xstate_free_save_area(v); + else + xfree(v->arch.fpu_ctxt); +} + /* * Local variables: * mode: C diff -r a2f5b9631b2f -r cf78dad029ac xen/include/asm-x86/i387.h --- a/xen/include/asm-x86/i387.h Tue May 03 13:34:11 2011 -0500 +++ b/xen/include/asm-x86/i387.h Tue May 03 13:37:01 2011 -0500 @@ -17,4 +17,6 @@ void setup_fpu(struct vcpu *v); void save_init_fpu(struct vcpu *v); +int vcpu_init_fpu(struct vcpu *v); +void vcpu_destroy_fpu(struct vcpu *v); #endif /* __ASM_I386_I387_H */