ia64/xen-unstable

changeset 4856:4f406bfbf32e

bitkeeper revision 1.1389.15.17 (42826929NzXOK9PSr4_HoDheSjVx3A)

vmx.h, i387.h, vmx_vmcs.c, vmx_io.c, vmx.c, traps.c:
Implement a eager save/lazy restore algorithm for dealing with the
FP state of a VMX guest.
Signed-off-by: Xin B Li <xin.b.li@intel.com>
Signed-off-by: Asit Mallick <asit.k.mallick@intel.com>
Signed-off-by: Arun Sharma <arun.sharma@intel.com>
Signed-off-by: Christian Limpach <Christian.Limpach@cl.cam.ac.uk>
author cl349@firebug.cl.cam.ac.uk
date Wed May 11 20:20:57 2005 +0000 (2005-05-11)
parents b5334eb38828
children 7b0fa15646cd
files xen/arch/x86/traps.c xen/arch/x86/vmx.c xen/arch/x86/vmx_io.c xen/arch/x86/vmx_vmcs.c xen/include/asm-x86/i387.h xen/include/asm-x86/vmx.h
line diff
     1.1 --- a/xen/arch/x86/traps.c	Wed May 11 17:42:15 2005 +0000
     1.2 +++ b/xen/arch/x86/traps.c	Wed May 11 20:20:57 2005 +0000
     1.3 @@ -919,13 +919,7 @@ asmlinkage int math_state_restore(struct
     1.4      /* Prevent recursion. */
     1.5      clts();
     1.6  
     1.7 -    if ( !test_and_set_bit(EDF_USEDFPU, &current->flags) )
     1.8 -    {
     1.9 -        if ( test_bit(EDF_DONEFPUINIT, &current->flags) )
    1.10 -            restore_fpu(current);
    1.11 -        else
    1.12 -            init_fpu();
    1.13 -    }
    1.14 +    setup_fpu(current);
    1.15  
    1.16      if ( test_and_clear_bit(EDF_GUEST_STTS, &current->flags) )
    1.17      {
     2.1 --- a/xen/arch/x86/vmx.c	Wed May 11 17:42:15 2005 +0000
     2.2 +++ b/xen/arch/x86/vmx.c	Wed May 11 20:20:57 2005 +0000
     2.3 @@ -154,6 +154,21 @@ static int vmx_do_page_fault(unsigned lo
     2.4      return result;
     2.5  }
     2.6  
     2.7 +static void vmx_do_no_device_fault() 
     2.8 +{
     2.9 +    unsigned long cr0;
    2.10 +        
    2.11 +    clts();
    2.12 +    setup_fpu(current);
    2.13 +    __vmread(CR0_READ_SHADOW, &cr0);
    2.14 +    if (!(cr0 & X86_CR0_TS)) {
    2.15 +        __vmread(GUEST_CR0, &cr0);
    2.16 +        cr0 &= ~X86_CR0_TS;
    2.17 +        __vmwrite(GUEST_CR0, cr0);
    2.18 +    }
    2.19 +    __vmwrite(EXCEPTION_BITMAP, MONITOR_DEFAULT_EXCEPTION_BITMAP);
    2.20 +}
    2.21 +
    2.22  static void vmx_do_general_protection_fault(struct cpu_user_regs *regs) 
    2.23  {
    2.24      unsigned long eip, error_code;
    2.25 @@ -894,6 +909,9 @@ static int vmx_cr_access(unsigned long e
    2.26          mov_from_cr(cr, gp, regs);
    2.27          break;
    2.28      case TYPE_CLTS:
    2.29 +        clts();
    2.30 +        setup_fpu(current);
    2.31 +
    2.32          __vmread(GUEST_CR0, &value);
    2.33          value &= ~X86_CR0_TS; /* clear TS */
    2.34          __vmwrite(GUEST_CR0, value);
    2.35 @@ -1093,6 +1111,11 @@ asmlinkage void vmx_vmexit_handler(struc
    2.36              break;
    2.37          }
    2.38  #endif
    2.39 +        case TRAP_no_device:
    2.40 +        {
    2.41 +            vmx_do_no_device_fault();
    2.42 +            break;  
    2.43 +        }
    2.44          case TRAP_gp_fault:
    2.45          {
    2.46              vmx_do_general_protection_fault(&regs);
     3.1 --- a/xen/arch/x86/vmx_io.c	Wed May 11 17:42:15 2005 +0000
     3.2 +++ b/xen/arch/x86/vmx_io.c	Wed May 11 20:20:57 2005 +0000
     3.3 @@ -429,6 +429,7 @@ void vmx_intr_assist(struct exec_domain 
     3.4  
     3.5  void vmx_do_resume(struct exec_domain *d) 
     3.6  {
     3.7 +    vmx_stts();
     3.8      if ( test_bit(VMX_CPU_STATE_PG_ENABLED, &d->arch.arch_vmx.cpu_state) )
     3.9          __vmwrite(GUEST_CR3, pagetable_val(d->arch.shadow_table));
    3.10      else
     4.1 --- a/xen/arch/x86/vmx_vmcs.c	Wed May 11 17:42:15 2005 +0000
     4.2 +++ b/xen/arch/x86/vmx_vmcs.c	Wed May 11 20:20:57 2005 +0000
     4.3 @@ -164,6 +164,9 @@ void vmx_do_launch(struct exec_domain *e
     4.4      struct pfn_info *page;
     4.5      struct cpu_user_regs *regs = get_cpu_user_regs();
     4.6  
     4.7 +    vmx_stts();
     4.8 +    set_bit(EDF_GUEST_STTS, &ed->flags);
     4.9 +
    4.10      cpu = smp_processor_id();
    4.11  
    4.12      page = (struct pfn_info *) alloc_domheap_page(NULL);
     5.1 --- a/xen/include/asm-x86/i387.h	Wed May 11 17:42:15 2005 +0000
     5.2 +++ b/xen/include/asm-x86/i387.h	Wed May 11 20:20:57 2005 +0000
     5.3 @@ -28,4 +28,16 @@ extern void restore_fpu(struct exec_doma
     5.4      __asm__ __volatile__ ( "ldmxcsr %0" : : "m" (__mxcsr) ); \
     5.5  } while ( 0 )
     5.6  
     5.7 +/* Make domain the FPU owner */
     5.8 +static inline void setup_fpu(struct exec_domain *ed)
     5.9 +{
    5.10 +    if ( !test_and_set_bit(EDF_USEDFPU, &ed->flags) )
    5.11 +    {
    5.12 +        if ( test_bit(EDF_DONEFPUINIT, &ed->flags) )
    5.13 +            restore_fpu(ed);
    5.14 +        else
    5.15 +            init_fpu();
    5.16 +    }
    5.17 +}
    5.18 +
    5.19  #endif /* __ASM_I386_I387_H */
     6.1 --- a/xen/include/asm-x86/vmx.h	Wed May 11 17:42:15 2005 +0000
     6.2 +++ b/xen/include/asm-x86/vmx.h	Wed May 11 20:20:57 2005 +0000
     6.3 @@ -24,6 +24,7 @@
     6.4  #include <asm/regs.h>
     6.5  #include <asm/processor.h>
     6.6  #include <asm/vmx_vmcs.h>
     6.7 +#include <asm/i387.h>
     6.8  
     6.9  extern void vmx_asm_vmexit_handler(struct cpu_user_regs);
    6.10  extern void vmx_asm_do_resume(void);
    6.11 @@ -251,4 +252,19 @@ static inline int __vmxon (u64 addr)
    6.12      return 0;
    6.13  }
    6.14  
    6.15 +/* Make sure that xen intercepts any FP accesses from current */
    6.16 +static inline void vmx_stts()
    6.17 +{
    6.18 +    unsigned long cr0;
    6.19 +
    6.20 +    __vmread(GUEST_CR0, &cr0);
    6.21 +    if (!(cr0 & X86_CR0_TS))
    6.22 +        __vmwrite(GUEST_CR0, cr0 | X86_CR0_TS);
    6.23 +
    6.24 +    __vmread(CR0_READ_SHADOW, &cr0);
    6.25 +    if (!(cr0 & X86_CR0_TS))
    6.26 +       __vmwrite(EXCEPTION_BITMAP, MONITOR_DEFAULT_EXCEPTION_BITMAP | 
    6.27 +                                   EXCEPTION_BITMAP_NM);
    6.28 +}
    6.29 + 
    6.30  #endif /* __ASM_X86_VMX_H__ */