[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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |