direct-io.hg

changeset 14674:2b715386b4cf

hvm vmx: Fix MSR-intercept bitmap initialisation (two bitmap offsets
are documented the wrong way round in the current PRM Vol.3). Clear
bits in the bitmap only /after/ it has been initialised to
all-1s. Clean up start-of-day info printing.
Signed-off-by: Keir Fraser <keir@xensource.com>
author Keir Fraser <keir@xensource.com>
date Fri Mar 30 18:42:49 2007 +0100 (2007-03-30)
parents 36ff129dbd8b
children b0b20a09d253
files xen/arch/x86/hvm/hvm.c xen/arch/x86/hvm/svm/svm.c xen/arch/x86/hvm/vmx/vmcs.c xen/arch/x86/hvm/vmx/vmx.c xen/include/asm-ia64/vmx_vpd.h xen/include/asm-x86/hvm/hvm.h xen/include/asm-x86/hvm/vmx/vmcs.h xen/include/asm-x86/hvm/vmx/vmx.h
line diff
     1.1 --- a/xen/arch/x86/hvm/hvm.c	Fri Mar 30 18:39:34 2007 +0100
     1.2 +++ b/xen/arch/x86/hvm/hvm.c	Fri Mar 30 18:42:49 2007 +0100
     1.3 @@ -65,8 +65,8 @@ char __attribute__ ((__section__ (".bss.
     1.4  
     1.5  void hvm_enable(struct hvm_function_table *fns)
     1.6  {
     1.7 -    if ( hvm_enabled )
     1.8 -        return;
     1.9 +    BUG_ON(hvm_enabled);
    1.10 +    printk("HVM: %s enabled\n", fns->name);
    1.11  
    1.12      /*
    1.13       * Allow direct access to the PC debug port (it is often used for I/O
     2.1 --- a/xen/arch/x86/hvm/svm/svm.c	Fri Mar 30 18:39:34 2007 +0100
     2.2 +++ b/xen/arch/x86/hvm/svm/svm.c	Fri Mar 30 18:42:49 2007 +0100
     2.3 @@ -890,6 +890,7 @@ static int svm_event_injection_faulted(s
     2.4  }
     2.5  
     2.6  static struct hvm_function_table svm_function_table = {
     2.7 +    .name                 = "SVM",
     2.8      .disable              = stop_svm,
     2.9      .vcpu_initialise      = svm_vcpu_initialise,
    2.10      .vcpu_destroy         = svm_vcpu_destroy,
    2.11 @@ -954,9 +955,8 @@ int start_svm(void)
    2.12          return 0;
    2.13      }
    2.14  
    2.15 -    if (!hsa[cpu])
    2.16 -        if (!(hsa[cpu] = alloc_host_save_area()))
    2.17 -            return 0;
    2.18 +    if ( (hsa[cpu] == NULL) && ((hsa[cpu] = alloc_host_save_area()) == NULL) )
    2.19 +        return 0;
    2.20      
    2.21      rdmsr(MSR_EFER, eax, edx);
    2.22      eax |= EFER_SVME;
    2.23 @@ -971,13 +971,15 @@ int start_svm(void)
    2.24      phys_hsa_hi = (u32) (phys_hsa >> 32);    
    2.25      wrmsr(MSR_K8_VM_HSAVE_PA, phys_hsa_lo, phys_hsa_hi);
    2.26    
    2.27 -    if (!root_vmcb[cpu])
    2.28 -        if (!(root_vmcb[cpu] = alloc_vmcb())) 
    2.29 -            return 0;
    2.30 +    if ( (root_vmcb[cpu] == NULL) &&
    2.31 +         ((root_vmcb[cpu] = alloc_vmcb()) == NULL) )
    2.32 +        return 0;
    2.33      root_vmcb_pa[cpu] = virt_to_maddr(root_vmcb[cpu]);
    2.34  
    2.35 -    if (cpu == 0)
    2.36 -        setup_vmcb_dump();
    2.37 +    if ( cpu != 0 )
    2.38 +        return 1;
    2.39 +
    2.40 +    setup_vmcb_dump();
    2.41  
    2.42      hvm_enable(&svm_function_table);
    2.43  
     3.1 --- a/xen/arch/x86/hvm/vmx/vmcs.c	Fri Mar 30 18:39:34 2007 +0100
     3.2 +++ b/xen/arch/x86/hvm/vmx/vmcs.c	Fri Mar 30 18:42:49 2007 +0100
     3.3 @@ -38,10 +38,10 @@
     3.4  #include <asm/shadow.h>
     3.5  
     3.6  /* Dynamic (run-time adjusted) execution control flags. */
     3.7 -static u32 vmx_pin_based_exec_control;
     3.8 -static u32 vmx_cpu_based_exec_control;
     3.9 -static u32 vmx_vmexit_control;
    3.10 -static u32 vmx_vmentry_control;
    3.11 +u32 vmx_pin_based_exec_control;
    3.12 +u32 vmx_cpu_based_exec_control;
    3.13 +u32 vmx_vmexit_control;
    3.14 +u32 vmx_vmentry_control;
    3.15  
    3.16  static u32 vmcs_revision_id;
    3.17  
    3.18 @@ -61,25 +61,6 @@ static u32 adjust_vmx_controls(u32 ctl_m
    3.19      return ctl;
    3.20  }
    3.21  
    3.22 -static void disable_intercept_for_msr(u32 msr)
    3.23 -{
    3.24 -    /*
    3.25 -     * See Intel PRM Vol. 3, 20.6.9 (MSR-Bitmap Address).
    3.26 -     * We can control MSRs 0x00000000-0x00001fff and 0xc0000000-0xc0001fff.
    3.27 -     */
    3.28 -    if ( msr <= 0x1fff )
    3.29 -    {
    3.30 -        __clear_bit(msr, hvm_msr_bitmap + 0x000); /* read-low */
    3.31 -        __clear_bit(msr, hvm_msr_bitmap + 0x400); /* write-low */
    3.32 -    }
    3.33 -    else if ( (msr >= 0xc0000000) && (msr <= 0xc0001fff) )
    3.34 -    {
    3.35 -        msr &= 0x1fff;
    3.36 -        __clear_bit(msr, hvm_msr_bitmap + 0x800); /* read-high */
    3.37 -        __clear_bit(msr, hvm_msr_bitmap + 0xc00); /* write-high */
    3.38 -    }
    3.39 -}
    3.40 -
    3.41  void vmx_init_vmcs_config(void)
    3.42  {
    3.43      u32 vmx_msr_low, vmx_msr_high, min, max;
    3.44 @@ -125,9 +106,6 @@ void vmx_init_vmcs_config(void)
    3.45          vmx_cpu_based_exec_control = _vmx_cpu_based_exec_control;
    3.46          vmx_vmexit_control         = _vmx_vmexit_control;
    3.47          vmx_vmentry_control        = _vmx_vmentry_control;
    3.48 -
    3.49 -        disable_intercept_for_msr(MSR_FS_BASE);
    3.50 -        disable_intercept_for_msr(MSR_GS_BASE);
    3.51      }
    3.52      else
    3.53      {
    3.54 @@ -310,7 +288,7 @@ static void construct_vmcs(struct vcpu *
    3.55      __vmwrite(CPU_BASED_VM_EXEC_CONTROL, vmx_cpu_based_exec_control);
    3.56      v->arch.hvm_vcpu.u.vmx.exec_control = vmx_cpu_based_exec_control;
    3.57  
    3.58 -    if ( vmx_cpu_based_exec_control & CPU_BASED_ACTIVATE_MSR_BITMAP )
    3.59 +    if ( cpu_has_vmx_msr_bitmap )
    3.60          __vmwrite(MSR_BITMAP, virt_to_maddr(hvm_msr_bitmap));
    3.61  
    3.62      /* I/O access bitmap. */
     4.1 --- a/xen/arch/x86/hvm/vmx/vmx.c	Fri Mar 30 18:39:34 2007 +0100
     4.2 +++ b/xen/arch/x86/hvm/vmx/vmx.c	Fri Mar 30 18:42:49 2007 +0100
     4.3 @@ -996,7 +996,28 @@ static int vmx_event_injection_faulted(s
     4.4      return (idtv_info_field & INTR_INFO_VALID_MASK);
     4.5  }
     4.6  
     4.7 +static void disable_intercept_for_msr(u32 msr)
     4.8 +{
     4.9 +    /*
    4.10 +     * See Intel PRM Vol. 3, 20.6.9 (MSR-Bitmap Address). Early manuals
    4.11 +     * have the write-low and read-high bitmap offsets the wrong way round.
    4.12 +     * We can control MSRs 0x00000000-0x00001fff and 0xc0000000-0xc0001fff.
    4.13 +     */
    4.14 +    if ( msr <= 0x1fff )
    4.15 +    {
    4.16 +        __clear_bit(msr, hvm_msr_bitmap + 0x000); /* read-low */
    4.17 +        __clear_bit(msr, hvm_msr_bitmap + 0x800); /* write-low */
    4.18 +    }
    4.19 +    else if ( (msr >= 0xc0000000) && (msr <= 0xc0001fff) )
    4.20 +    {
    4.21 +        msr &= 0x1fff;
    4.22 +        __clear_bit(msr, hvm_msr_bitmap + 0x400); /* read-high */
    4.23 +        __clear_bit(msr, hvm_msr_bitmap + 0xc00); /* write-high */
    4.24 +    }
    4.25 +}
    4.26 +
    4.27  static struct hvm_function_table vmx_function_table = {
    4.28 +    .name                 = "VMX",
    4.29      .disable              = stop_vmx,
    4.30      .vcpu_initialise      = vmx_vcpu_initialise,
    4.31      .vcpu_destroy         = vmx_vcpu_destroy,
    4.32 @@ -1074,12 +1095,20 @@ int start_vmx(void)
    4.33          return 0;
    4.34      }
    4.35  
    4.36 -    printk("VMXON is done\n");
    4.37 -
    4.38      vmx_save_host_msrs();
    4.39  
    4.40 +    if ( smp_processor_id() != 0 )
    4.41 +        return 1;
    4.42 +
    4.43      hvm_enable(&vmx_function_table);
    4.44  
    4.45 +    if ( cpu_has_vmx_msr_bitmap )
    4.46 +    {
    4.47 +        printk("VMX: MSR intercept bitmap enabled\n");
    4.48 +        disable_intercept_for_msr(MSR_FS_BASE);
    4.49 +        disable_intercept_for_msr(MSR_GS_BASE);
    4.50 +    }
    4.51 +
    4.52      return 1;
    4.53  }
    4.54  
     5.1 --- a/xen/include/asm-ia64/vmx_vpd.h	Fri Mar 30 18:39:34 2007 +0100
     5.2 +++ b/xen/include/asm-ia64/vmx_vpd.h	Fri Mar 30 18:42:49 2007 +0100
     5.3 @@ -97,9 +97,6 @@ struct arch_vmx_struct {
     5.4  #endif
     5.5  };
     5.6  
     5.7 -#define vmx_schedule_tail(next)         \
     5.8 -    (next)->thread.arch_vmx.arch_vmx_schedule_tail((next))
     5.9 -
    5.10  #define VMX_DOMAIN(v)   v->arch.arch_vmx.flags
    5.11  
    5.12  #define ARCH_VMX_IO_WAIT        3       /* Waiting for I/O completion */
     6.1 --- a/xen/include/asm-x86/hvm/hvm.h	Fri Mar 30 18:39:34 2007 +0100
     6.2 +++ b/xen/include/asm-x86/hvm/hvm.h	Fri Mar 30 18:42:49 2007 +0100
     6.3 @@ -61,6 +61,8 @@ typedef struct segment_register {
     6.4   * supports Intel's VT-x and AMD's SVM extensions.
     6.5   */
     6.6  struct hvm_function_table {
     6.7 +    char *name;
     6.8 +
     6.9      /*
    6.10       *  Disable HVM functionality
    6.11       */
     7.1 --- a/xen/include/asm-x86/hvm/vmx/vmcs.h	Fri Mar 30 18:39:34 2007 +0100
     7.2 +++ b/xen/include/asm-x86/hvm/vmx/vmcs.h	Fri Mar 30 18:42:49 2007 +0100
     7.3 @@ -80,9 +80,6 @@ struct arch_vmx_struct {
     7.4      unsigned long        vmxassist_enabled:1;
     7.5  };
     7.6  
     7.7 -#define vmx_schedule_tail(next)         \
     7.8 -    (next)->thread.arch_vmx.arch_vmx_schedule_tail((next))
     7.9 -
    7.10  struct vmcs_struct *vmx_alloc_host_vmcs(void);
    7.11  void vmx_free_host_vmcs(struct vmcs_struct *vmcs);
    7.12  
    7.13 @@ -91,11 +88,6 @@ void vmx_destroy_vmcs(struct vcpu *v);
    7.14  void vmx_vmcs_enter(struct vcpu *v);
    7.15  void vmx_vmcs_exit(struct vcpu *v);
    7.16  
    7.17 -#define VMCS_USE_HOST_ENV       1
    7.18 -#define VMCS_USE_SEPARATE_ENV   0
    7.19 -
    7.20 -extern int vmcs_version;
    7.21 -
    7.22  #define CPU_BASED_VIRTUAL_INTR_PENDING  0x00000004
    7.23  #define CPU_BASED_USE_TSC_OFFSETING     0x00000008
    7.24  #define CPU_BASED_HLT_EXITING           0x00000080
    7.25 @@ -112,16 +104,23 @@ extern int vmcs_version;
    7.26  #define CPU_BASED_ACTIVATE_MSR_BITMAP   0x10000000
    7.27  #define CPU_BASED_MONITOR_EXITING       0x20000000
    7.28  #define CPU_BASED_PAUSE_EXITING         0x40000000
    7.29 +extern u32 vmx_cpu_based_exec_control;
    7.30  
    7.31  #define PIN_BASED_EXT_INTR_MASK         0x00000001
    7.32  #define PIN_BASED_NMI_EXITING           0x00000008
    7.33 +extern u32 vmx_pin_based_exec_control;
    7.34  
    7.35  #define VM_EXIT_IA32E_MODE              0x00000200
    7.36  #define VM_EXIT_ACK_INTR_ON_EXIT        0x00008000
    7.37 +extern u32 vmx_vmexit_control;
    7.38  
    7.39  #define VM_ENTRY_IA32E_MODE             0x00000200
    7.40  #define VM_ENTRY_SMM                    0x00000400
    7.41  #define VM_ENTRY_DEACT_DUAL_MONITOR     0x00000800
    7.42 +extern u32 vmx_vmentry_control;
    7.43 +
    7.44 +#define cpu_has_vmx_msr_bitmap \
    7.45 +    (vmx_cpu_based_exec_control & CPU_BASED_ACTIVATE_MSR_BITMAP)
    7.46  
    7.47  /* VMCS Encordings */
    7.48  enum vmcs_field {
     8.1 --- a/xen/include/asm-x86/hvm/vmx/vmx.h	Fri Mar 30 18:39:34 2007 +0100
     8.2 +++ b/xen/include/asm-x86/hvm/vmx/vmx.h	Fri Mar 30 18:42:49 2007 +0100
     8.3 @@ -33,8 +33,6 @@ void vmx_intr_assist(void);
     8.4  void vmx_do_resume(struct vcpu *);
     8.5  void set_guest_time(struct vcpu *v, u64 gtime);
     8.6  
     8.7 -extern unsigned int cpu_rev;
     8.8 -
     8.9  /*
    8.10   * Exit Reasons
    8.11   */