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] enforce EPT paging structure memory type and page-wa

To: "xen-devel@xxxxxxxxxxxxxxxxxxx" <xen-devel@xxxxxxxxxxxxxxxxxxx>
Subject: [Xen-devel] [PATCH] enforce EPT paging structure memory type and page-walk length check
From: "Li, Xin" <xin.li@xxxxxxxxx>
Date: Thu, 10 Jun 2010 16:09:59 +0800
Accept-language: zh-CN, en-US
Acceptlanguage: zh-CN, en-US
Delivery-date: Thu, 10 Jun 2010 01:11:52 -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: AcsIdFHaAaqWlHaSQraOgKSjvMq7Pg==
Thread-topic: [PATCH] enforce EPT paging structure memory type and page-walk length check
VMX: enforce EPT paging structure memory type and page-walk length check.

Also use a micro to get EPT walk length.

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

diff -r b522d6148f44 xen/arch/x86/hvm/vmx/vmcs.c
--- a/xen/arch/x86/hvm/vmx/vmcs.c       Thu Jun 10 08:31:36 2010 +0100
+++ b/xen/arch/x86/hvm/vmx/vmcs.c       Wed Jun 09 19:37:38 2010 -0700
@@ -192,6 +192,26 @@ static int vmx_init_vmcs_config(void)
             MSR_IA32_VMX_PROCBASED_CTLS2, &mismatch);
     }
 
