]> xenbits.xensource.com Git - xen.git/commitdiff
hvm vmx: Fix MSR-intercept bitmap initialisation (two bitmap offsets
authorKeir Fraser <keir@xensource.com>
Fri, 30 Mar 2007 17:42:49 +0000 (18:42 +0100)
committerKeir Fraser <keir@xensource.com>
Fri, 30 Mar 2007 17:42:49 +0000 (18:42 +0100)
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>
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

index 3a40d69c011f7405db07611bc52cbed38e45e788..60b415ea15b5ea7beef0f1b75e210fc41c34410c 100644 (file)
@@ -65,8 +65,8 @@ char __attribute__ ((__section__ (".bss.page_aligned")))
 
 void hvm_enable(struct hvm_function_table *fns)
 {
-    if ( hvm_enabled )
-        return;
+    BUG_ON(hvm_enabled);
+    printk("HVM: %s enabled\n", fns->name);
 
     /*
      * Allow direct access to the PC debug port (it is often used for I/O
index c54d1272bd6e8c7bc944fb1404a6ac1e793a96d4..99f3e87713a5a37f4f74389be7ae9bbd7b1252b5 100644 (file)
@@ -890,6 +890,7 @@ static int svm_event_injection_faulted(struct vcpu *v)
 }
 
 static struct hvm_function_table svm_function_table = {
+    .name                 = "SVM",
     .disable              = stop_svm,
     .vcpu_initialise      = svm_vcpu_initialise,
     .vcpu_destroy         = svm_vcpu_destroy,
@@ -954,9 +955,8 @@ int start_svm(void)
         return 0;
     }
 
-    if (!hsa[cpu])
-        if (!(hsa[cpu] = alloc_host_save_area()))
-            return 0;
+    if ( (hsa[cpu] == NULL) && ((hsa[cpu] = alloc_host_save_area()) == NULL) )
+        return 0;
     
     rdmsr(MSR_EFER, eax, edx);
     eax |= EFER_SVME;
@@ -971,13 +971,15 @@ int start_svm(void)
     phys_hsa_hi = (u32) (phys_hsa >> 32);    
     wrmsr(MSR_K8_VM_HSAVE_PA, phys_hsa_lo, phys_hsa_hi);
   
-    if (!root_vmcb[cpu])
-        if (!(root_vmcb[cpu] = alloc_vmcb())) 
-            return 0;
+    if ( (root_vmcb[cpu] == NULL) &&
+         ((root_vmcb[cpu] = alloc_vmcb()) == NULL) )
+        return 0;
     root_vmcb_pa[cpu] = virt_to_maddr(root_vmcb[cpu]);
 
-    if (cpu == 0)
-        setup_vmcb_dump();
+    if ( cpu != 0 )
+        return 1;
+
+    setup_vmcb_dump();
 
     hvm_enable(&svm_function_table);
 
index a8d92dd1cf67ac59f73bb482d17fd005a5d9bf39..beed602f9b40c80c2ea0d72b10d023f64dfc77fa 100644 (file)
 #include <asm/shadow.h>
 
 /* Dynamic (run-time adjusted) execution control flags. */
-static u32 vmx_pin_based_exec_control;
-static u32 vmx_cpu_based_exec_control;
-static u32 vmx_vmexit_control;
-static u32 vmx_vmentry_control;
+u32 vmx_pin_based_exec_control;
+u32 vmx_cpu_based_exec_control;
+u32 vmx_vmexit_control;
+u32 vmx_vmentry_control;
 
 static u32 vmcs_revision_id;
 
@@ -61,25 +61,6 @@ static u32 adjust_vmx_controls(u32 ctl_min, u32 ctl_max, u32 msr)
     return ctl;
 }
 
-static void disable_intercept_for_msr(u32 msr)
-{
-    /*
-     * See Intel PRM Vol. 3, 20.6.9 (MSR-Bitmap Address).
-     * We can control MSRs 0x00000000-0x00001fff and 0xc0000000-0xc0001fff.
-     */
-    if ( msr <= 0x1fff )
-    {
-        __clear_bit(msr, hvm_msr_bitmap + 0x000); /* read-low */
-        __clear_bit(msr, hvm_msr_bitmap + 0x400); /* write-low */
-    }
-    else if ( (msr >= 0xc0000000) && (msr <= 0xc0001fff) )
-    {
-        msr &= 0x1fff;
-        __clear_bit(msr, hvm_msr_bitmap + 0x800); /* read-high */
-        __clear_bit(msr, hvm_msr_bitmap + 0xc00); /* write-high */
-    }
-}
-
 void vmx_init_vmcs_config(void)
 {
     u32 vmx_msr_low, vmx_msr_high, min, max;
@@ -125,9 +106,6 @@ void vmx_init_vmcs_config(void)
         vmx_cpu_based_exec_control = _vmx_cpu_based_exec_control;
         vmx_vmexit_control         = _vmx_vmexit_control;
         vmx_vmentry_control        = _vmx_vmentry_control;
-
-        disable_intercept_for_msr(MSR_FS_BASE);
-        disable_intercept_for_msr(MSR_GS_BASE);
     }
     else
     {
@@ -310,7 +288,7 @@ static void construct_vmcs(struct vcpu *v)
     __vmwrite(CPU_BASED_VM_EXEC_CONTROL, vmx_cpu_based_exec_control);
     v->arch.hvm_vcpu.u.vmx.exec_control = vmx_cpu_based_exec_control;
 
-    if ( vmx_cpu_based_exec_control & CPU_BASED_ACTIVATE_MSR_BITMAP )
+    if ( cpu_has_vmx_msr_bitmap )
         __vmwrite(MSR_BITMAP, virt_to_maddr(hvm_msr_bitmap));
 
     /* I/O access bitmap. */
index 3856a31e96a0b125753c35a8e8e0a9ce5327500b..368733c1a665aa8c9e3112ba10a7f7380efa34f8 100644 (file)
@@ -996,7 +996,28 @@ static int vmx_event_injection_faulted(struct vcpu *v)
     return (idtv_info_field & INTR_INFO_VALID_MASK);
 }
 
+static void disable_intercept_for_msr(u32 msr)
+{
+    /*
+     * See Intel PRM Vol. 3, 20.6.9 (MSR-Bitmap Address). Early manuals
+     * have the write-low and read-high bitmap offsets the wrong way round.
+     * We can control MSRs 0x00000000-0x00001fff and 0xc0000000-0xc0001fff.
+     */
+    if ( msr <= 0x1fff )
+    {
+        __clear_bit(msr, hvm_msr_bitmap + 0x000); /* read-low */
+        __clear_bit(msr, hvm_msr_bitmap + 0x800); /* write-low */
+    }
+    else if ( (msr >= 0xc0000000) && (msr <= 0xc0001fff) )
+    {
+        msr &= 0x1fff;
+        __clear_bit(msr, hvm_msr_bitmap + 0x400); /* read-high */
+        __clear_bit(msr, hvm_msr_bitmap + 0xc00); /* write-high */
+    }
+}
+
 static struct hvm_function_table vmx_function_table = {
+    .name                 = "VMX",
     .disable              = stop_vmx,
     .vcpu_initialise      = vmx_vcpu_initialise,
     .vcpu_destroy         = vmx_vcpu_destroy,
@@ -1074,12 +1095,20 @@ int start_vmx(void)
         return 0;
     }
 
-    printk("VMXON is done\n");
-
     vmx_save_host_msrs();
 
+    if ( smp_processor_id() != 0 )
+        return 1;
+
     hvm_enable(&vmx_function_table);
 
+    if ( cpu_has_vmx_msr_bitmap )
+    {
+        printk("VMX: MSR intercept bitmap enabled\n");
+        disable_intercept_for_msr(MSR_FS_BASE);
+        disable_intercept_for_msr(MSR_GS_BASE);
+    }
+
     return 1;
 }
 
