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

[Xen-changelog] [xen-unstable] VMX: enforce INVVPID checking



# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1276245298 -3600
# Node ID a822156d9fbb706d25016bb3e067faac005254b4
# Parent  2e38205b0d736bea92c3909cff6b363809f89d91
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>
---
 xen/arch/x86/hvm/vmx/vmcs.c        |   11 +++++++++-
 xen/include/asm-x86/hvm/vmx/vmcs.h |    6 +++++
 xen/include/asm-x86/hvm/vmx/vmx.h  |   39 +++++++++++++++++++++++++++++++++----
 3 files changed, 51 insertions(+), 5 deletions(-)

diff -r 2e38205b0d73 -r a822156d9fbb xen/arch/x86/hvm/vmx/vmcs.c
--- a/xen/arch/x86/hvm/vmx/vmcs.c       Fri Jun 11 09:31:14 2010 +0100
+++ b/xen/arch/x86/hvm/vmx/vmcs.c       Fri Jun 11 09:34:58 2010 +0100
@@ -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 2e38205b0d73 -r a822156d9fbb xen/include/asm-x86/hvm/vmx/vmcs.h
--- a/xen/include/asm-x86/hvm/vmx/vmcs.h        Fri Jun 11 09:31:14 2010 +0100
+++ b/xen/include/asm-x86/hvm/vmx/vmcs.h        Fri Jun 11 09:34:58 2010 +0100
@@ -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 2e38205b0d73 -r a822156d9fbb xen/include/asm-x86/hvm/vmx/vmx.h
--- a/xen/include/asm-x86/hvm/vmx/vmx.h Fri Jun 11 09:31:14 2010 +0100
+++ b/xen/include/asm-x86/hvm/vmx/vmx.h Fri Jun 11 09:34:58 2010 +0100
@@ -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)

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

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