[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH v4 2/4] VMX: clean up capability checks



VMCS size validation on APs should check against BP's size.

No need for a separate cpu_has_vmx_ins_outs_instr_info variable
anymore.

Use proper symbolics.

Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>

--- a/xen/arch/x86/hvm/vmx/vmcs.c
+++ b/xen/arch/x86/hvm/vmx/vmcs.c
@@ -70,7 +70,6 @@ u32 vmx_secondary_exec_control __read_mo
 u32 vmx_vmexit_control __read_mostly;
 u32 vmx_vmentry_control __read_mostly;
 u64 vmx_ept_vpid_cap __read_mostly;
-bool_t cpu_has_vmx_ins_outs_instr_info __read_mostly;
 
 static DEFINE_PER_CPU_READ_MOSTLY(struct vmcs_struct *, vmxon_region);
 static DEFINE_PER_CPU(struct vmcs_struct *, current_vmcs);
@@ -294,24 +293,33 @@ static int vmx_init_vmcs_config(void)
     if ( !vmx_pin_based_exec_control )
     {
         /* First time through. */
-        vmcs_revision_id = vmx_basic_msr_low;
+        vmcs_revision_id           = vmx_basic_msr_low & 
VMX_BASIC_REVISION_MASK;
         vmx_pin_based_exec_control = _vmx_pin_based_exec_control;
         vmx_cpu_based_exec_control = _vmx_cpu_based_exec_control;
         vmx_secondary_exec_control = _vmx_secondary_exec_control;
         vmx_ept_vpid_cap           = _vmx_ept_vpid_cap;
         vmx_vmexit_control         = _vmx_vmexit_control;
         vmx_vmentry_control        = _vmx_vmentry_control;
-        cpu_has_vmx_ins_outs_instr_info = !!(vmx_basic_msr_high & (1U<<22));
         vmx_basic_msr              = ((u64)vmx_basic_msr_high << 32) |
                                      vmx_basic_msr_low;
         vmx_display_features();
+
+        /* IA-32 SDM Vol 3B: VMCS size is never greater than 4kB. */
+        if ( (vmx_basic_msr_high & (VMX_BASIC_VMCS_SIZE_MASK >> 32)) >
+             PAGE_SIZE )
+        {
+            printk("VMX: CPU%d VMCS size is too big (%Lu bytes)\n",
+                   smp_processor_id(),
+                   vmx_basic_msr_high & (VMX_BASIC_VMCS_SIZE_MASK >> 32));
+            return -EINVAL;
+        }
     }
     else
     {
         /* Globals are already initialised: re-check them. */
         mismatch |= cap_check(
             "VMCS revision ID",
-            vmcs_revision_id, vmx_basic_msr_low);
+            vmcs_revision_id, vmx_basic_msr_low & VMX_BASIC_REVISION_MASK);
         mismatch |= cap_check(
             "Pin-Based Exec Control",
             vmx_pin_based_exec_control, _vmx_pin_based_exec_control);
@@ -331,13 +339,21 @@ static int vmx_init_vmcs_config(void)
             "EPT and VPID Capability",
             vmx_ept_vpid_cap, _vmx_ept_vpid_cap);
         if ( cpu_has_vmx_ins_outs_instr_info !=
-             !!(vmx_basic_msr_high & (1U<<22)) )
+             !!(vmx_basic_msr_high & (VMX_BASIC_INS_OUT_INFO >> 32)) )
         {
             printk("VMX INS/OUTS Instruction Info: saw %d expected %d\n",
-                   !!(vmx_basic_msr_high & (1U<<22)),
+                   !!(vmx_basic_msr_high & (VMX_BASIC_INS_OUT_INFO >> 32)),
                    cpu_has_vmx_ins_outs_instr_info);
             mismatch = 1;
         }
+        if ( (vmx_basic_msr_high & (VMX_BASIC_VMCS_SIZE_MASK >> 32)) !=
+             ((vmx_basic_msr & VMX_BASIC_VMCS_SIZE_MASK) >> 32) )
+        {
+            printk("VMX: CPU%d unexpected VMCS size %Lu\n",
+                   smp_processor_id(),
+                   vmx_basic_msr_high & (VMX_BASIC_VMCS_SIZE_MASK >> 32));
+            mismatch = 1;
+        }
         if ( mismatch )
         {
             printk("VMX: Capabilities fatally differ between CPU%d and CPU0\n",
@@ -346,16 +362,8 @@ static int vmx_init_vmcs_config(void)
         }
     }
 