index 85bd0b1b0bdcdc1ce9fb0d54ecc75d54cfd4b22e..39acbd1c239096e84772d7c6c8b0187835459892 100644 (file)
@@ -97,9 +97,6 @@ struct arch_vmx_struct {
 #endif
 };
 
-#define vmx_schedule_tail(next)         \
-    (next)->thread.arch_vmx.arch_vmx_schedule_tail((next))
-
 #define VMX_DOMAIN(v)   v->arch.arch_vmx.flags
 
 #define ARCH_VMX_IO_WAIT        3       /* Waiting for I/O completion */
index 3d3aa356836758c755480df702aad8cce13855bc..4872505ef3af6ece75401f815a109b2a0c1f0f2c 100644 (file)
@@ -61,6 +61,8 @@ typedef struct segment_register {
  * supports Intel's VT-x and AMD's SVM extensions.
  */
 struct hvm_function_table {
+    char *name;
+
     /*
      *  Disable HVM functionality
      */
index 077dd619198eede214db23f70da5d17591a4f4a3..23a0b71be078b05dd245383d39875f0da278cc1d 100644 (file)
@@ -80,9 +80,6 @@ struct arch_vmx_struct {
     unsigned long        vmxassist_enabled:1;
 };
 
-#define vmx_schedule_tail(next)         \
-    (next)->thread.arch_vmx.arch_vmx_schedule_tail((next))
-
 struct vmcs_struct *vmx_alloc_host_vmcs(void);
 void vmx_free_host_vmcs(struct vmcs_struct *vmcs);
 
@@ -91,11 +88,6 @@ void vmx_destroy_vmcs(struct vcpu *v);
 void vmx_vmcs_enter(struct vcpu *v);
 void vmx_vmcs_exit(struct vcpu *v);
 
-#define VMCS_USE_HOST_ENV       1
-#define VMCS_USE_SEPARATE_ENV   0
-
-extern int vmcs_version;
-
 #define CPU_BASED_VIRTUAL_INTR_PENDING  0x00000004
 #define CPU_BASED_USE_TSC_OFFSETING     0x00000008
 #define CPU_BASED_HLT_EXITING           0x00000080
@@ -112,16 +104,23 @@ extern int vmcs_version;
 #define CPU_BASED_ACTIVATE_MSR_BITMAP   0x10000000
 #define CPU_BASED_MONITOR_EXITING       0x20000000
 #define CPU_BASED_PAUSE_EXITING         0x40000000
+extern u32 vmx_cpu_based_exec_control;
 
 #define PIN_BASED_EXT_INTR_MASK         0x00000001
 #define PIN_BASED_NMI_EXITING           0x00000008
+extern u32 vmx_pin_based_exec_control;
 
 #define VM_EXIT_IA32E_MODE              0x00000200
 #define VM_EXIT_ACK_INTR_ON_EXIT        0x00008000
+extern u32 vmx_vmexit_control;
 
 #define VM_ENTRY_IA32E_MODE             0x00000200
 #define VM_ENTRY_SMM                    0x00000400
 #define VM_ENTRY_DEACT_DUAL_MONITOR     0x00000800
+extern u32 vmx_vmentry_control;
+
+#define cpu_has_vmx_msr_bitmap \
+    (vmx_cpu_based_exec_control & CPU_BASED_ACTIVATE_MSR_BITMAP)
 
 /* VMCS Encordings */
 enum vmcs_field {
index 5ee44f9650934ef9b1c72b8338989513e68cd76f..38ad5e25bd0c5c3f751990941cf83ba8c9193905 100644 (file)
@@ -33,8 +33,6 @@ void vmx_intr_assist(void);
 void vmx_do_resume(struct vcpu *);
 void set_guest_time(struct vcpu *v, u64 gtime);
 
-extern unsigned int cpu_rev;
-
 /*
  * Exit Reasons
  */