WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-devel

[Xen-devel] [PATCH] does EPT capabilities detection strictly according t

To: "xen-devel@xxxxxxxxxxxxxxxxxxx" <xen-devel@xxxxxxxxxxxxxxxxxxx>
Subject: [Xen-devel] [PATCH] does EPT capabilities detection strictly according to Intel SDM
From: "Li, Xin" <xin.li@xxxxxxxxx>
Date: Mon, 31 May 2010 22:26:08 +0800
Accept-language: zh-CN, en-US
Acceptlanguage: zh-CN, en-US
Delivery-date: Mon, 31 May 2010 07:27:22 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
Thread-index: AcsAzTY0pz8FQMOkQLeXMakuD9vUJQ==
Thread-topic: [PATCH] does EPT capabilities detection strictly according to Intel SDM
VMX: does EPT capabilities detection strictly according to Intel SDM.

Signed-off-by: Xin Li <xin.li@xxxxxxxxx>

diff -r 96917cf25bf3 xen/arch/x86/hvm/svm/svm.c
--- a/xen/arch/x86/hvm/svm/svm.c        Fri May 28 10:54:07 2010 +0100
+++ b/xen/arch/x86/hvm/svm/svm.c        Sun May 30 19:10:21 2010 -0700
@@ -935,9 +935,9 @@ struct hvm_function_table * __init start
                          cpuid_edx(0x8000000A) : 0);
 
     svm_function_table.hap_supported = cpu_has_svm_npt;
-    svm_function_table.hap_superpage_level =
+    svm_function_table.hap_capabilities = HVM_HAP_SUPERPAGE_2MB |
         ((CONFIG_PAGING_LEVELS == 4) && (cpuid_edx(0x80000001) & 0x04000000)) ?
-            2 : 1;
+            HVM_HAP_SUPERPAGE_1GB : 0;
 
     return &svm_function_table;
 }
diff -r 96917cf25bf3 xen/arch/x86/hvm/vmx/vmcs.c
--- a/xen/arch/x86/hvm/vmx/vmcs.c       Fri May 28 10:54:07 2010 +0100
+++ b/xen/arch/x86/hvm/vmx/vmcs.c       Sun May 30 19:10:21 2010 -0700
@@ -64,7 +64,7 @@ u32 vmx_secondary_exec_control __read_mo
 u32 vmx_secondary_exec_control __read_mostly;
 u32 vmx_vmexit_control __read_mostly;
 u32 vmx_vmentry_control __read_mostly;
-u8 vmx_ept_super_page_level_limit __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 *, host_vmcs);
@@ -92,10 +92,10 @@ static void __init vmx_display_features(
     if ( !printed )
         printk(" - none\n");
 
-    if ( vmx_ept_super_page_level_limit )
-        printk("EPT supports %s super page.\n",
-               (vmx_ept_super_page_level_limit == 2) ? "1G" :
-               ((vmx_ept_super_page_level_limit == 1) ? "2M" : "4K"));
+    if ( cpu_has_vmx_ept_1gb )
+        printk("EPT supports 1GB super page.\n");
+    if ( cpu_has_vmx_ept_2mb )
+        printk("EPT supports 2MB super page.\n");
 }
 
 static u32 adjust_vmx_controls(
@@ -132,7 +132,7 @@ static int vmx_init_vmcs_config(void)
     u32 _vmx_pin_based_exec_control;
     u32 _vmx_cpu_based_exec_control;
     u32 _vmx_secondary_exec_control = 0;
-    u8 ept_super_page_level_limit = 0;
+    u64 _vmx_ept_vpid_cap = 0;
     u32 _vmx_vmexit_control;
     u32 _vmx_vmentry_control;
     bool_t mismatch = 0;
@@ -208,16 +208,12 @@ static int vmx_init_vmcs_config(void)
             _vmx_secondary_exec_control &=
                 ~(SECONDARY_EXEC_ENABLE_EPT |
                   SECONDARY_EXEC_UNRESTRICTED_GUEST);
-        if ( _vmx_secondary_exec_control & SECONDARY_EXEC_ENABLE_EPT )
-        {
-            uint64_t cap;
-            rdmsrl(MSR_IA32_VMX_EPT_VPID_CAP, cap);
-            if ( cap & VMX_EPT_SUPER_PAGE_1G )
-                ept_super_page_level_limit = 2;
-            else if ( cap & VMX_EPT_SUPER_PAGE_2M )
-                ept_super_page_level_limit = 1;
-        }
     }