-    /* IA-32 SDM Vol 3B: VMCS size is never greater than 4kB. */
-    if ( (vmx_basic_msr_high & 0x1fff) > PAGE_SIZE )
-    {
-        printk("VMX: CPU%d VMCS size is too big (%u bytes)\n",
-               smp_processor_id(), vmx_basic_msr_high & 0x1fff);
-        return -EINVAL;
-    }
-
     /* IA-32 SDM Vol 3B: 64-bit CPUs always have VMX_BASIC_MSR[48]==0. */
-    if ( vmx_basic_msr_high & (1u<<16) )
+    if ( vmx_basic_msr_high & (VMX_BASIC_32BIT_ADDRESSES >> 32) )
     {
         printk("VMX: CPU%d limits VMX structure pointers to 32 bits\n",
                smp_processor_id());
@@ -363,10 +371,12 @@ static int vmx_init_vmcs_config(void)
     }
 
     /* Require Write-Back (WB) memory type for VMCS accesses. */
-    if ( ((vmx_basic_msr_high >> 18) & 15) != 6 )
+    opt = (vmx_basic_msr_high & (VMX_BASIC_MEMORY_TYPE_MASK >> 32)) /
+          ((VMX_BASIC_MEMORY_TYPE_MASK & -VMX_BASIC_MEMORY_TYPE_MASK) >> 32);
+    if ( opt != MTRR_TYPE_WRBACK )
     {
         printk("VMX: CPU%d has unexpected VMCS access type %u\n",
-               smp_processor_id(), (vmx_basic_msr_high >> 18) & 15);
+               smp_processor_id(), opt);
         return -EINVAL;
     }
 
--- a/xen/include/asm-x86/hvm/vmx/vmcs.h
+++ b/xen/include/asm-x86/hvm/vmx/vmcs.h
@@ -210,8 +210,6 @@ extern u32 vmx_vmentry_control;
 #define SECONDARY_EXEC_ENABLE_VMCS_SHADOWING    0x00004000
 extern u32 vmx_secondary_exec_control;
 
-extern bool_t cpu_has_vmx_ins_outs_instr_info;
-
 #define VMX_EPT_EXEC_ONLY_SUPPORTED             0x00000001
 #define VMX_EPT_WALK_LENGTH_4_SUPPORTED         0x00000040
 #define VMX_EPT_MEMORY_TYPE_UC                  0x00000100
@@ -278,6 +276,12 @@ extern bool_t cpu_has_vmx_ins_outs_instr
 #define VMX_INTR_SHADOW_SMI             0x00000004
 #define VMX_INTR_SHADOW_NMI             0x00000008
 
+#define VMX_BASIC_REVISION_MASK         0x7fffffff
+#define VMX_BASIC_VMCS_SIZE_MASK        (0x1fffULL << 32)
+#define VMX_BASIC_32BIT_ADDRESSES       (1ULL << 48)
+#define VMX_BASIC_DUAL_MONITOR          (1ULL << 49)
+#define VMX_BASIC_MEMORY_TYPE_MASK      (0xfULL << 50)
+#define VMX_BASIC_INS_OUT_INFO          (1ULL << 54)
 /* 
  * bit 55 of IA32_VMX_BASIC MSR, indicating whether any VMX controls that
  * default to 1 may be cleared to 0.
@@ -285,6 +289,8 @@ extern bool_t cpu_has_vmx_ins_outs_instr
 #define VMX_BASIC_DEFAULT1_ZERO                (1ULL << 55)
 
 extern u64 vmx_basic_msr;
+#define cpu_has_vmx_ins_outs_instr_info \
+    (!!(vmx_basic_msr & VMX_BASIC_INS_OUT_INFO))
 
 /* Guest interrupt status */
 #define VMX_GUEST_INTR_STATUS_SUBFIELD_BITMASK  0x0FF


Attachment: VMX-check-capabilities.patch
Description: Text document

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.