+    /* 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);
+
+        /*
+         * Additional sanity checking before using EPT:
+         * 1) the CPU we are running on must support EPT WB, as we will set
+         *    ept paging structures memory type to WB;
+         * 2) the CPU must support the EPT page-walk length of 4 according to
+         *    Intel SDM 25.2.2.
+         *
+         * Or we just don't use EPT.
+         */
+        if ( !(_vmx_ept_vpid_cap & VMX_EPT_MEMORY_TYPE_WB) ||
+             !(_vmx_ept_vpid_cap & VMX_EPT_WALK_LENGTH_4_SUPPORTED) )
+            _vmx_secondary_exec_control &= ~SECONDARY_EXEC_ENABLE_EPT;
+    }
+
     if ( _vmx_secondary_exec_control & SECONDARY_EXEC_ENABLE_EPT )
     {
         /*
@@ -209,11 +229,6 @@ static int vmx_init_vmcs_config(void)
                 ~(SECONDARY_EXEC_ENABLE_EPT |
                   SECONDARY_EXEC_UNRESTRICTED_GUEST);
     }
-
-    /* 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 )
diff -r b522d6148f44 xen/arch/x86/hvm/vmx/vmx.c
--- a/xen/arch/x86/hvm/vmx/vmx.c        Thu Jun 10 08:31:36 2010 +0100
+++ b/xen/arch/x86/hvm/vmx/vmx.c        Wed Jun 09 19:37:39 2010 -0700
@@ -78,11 +78,14 @@ static int vmx_domain_initialise(struct 
 {
     int rc;
 
-    d->arch.hvm_domain.vmx.ept_control.etmt = EPT_DEFAULT_MT;
-    d->arch.hvm_domain.vmx.ept_control.gaw  = EPT_DEFAULT_GAW;
+    /* Set the memory type used when accessing EPT paging structures. */
+    d->arch.hvm_domain.vmx.ept_control.ept_mt = EPT_DEFAULT_MT;
+
+    /* set EPT page-walk length, now it's actual walk length - 1, i.e. 3 */
+    d->arch.hvm_domain.vmx.ept_control.ept_wl = 3;
+
     d->arch.hvm_domain.vmx.ept_control.asr  =
         pagetable_get_pfn(p2m_get_pagetable(p2m_get_hostp2m(d)));
-
 
     if ( (rc = vmx_alloc_vlapic_mapping(d)) != 0 )
         return rc;
diff -r b522d6148f44 xen/arch/x86/mm/hap/p2m-ept.c
--- a/xen/arch/x86/mm/hap/p2m-ept.c     Thu Jun 10 08:31:36 2010 +0100
+++ b/xen/arch/x86/mm/hap/p2m-ept.c     Wed Jun 09 19:37:39 2010 -0700
@@ -253,7 +253,7 @@ ept_set_entry(struct domain *d, unsigned
 
     ASSERT(table != NULL);
 
-    for ( i = EPT_DEFAULT_GAW; i > walk_level; i-- )
+    for ( i = ept_get_wl(d); i > walk_level; i-- )
     {
         ret = ept_next_level(d, 0, &table, &gfn_remainder, i * 
EPT_TABLE_ORDER);
         if ( !ret )
@@ -402,7 +402,7 @@ static mfn_t ept_get_entry(struct domain
 
     /* Should check if gfn obeys GAW here. */
 
-    for ( i = EPT_DEFAULT_GAW; i > 0; i-- )
+    for ( i = ept_get_wl(d); i > 0; i-- )
     {
     retry:
         ret = ept_next_level(d, 1, &table, &gfn_remainder,
@@ -492,7 +492,7 @@ static ept_entry_t ept_get_entry_content
     if ( gfn > d->arch.p2m->max_mapped_pfn )
         goto out;
 
-    for ( i = EPT_DEFAULT_GAW; i > 0; i-- )
+    for ( i = ept_get_wl(d); i > 0; i-- )
     {
         ret = ept_next_level(d, 1, &table, &gfn_remainder,
                              i * EPT_TABLE_ORDER);
@@ -531,7 +531,7 @@ void ept_walk_table(struct domain *d, un
         goto out;
     }
 
-    for ( i = EPT_DEFAULT_GAW; i >= 0; i-- )
+    for ( i = ept_get_wl(d); i >= 0; i-- )
     {
         ept_entry_t *ept_entry, *next;
         u32 index;
@@ -658,8 +658,6 @@ static void ept_change_entry_type_global
     if ( pagetable_get_pfn(p2m_get_pagetable(p2m_get_hostp2m(d))) == 0 )
         return;
 
-    BUG_ON(EPT_DEFAULT_GAW != 3);
-
     l4e = 
map_domain_page(mfn_x(pagetable_get_mfn(p2m_get_pagetable(p2m_get_hostp2m(d)))));
     for (i4 = 0; i4 < EPT_PAGETABLE_ENTRIES; i4++ )
     {
@@ -751,7 +749,7 @@ static void ept_dump_p2m_table(unsigned 
     int order;
     int i;
     int is_pod;
-    int ret;
+    int ret = 0;
     unsigned long index;
     unsigned long gfn, gfn_remainder;
     unsigned long record_counter = 0;
@@ -772,7 +770,7 @@ static void ept_dump_p2m_table(unsigned 
             table =
                 
map_domain_page(mfn_x(pagetable_get_mfn(p2m_get_pagetable(p2m))));
 
-            for ( i = EPT_DEFAULT_GAW; i > 0; i-- )
+            for ( i = ept_get_wl(d); i > 0; i-- )
             {
                 ret = ept_next_level(d, 1, &table, &gfn_remainder,
                                      i * EPT_TABLE_ORDER);
diff -r b522d6148f44 xen/include/asm-x86/hvm/vmx/vmcs.h
--- a/xen/include/asm-x86/hvm/vmx/vmcs.h        Thu Jun 10 08:31:36 2010 +0100
+++ b/xen/include/asm-x86/hvm/vmx/vmcs.h        Wed Jun 09 19:37:39 2010 -0700
@@ -55,22 +55,24 @@ struct vmx_msr_state {
     unsigned long msrs[VMX_MSR_COUNT];
 };
 
-#define EPT_DEFAULT_MT      6
-#define EPT_DEFAULT_GAW     3
+#define EPT_DEFAULT_MT      MTRR_TYPE_WRBACK
 
 struct vmx_domain {
     unsigned long apic_access_mfn;
     union {
         struct {
-            u64 etmt :3,
-                gaw  :3,
-                rsvd :6,
-                asr  :52;
+            u64 ept_mt :3,
+                ept_wl :3,
+                rsvd   :6,
+                asr    :52;
         };
         u64 eptp;
     } ept_control;
     cpumask_t ept_synced;
 };
+
+#define ept_get_wl(d)  \
+    ((d)->arch.hvm_domain.vmx.ept_control.ept_wl)
 
 struct arch_vmx_struct {
     /* Virtual address of VMCS. */
@@ -174,8 +176,9 @@ extern u32 vmx_secondary_exec_control;
 
 extern bool_t cpu_has_vmx_ins_outs_instr_info;
 
-extern u64 vmx_ept_vpid_cap;
-
+#define VMX_EPT_WALK_LENGTH_4_SUPPORTED         0x00000040
+#define VMX_EPT_MEMORY_TYPE_UC                  0x00000100
+#define VMX_EPT_MEMORY_TYPE_WB                  0x00004000
 #define VMX_EPT_SUPERPAGE_2MB                   0x00010000
 #define VMX_EPT_SUPERPAGE_1GB                   0x00020000
 
@@ -193,10 +196,6 @@ extern u64 vmx_ept_vpid_cap;
     (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 \
diff -r b522d6148f44 xen/include/asm-x86/hvm/vmx/vmx.h
--- a/xen/include/asm-x86/hvm/vmx/vmx.h Thu Jun 10 08:31:36 2010 +0100
+++ b/xen/include/asm-x86/hvm/vmx/vmx.h Wed Jun 09 19:37:39 2010 -0700
@@ -183,6 +183,20 @@ void vmx_update_debug_state(struct vcpu 
 #define MODRM_EAX_06    ".byte 0x30\n" /* [EAX], with reg/opcode: /6 */
 #define MODRM_EAX_07    ".byte 0x38\n" /* [EAX], with reg/opcode: /7 */
 #define MODRM_EAX_ECX   ".byte 0xc1\n" /* EAX, ECX */
+
+extern u64 vmx_ept_vpid_cap;
+
+#define cpu_has_vmx_ept_wl4_supported           \
+    (vmx_ept_vpid_cap & VMX_EPT_WALK_LENGTH_4_SUPPORTED)
+#define cpu_has_vmx_ept_mt_uc                   \
+    (vmx_ept_vpid_cap & VMX_EPT_MEMORY_TYPE_UC)
+#define cpu_has_vmx_ept_mt_wb                   \
+    (vmx_ept_vpid_cap & VMX_EPT_MEMORY_TYPE_WB)
+#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)
+
 
 static inline void __vmptrld(u64 addr)
 {

Attachment: ept_mt_wl_check.patch
Description: ept_mt_wl_check.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] enforce EPT paging structure memory type and page-walk length check, Li, Xin <=