+
+    /* The IA32_VMX_EPT_VPID_CAP MSR exists only when EPT or VPID available */
+    if ( _vmx_secondary_exec_control &
+          (SECONDARY_EXEC_ENABLE_EPT | SECONDARY_EXEC_ENABLE_VPID) )
+        rdmsrl(MSR_IA32_VMX_EPT_VPID_CAP, _vmx_ept_vpid_cap);
 
     if ( (_vmx_secondary_exec_control & SECONDARY_EXEC_PAUSE_LOOP_EXITING) &&
           ple_gap == 0 )
@@ -256,7 +252,7 @@ static int vmx_init_vmcs_config(void)
         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_super_page_level_limit = ept_super_page_level_limit;
+        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));
@@ -283,12 +279,9 @@ static int vmx_init_vmcs_config(void)
         mismatch |= cap_check(
             "VMEntry Control",
             vmx_vmentry_control, _vmx_vmentry_control);
-        if ( vmx_ept_super_page_level_limit > ept_super_page_level_limit )
-        {
-            printk("EPT Super Page Limit: saw %u expected >= %u\n",
-                   ept_super_page_level_limit, vmx_ept_super_page_level_limit);
-            mismatch = 1;
-        }
+        mismatch |= cap_check(
+            "EPT Super Page Capability",
+            vmx_ept_vpid_cap, _vmx_ept_vpid_cap);
         if ( cpu_has_vmx_ins_outs_instr_info !=
              !!(vmx_basic_msr_high & (1U<<22)) )
         {
diff -r 96917cf25bf3 xen/arch/x86/hvm/vmx/vmx.c
--- a/xen/arch/x86/hvm/vmx/vmx.c        Fri May 28 10:54:07 2010 +0100
+++ b/xen/arch/x86/hvm/vmx/vmx.c        Sun May 30 19:10:21 2010 -0700
@@ -1432,10 +1432,16 @@ struct hvm_function_table * __init start
     if ( cpu_has_vmx_ept )
     {
         vmx_function_table.hap_supported = 1;
+
+        vmx_function_table.hap_capabilities = 0;
+
+        if ( cpu_has_vmx_ept_2mb )
+            vmx_function_table.hap_capabilities |= HVM_HAP_SUPERPAGE_2MB;
+        if ( cpu_has_vmx_ept_1gb )
+            vmx_function_table.hap_capabilities |= HVM_HAP_SUPERPAGE_1GB;
+
         setup_ept_dump();
     }
-    
-    vmx_function_table.hap_superpage_level = vmx_ept_super_page_level_limit;
 
     setup_vmcs_dump();
 
diff -r 96917cf25bf3 xen/arch/x86/mm/hap/p2m-ept.c
--- a/xen/arch/x86/mm/hap/p2m-ept.c     Fri May 28 10:54:07 2010 +0100
+++ b/xen/arch/x86/mm/hap/p2m-ept.c     Sun May 30 19:10:21 2010 -0700
@@ -308,9 +308,14 @@ ept_set_entry(struct domain *d, unsigned
         int num = order / EPT_TABLE_ORDER;
         int level;
         ept_entry_t *split_ept_entry;
-    
-        if ( num >= cpu_vmx_ept_super_page_level_limit )
-            num = cpu_vmx_ept_super_page_level_limit;
+
+        if ( (num >= 2) && hvm_hap_has_1gb(d) )
+            num = 2;
+        else if ( (num >= 1) && hvm_hap_has_2mb(d) )
+            num = 1;
+        else
+            num = 0;
+
         for ( level = split_level; level > num ; level-- )
         {
             rv = ept_split_large_page(d, &table, &index, gfn, level);
diff -r 96917cf25bf3 xen/arch/x86/mm/p2m.c
--- a/xen/arch/x86/mm/p2m.c     Fri May 28 10:54:07 2010 +0100
+++ b/xen/arch/x86/mm/p2m.c     Sun May 30 19:10:21 2010 -0700
@@ -1758,10 +1758,9 @@ int set_p2m_entry(struct domain *d, unsi
     {
         if ( is_hvm_domain(d) && paging_mode_hap(d) )
             order = ( (((gfn | mfn_x(mfn) | todo) & ((1ul << 18) - 1)) == 0) &&
-                      (hvm_funcs.hap_superpage_level == 2) &&
-                      opt_hap_1gb ) ? 18 :
-                ((((gfn | mfn_x(mfn) | todo) & ((1ul << 9) - 1)) == 0) &&
-                      (hvm_funcs.hap_superpage_level >= 1)) ? 9 : 0;
+                      hvm_hap_has_1gb(d) && opt_hap_1gb ) ? 18 :
+                      ((((gfn | mfn_x(mfn) | todo) & ((1ul << 9) - 1)) == 0) &&
+                      hvm_hap_has_2mb(d)) ? 9 : 0;
         else
             order = 0;
 
diff -r 96917cf25bf3 xen/include/asm-x86/hvm/hvm.h
--- a/xen/include/asm-x86/hvm/hvm.h     Fri May 28 10:54:07 2010 +0100
+++ b/xen/include/asm-x86/hvm/hvm.h     Sun May 30 19:10:21 2010 -0700
@@ -62,6 +62,14 @@ enum hvm_intblk {
 #define HVM_INTR_SHADOW_NMI    0x00000008
 
 /*
+ * HAP super page capabilities:
+ * bit0: if 2MB super page is allowed?
+ * bit1: if 1GB super page is allowed?
+ */
+#define HVM_HAP_SUPERPAGE_2MB   0x00000001
+#define HVM_HAP_SUPERPAGE_1GB   0x00000002
+
+/*
  * The hardware virtual machine (HVM) interface abstracts away from the
  * x86/x86_64 CPU virtualization assist specifics. Currently this interface
  * supports Intel's VT-x and AMD's SVM extensions.
@@ -72,11 +80,8 @@ struct hvm_function_table {
     /* Support Hardware-Assisted Paging? */
     int hap_supported;
 
-    /*
-     * Indicate HAP super page level.
-     * 0 -- 4KB, 1 -- 2MB, 2 -- 1GB.
-     */
-    int hap_superpage_level;
+    /* Indicate HAP capabilities. */
+    int hap_capabilities;
 
 
     /*
@@ -175,6 +180,11 @@ int hvm_girq_dest_2_vcpu_id(struct domai
     (hvm_paging_enabled(v) && ((v)->arch.hvm_vcpu.guest_cr[4] & X86_CR4_PAE))
 #define hvm_nx_enabled(v) \
     (!!((v)->arch.hvm_vcpu.guest_efer & EFER_NX))
+
+#define hvm_hap_has_1gb(d) \
+    (hvm_funcs.hap_capabilities & HVM_HAP_SUPERPAGE_1GB)
+#define hvm_hap_has_2mb(d) \
+    (hvm_funcs.hap_capabilities & HVM_HAP_SUPERPAGE_2MB)
 
 #ifdef __x86_64__
 #define hvm_long_mode_enabled(v) \
diff -r 96917cf25bf3 xen/include/asm-x86/hvm/vmx/vmcs.h
--- a/xen/include/asm-x86/hvm/vmx/vmcs.h        Fri May 28 10:54:07 2010 +0100
+++ b/xen/include/asm-x86/hvm/vmx/vmcs.h        Sun May 30 19:10:21 2010 -0700
@@ -174,10 +174,10 @@ extern u32 vmx_secondary_exec_control;
 
 extern bool_t cpu_has_vmx_ins_outs_instr_info;
 
-extern u8 vmx_ept_super_page_level_limit;
+extern u64 vmx_ept_vpid_cap;
 
-#define VMX_EPT_SUPER_PAGE_2M              0x00010000
-#define VMX_EPT_SUPER_PAGE_1G              0x00020000
+#define VMX_EPT_SUPERPAGE_2MB                   0x00010000
+#define VMX_EPT_SUPERPAGE_1GB                   0x00020000
 
 #define cpu_has_wbinvd_exiting \
     (vmx_secondary_exec_control & SECONDARY_EXEC_WBINVD_EXITING)
@@ -193,6 +193,10 @@ extern u8 vmx_ept_super_page_level_limit
     (vmx_cpu_based_exec_control & CPU_BASED_ACTIVATE_SECONDARY_CONTROLS)
 #define cpu_has_vmx_ept \
     (vmx_secondary_exec_control & SECONDARY_EXEC_ENABLE_EPT)
+#define cpu_has_vmx_ept_1gb \
+    (vmx_ept_vpid_cap & VMX_EPT_SUPERPAGE_1GB)
+#define cpu_has_vmx_ept_2mb \
+    (vmx_ept_vpid_cap & VMX_EPT_SUPERPAGE_2MB)
 #define cpu_has_vmx_vpid \
     (vmx_secondary_exec_control & SECONDARY_EXEC_ENABLE_VPID)
 #define cpu_has_monitor_trap_flag \
@@ -206,8 +210,6 @@ extern u8 vmx_ept_super_page_level_limit
      SECONDARY_EXEC_UNRESTRICTED_GUEST)
 #define cpu_has_vmx_ple \
     (vmx_secondary_exec_control & SECONDARY_EXEC_PAUSE_LOOP_EXITING)
-#define cpu_vmx_ept_super_page_level_limit  \
-    vmx_ept_super_page_level_limit
 
 /* GUEST_INTERRUPTIBILITY_INFO flags. */
 #define VMX_INTR_SHADOW_STI             0x00000001

Attachment: ept_2m_1g_detection.patch
Description: ept_2m_1g_detection.patch

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-devel] [PATCH] does EPT capabilities detection strictly according to Intel SDM, Li, Xin <=