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 INVVPID checking

To: "xen-devel@xxxxxxxxxxxxxxxxxxx" <xen-devel@xxxxxxxxxxxxxxxxxxx>
Subject: [Xen-devel] [PATCH] enforce INVVPID checking
From: "Li, Xin" <xin.li@xxxxxxxxx>
Date: Fri, 11 Jun 2010 06:49:57 +0800
Accept-language: zh-CN, en-US
Acceptlanguage: zh-CN, en-US
Delivery-date: Thu, 10 Jun 2010 15:50:38 -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: AcsI70AUeSfVej2/R52YybQBQBXBDA==
Thread-topic: [PATCH] enforce INVVPID checking
VMX: enforce INVVPID checking

Escalate to use a wider context invalidation if the requested context
invalidation is not supported.

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

diff -r 04e81a65d27e xen/arch/x86/hvm/vmx/vmcs.c
--- a/xen/arch/x86/hvm/vmx/vmcs.c       Thu Jun 10 22:39:52 2010 +0100
+++ b/xen/arch/x86/hvm/vmx/vmcs.c       Thu Jun 10 10:11:19 2010 -0700
@@ -213,6 +213,15 @@ static int vmx_init_vmcs_config(void)
              !(_vmx_ept_vpid_cap & VMX_EPT_WALK_LENGTH_4_SUPPORTED) ||
              !(_vmx_ept_vpid_cap & VMX_EPT_INVEPT_ALL_CONTEXT) )
             _vmx_secondary_exec_control &= ~SECONDARY_EXEC_ENABLE_EPT;
+
+        /*
+         * the CPU must support INVVPID all context invalidation, because we
+         * will use it as final resort if other types are not supported.
+         *
+         * Or we just don't use VPID.
+         */
+        if ( !(_vmx_ept_vpid_cap & VMX_VPID_INVVPID_ALL_CONTEXT) )
+            _vmx_secondary_exec_control &= ~SECONDARY_EXEC_ENABLE_VPID;
     }
 
     if ( _vmx_secondary_exec_control & SECONDARY_EXEC_ENABLE_EPT )
@@ -298,7 +307,7 @@ static int vmx_init_vmcs_config(void)
             "VMEntry Control",
             vmx_vmentry_control, _vmx_vmentry_control);
         mismatch |= cap_check(
-            "EPT Super Page Capability",
+            "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)) )
diff -r 04e81a65d27e xen/include/asm-x86/hvm/vmx/vmcs.h
--- a/xen/include/asm-x86/hvm/vmx/vmcs.h        Thu Jun 10 22:39:52 2010 +0100
+++ b/xen/include/asm-x86/hvm/vmx/vmcs.h        Thu Jun 10 10:11:19 2010 -0700
@@ -188,6 +188,12 @@ extern bool_t cpu_has_vmx_ins_outs_instr
 #define VMX_EPT_INVEPT_INSTRUCTION              0x00100000
 #define VMX_EPT_INVEPT_SINGLE_CONTEXT           0x02000000
 #define VMX_EPT_INVEPT_ALL_CONTEXT              0x04000000
+
+#define VMX_VPID_INVVPID_INSTRUCTION                        0x100000000ULL
+#define VMX_VPID_INVVPID_INDIVIDUAL_ADDR                    0x10000000000ULL
+#define VMX_VPID_INVVPID_SINGLE_CONTEXT                     0x20000000000ULL
+#define VMX_VPID_INVVPID_ALL_CONTEXT                        0x40000000000ULL
+#define VMX_VPID_INVVPID_SINGLE_CONTEXT_RETAINING_GLOBAL    0x80000000000ULL
 
 #define cpu_has_wbinvd_exiting \
     (vmx_secondary_exec_control & SECONDARY_EXEC_WBINVD_EXITING)
diff -r 04e81a65d27e xen/include/asm-x86/hvm/vmx/vmx.h
--- a/xen/include/asm-x86/hvm/vmx/vmx.h Thu Jun 10 22:39:52 2010 +0100
+++ b/xen/include/asm-x86/hvm/vmx/vmx.h Thu Jun 10 10:11:19 2010 -0700
@@ -202,6 +202,18 @@ extern u64 vmx_ept_vpid_cap;
 #define INVEPT_SINGLE_CONTEXT   1
 #define INVEPT_ALL_CONTEXT      2
 
+#define cpu_has_vmx_vpid_invvpid_individual_addr                    \
+    (vmx_ept_vpid_cap & VMX_VPID_INVVPID_INDIVIDUAL_ADDR)
+#define cpu_has_vmx_vpid_invvpid_single_context                     \
+    (vmx_ept_vpid_cap & VMX_VPID_INVVPID_SINGLE_CONTEXT)
+#define cpu_has_vmx_vpid_invvpid_single_context_retaining_global    \
+    (vmx_ept_vpid_cap & VMX_VPID_INVVPID_SINGLE_CONTEXT_RETAINING_GLOBAL)
+
+#define INVVPID_INDIVIDUAL_ADDR                 0
+#define INVVPID_SINGLE_CONTEXT                  1
+#define INVVPID_ALL_CONTEXT                     2
+#define INVVPID_SINGLE_CONTEXT_RETAINING_GLOBAL 3
+
 static inline void __vmptrld(u64 addr)
 {
     asm volatile ( VMPTRLD_OPCODE
@@ -307,7 +319,7 @@ static inline void __invept(int type, u6
                    : "memory" );
 }
 
-static inline void __invvpid(int ext, u16 vpid, u64 gva)
+static inline void __invvpid(int type, u16 vpid, u64 gva)
 {
     struct {
         u64 vpid:16;
@@ -324,7 +336,7 @@ static inline void __invvpid(int ext, u1
                    "    "__FIXUP_WORD" 1b,2b\n"
                    ".previous"
                    :
-                   : "a" (&operand), "c" (ext)
+                   : "a" (&operand), "c" (type)
                    : "memory" );
 }
 
@@ -337,12 +349,31 @@ void ept_sync_domain(struct domain *d);
 
 static inline void vpid_sync_vcpu_gva(struct vcpu *v, unsigned long gva)
 {
-    __invvpid(0, v->arch.hvm_vcpu.asid, (u64)gva);
+    int type = INVVPID_INDIVIDUAL_ADDR;
+
+    /*
+     * If individual address invalidation is not supported, we escalate to
+     * use single context invalidation.
+     */
+    if ( likely(cpu_has_vmx_vpid_invvpid_individual_addr) )
+        goto execute_invvpid;
+
+    type = INVVPID_SINGLE_CONTEXT;
+
+    /*
+     * If single context invalidation is not supported, we escalate to
+     * use all context invalidation.
+     */
+    if ( !cpu_has_vmx_vpid_invvpid_single_context )
+        type = INVVPID_ALL_CONTEXT;
+
+execute_invvpid:
+    __invvpid(type, v->arch.hvm_vcpu.asid, (u64)gva);
 }
 
 static inline void vpid_sync_all(void)
 {
-    __invvpid(2, 0, 0);
+    __invvpid(INVVPID_ALL_CONTEXT, 0, 0);
 }
 
 static inline void __vmxoff(void)

Attachment: enforce_invvpid_checking.patch
Description: enforce_invvpid_checking.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 INVVPID checking, Li, Xin <=