vmx_fpu.patch
PATCH 1/1 vmx_fpu.patch
Implement a eager save/lazy restore algorithm for dealing with the FP state of a VMX guest.
Signed-off-by Xin B Li <[email protected]>
Signed-off-by Asit Mallick <[email protected]>
Signed-off-by Arun Sharma <[email protected]>
xen/arch/x86/traps.c +1 -9
@@ -917,15 +917,7 @@ asmlinkage int math_state_restore(struct cpu_user_regs *regs) {/* Prevent recursion. */ -clts (); - -if ( !test_and_set_bit (EDF_USEDFPU , ¤t->flags) ) - { -if (test_bit (EDF_DONEFPUINIT , ¤t->flags) ) -restore_fpu (current); -else -init_fpu (); - } +do_clts ();if (test_and_clear_bit (EDF_GUEST_STTS , ¤t->flags) ) {
===== xen/arch/x86/vmx.c 1.48 vs edited =====
xen/arch/x86/vmx.c +21 -0
@@ -154,6 +154,20 @@return result; } +static void vmx_do_no_device_fault () +{ +unsigned long cr0; + +do_clts (); +__vmread (CR0_READ_SHADOW , &cr0); +if (!(cr0 &X86_CR0_TS )) { +__vmread (GUEST_CR0 , &cr0); + cr0 &= ~X86_CR0_TS ; +__vmwrite (GUEST_CR0 , cr0); + } +__vmwrite (EXCEPTION_BITMAP ,MONITOR_DEFAULT_EXCEPTION_BITMAP ); +} +static void vmx_do_general_protection_fault (struct cpu_user_regs *regs) {unsigned long eip, error_code;
@@ -894,6 +908,8 @@mov_from_cr (cr, gp, regs);break ;case TYPE_CLTS : +do_clts (); +__vmread (GUEST_CR0 , &value); value &= ~X86_CR0_TS ;/* clear TS */ __vmwrite (GUEST_CR0 , value);
@@ -1093,6 +1109,11 @@ break; }#endif +case TRAP_no_device: + { +vmx_do_no_device_fault (); +break ; + }case TRAP_gp_fault: {vmx_do_general_protection_fault (®s);
===== xen/arch/x86/vmx_io.c 1.22 vs edited =====
xen/arch/x86/vmx_io.c +1 -0
@@ -429,6 +429,7 @@void vmx_do_resume (struct exec_domain *d) { +vmx_stts ();if (test_bit (VMX_CPU_STATE_PG_ENABLED , &d->arch.arch_vmx.cpu_state) )__vmwrite (GUEST_CR3 ,pagetable_val (d->arch.shadow_table));else
===== xen/arch/x86/vmx_vmcs.c 1.21 vs edited =====
xen/arch/x86/vmx_vmcs.c +3 -0
@@ -164,6 +164,9 @@struct pfn_info *page;struct cpu_user_regs *regs =get_cpu_user_regs (); +vmx_stts (); +set_bit (EDF_GUEST_STTS , &ed->flags); + cpu =smp_processor_id (); page = (struct pfn_info *)alloc_domheap_page (NULL );
===== xen/include/asm-x86/i387.h 1.9 vs edited =====
xen/include/asm-x86/i387.h +13 -0
@@ -28,4 +28,17 @@ __asm__ __volatile__ ("ldmxcsr %0" : :"m" (__mxcsr) ); \ } while ( 0 ) +/* Make current domain the FPU owner */ +static inline void do_clts() +{ +clts (); +if ( !test_and_set_bit (EDF_USEDFPU , ¤t->flags) ) + { +if (test_bit (EDF_DONEFPUINIT , ¤t->flags) ) +restore_fpu (current); +else +init_fpu (); + } +} +#endif /* __ASM_I386_I387_H */
===== xen/include/asm-x86/vmx.h 1.6 vs edited =====
xen/include/asm-x86/vmx.h +16 -0
@@ -24,6 +24,7 @@#include <asm/regs.h> #include <asm/processor.h> #include <asm/vmx_vmcs.h> +#include <asm/i387.h> extern void vmx_asm_vmexit_handler (struct cpu_user_regs );extern void vmx_asm_do_resume (void );
@@ -251,4 +252,19 @@ return 0; } +/* Make sure that xen intercepts any FP accesses from current */ +static inline void vmx_stts () +{ +unsigned long cr0; + +__vmread (GUEST_CR0 , &cr0); +if (!(cr0 &X86_CR0_TS )) +__vmwrite (GUEST_CR0 , cr0 |X86_CR0_TS ); + +__vmread (CR0_READ_SHADOW , &cr0); +if (!(cr0 &X86_CR0_TS )) +__vmwrite (EXCEPTION_BITMAP ,MONITOR_DEFAULT_EXCEPTION_BITMAP | +EXCEPTION_BITMAP_NM ); +} +#endif /* __ASM_X86_VMX_H__ */