KVM: VMX: EPT Feature Detection
PATCH 1/6 KVM: VMX: EPT Feature Detection
From 9e723871299268e844c9e72f3903ba5f4eb71751 Mon Sep 17 00:00:00 2001
From: Sheng Yang <[email protected]>
Date: Fri, 18 Apr 2008 17:02:59 +0800
Subject: [PATCH 1/5] KVM: VMX: EPT Feature Detection
--- arch/x86/kvm/vmx.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++---- arch/x86/kvm/vmx.h | 25 ++++++++++++++++++++ 2 files changed, 83 insertions(+), 5 deletions(-)
arch/x86/kvm/vmx.c +8 -0
@@ -42,6 +42,9 @@ module_param(enable_vpid, bool, 0);static int flexpriority_enabled =1 ;module_param (flexpriority_enabled, bool,0 ); +static int enable_ept; +module_param (enable_ept, bool,0 ); +struct vmcs {u32 revision_id;u32 abort;
@@ -107,6 +110,11 @@ static struct vmcs_config {u32 vmentry_ctrl; } vmcs_config; +struct vmx_capability { +u32 ept; +u32 vpid; +} vmx_capability; +#define VMX_SEGMENT_FIELD (seg) \ [VCPU_SREG_##seg] = { \ .selector = GUEST_##seg##_SELECTOR, \
@@ -214,6 +222,32 @@ static inline bool
cpu_has_vmx_virtualize_apic_accesses(void)
SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES);
}
+static inline int cpu_has_vmx_invept_individual_addr(void)
+{
+ return (!!(vmx_capability.ept & VMX_EPT_EXTENT_INDIVIDUAL_BIT));
+}
+
+static inline int cpu_has_vmx_invept_context(void)
+{
+ return (!!(vmx_capability.ept & VMX_EPT_EXTENT_CONTEXT_BIT));
+}
+
+static inline int cpu_has_vmx_invept_global(void)
+{
+ return (!!(vmx_capability.ept & VMX_EPT_EXTENT_GLOBAL_BIT));
+}
+
+static inline int cpu_has_vmx_ept(void)
+{
+ return (vmcs_config.cpu_based_2nd_exec_ctrl &
+ SECONDARY_EXEC_ENABLE_EPT);
+}
+
+static inline int vm_need_ept(void)
+{
+ return (cpu_has_vmx_ept() && enable_ept);
+}
+
static inline int vm_need_virtualize_apic_accesses(struct kvm *kvm) {
return ((cpu_has_vmx_virtualize_apic_accesses()) &&
@@ -985,7 +1019,7 @@ static __init int adjust_vmx_controls(u32 ctl_min, u32 ctl_opt,
static __init int setup_vmcs_config(struct vmcs_config *vmcs_conf) {
u32 vmx_msr_low, vmx_msr_high;
- u32 min, opt;
+ u32 min, opt, min2, opt2;
u32 _pin_based_exec_control = 0;
u32 _cpu_based_exec_control = 0;
u32 _cpu_based_2nd_exec_control = 0;
@@ -1003,6 +1037,8 @@ static __init int setup_vmcs_config(struct vmcs_config *vmcs_conf)
CPU_BASED_CR8_LOAD_EXITING | CPU_BASED_CR8_STORE_EXITING |
#endif
+ CPU_BASED_CR3_LOAD_EXITING |
+ CPU_BASED_CR3_STORE_EXITING |
CPU_BASED_USE_IO_BITMAPS |
CPU_BASED_MOV_DR_EXITING | CPU_BASED_USE_TSC_OFFSETING;
@@ -1018,11 +1054,13 @@ static __init int setup_vmcs_config(struct vmcs_config *vmcs_conf)
~CPU_BASED_CR8_STORE_EXITING;
#endif
if (_cpu_based_exec_control & CPU_BASED_ACTIVATE_SECONDARY_CONTROLS) {
- min = 0;
- opt = SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES |
+ min2 = 0;
+ opt2 = SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES |
SECONDARY_EXEC_WBINVD_EXITING |
- SECONDARY_EXEC_ENABLE_VPID;
- if (adjust_vmx_controls(min, opt, MSR_IA32_VMX_PROCBASED_CTLS2,
+ SECONDARY_EXEC_ENABLE_VPID |
+ SECONDARY_EXEC_ENABLE_EPT;
+ if (adjust_vmx_controls(min2, opt2,
+ MSR_IA32_VMX_PROCBASED_CTLS2,
&_cpu_based_2nd_exec_control) < 0)
return -EIO;
}
@@ -1031,6 +1069,16 @@ static __init int setup_vmcs_config(struct vmcs_config *vmcs_conf)
SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES))
_cpu_based_exec_control &= ~CPU_BASED_TPR_SHADOW;
#endif
+ if (_cpu_based_2nd_exec_control & SECONDARY_EXEC_ENABLE_EPT) {
+ /* CR3 accesses don't need to cause VM Exits when EPT enabled */
+ min &= ~(CPU_BASED_CR3_LOAD_EXITING |
+ CPU_BASED_CR3_STORE_EXITING);
+ if (adjust_vmx_controls(min, opt, MSR_IA32_VMX_PROCBASED_CTLS,
+ &_cpu_based_exec_control) < 0)
+ return -EIO;
+ rdmsr(MSR_IA32_VMX_EPT_VPID_CAP,
+ vmx_capability.ept, vmx_capability.vpid);
+ }
min = 0;
#ifdef CONFIG_X86_64
@@ -1638,6 +1686,9 @@ static int vmx_vcpu_setup(struct vcpu_vmx *vmx)
CPU_BASED_CR8_LOAD_EXITING;
#endif
}
+ if (!vm_need_ept())
+ exec_control |= CPU_BASED_CR3_STORE_EXITING |
+ CPU_BASED_CR3_LOAD_EXITING;
vmcs_write32(CPU_BASED_VM_EXEC_CONTROL, exec_control);
if (cpu_has_secondary_exec_ctrls()) {
@@ -1647,6 +1698,8 @@ static int vmx_vcpu_setup(struct vcpu_vmx *vmx)
~SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES;
if (vmx->vpid == 0)
exec_control &= ~SECONDARY_EXEC_ENABLE_VPID;
+ if (!vm_need_ept())
+ exec_control &= ~SECONDARY_EXEC_ENABLE_EPT;
vmcs_write32(SECONDARY_VM_EXEC_CONTROL, exec_control);
}
arch/x86/kvm/vmx.h +25 -0
@@ -35,6 +35,8 @@#define CPU_BASED_MWAIT_EXITING 0x00000400#define CPU_BASED_RDPMC_EXITING 0x00000800#define CPU_BASED_RDTSC_EXITING 0x00001000 +#define CPU_BASED_CR3_LOAD_EXITING 0x00008000 +#define CPU_BASED_CR3_STORE_EXITING 0x00010000#define CPU_BASED_CR8_LOAD_EXITING 0x00080000#define CPU_BASED_CR8_STORE_EXITING 0x00100000#define CPU_BASED_TPR_SHADOW 0x00200000
@@ -49,6 +51,7 @@* Definitions of Secondary Processor-Based VM-Execution Controls. */ #define SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES 0x00000001 +#define SECONDARY_EXEC_ENABLE_EPT 0x00000002#define SECONDARY_EXEC_ENABLE_VPID 0x00000020#define SECONDARY_EXEC_WBINVD_EXITING 0x00000040
@@ -100,10 +103,22 @@ enum vmcs_field {VIRTUAL_APIC_PAGE_ADDR_HIGH =0x00002013 ,APIC_ACCESS_ADDR =0x00002014 ,APIC_ACCESS_ADDR_HIGH =0x00002015 , +EPT_POINTER =0x0000201a , +EPT_POINTER_HIGH =0x0000201b , +GUEST_PHYSICAL_ADDRESS =0x00002400 , +GUEST_PHYSICAL_ADDRESS_HIGH =0x00002401 ,VMCS_LINK_POINTER =0x00002800 ,VMCS_LINK_POINTER_HIGH =0x00002801 ,GUEST_IA32_DEBUGCTL =0x00002802 ,GUEST_IA32_DEBUGCTL_HIGH =0x00002803 , +GUEST_PDPTR0 =0x0000280a , +GUEST_PDPTR0_HIGH =0x0000280b , +GUEST_PDPTR1 =0x0000280c , +GUEST_PDPTR1_HIGH =0x0000280d , +GUEST_PDPTR2 =0x0000280e , +GUEST_PDPTR2_HIGH =0x0000280f , +GUEST_PDPTR3 =0x00002810 , +GUEST_PDPTR3_HIGH =0x00002811 ,PIN_BASED_VM_EXEC_CONTROL =0x00004000 ,CPU_BASED_VM_EXEC_CONTROL =0x00004002 , EXCEPTION_BITMAP = 0x00004004,
@@ -226,6 +241,8 @@ enum vmcs_field {#define EXIT_REASON_MWAIT_INSTRUCTION 36#define EXIT_REASON_TPR_BELOW_THRESHOLD 43#define EXIT_REASON_APIC_ACCESS 44 +#define EXIT_REASON_EPT_VIOLATION 48 +#define EXIT_REASON_EPT_MISCONFIG 49#define EXIT_REASON_WBINVD 54/*
@@ -316,6 +333,7 @@ enum vmcs_field {#define MSR_IA32_VMX_CR4_FIXED1 0x489#define MSR_IA32_VMX_VMCS_ENUM 0x48a#define MSR_IA32_VMX_PROCBASED_CTLS2 0x48b +#define MSR_IA32_VMX_EPT_VPID_CAP 0x48c#define MSR_IA32_FEATURE_CONTROL 0x3a#define MSR_IA32_FEATURE_CONTROL_LOCKED 0x1
@@ -327,4 +345,11 @@ enum vmcs_field {#define VMX_VPID_EXTENT_SINGLE_CONTEXT 1#define VMX_VPID_EXTENT_ALL_CONTEXT 2 +#define VMX_EPT_EXTENT_INDIVIDUAL_ADDR 0 +#define VMX_EPT_EXTENT_CONTEXT 1 +#define VMX_EPT_EXTENT_GLOBAL 2 +#define VMX_EPT_EXTENT_INDIVIDUAL_BIT (1ul << 24) +#define VMX_EPT_EXTENT_CONTEXT_BIT (1ul << 25) +#define VMX_EPT_EXTENT_GLOBAL_BIT (1ul << 26) +#endif
--
1.5.4.5
From 9e723871299268e844c9e72f3903ba5f4eb71751 Mon Sep 17 00:00:00 2001
From: Sheng Yang <[email protected]>
Date: Fri, 18 Apr 2008 17:02:59 +0800
Subject: [PATCH 1/5] KVM: VMX: EPT Feature Detection
--- arch/x86/kvm/vmx.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++---- arch/x86/kvm/vmx.h | 25 ++++++++++++++++++++ 2 files changed, 83 insertions(+), 5 deletions(-)
arch/x86/kvm/vmx.c +58 -5
118 lines not on this page · raw message
arch/x86/kvm/vmx.h +25 -0
@@ -35,6 +35,8 @@#define CPU_BASED_MWAIT_EXITING 0x00000400#define CPU_BASED_RDPMC_EXITING 0x00000800#define CPU_BASED_RDTSC_EXITING 0x00001000 +#define CPU_BASED_CR3_LOAD_EXITING 0x00008000 +#define CPU_BASED_CR3_STORE_EXITING 0x00010000#define CPU_BASED_CR8_LOAD_EXITING 0x00080000#define CPU_BASED_CR8_STORE_EXITING 0x00100000#define CPU_BASED_TPR_SHADOW 0x00200000
@@ -49,6 +51,7 @@* Definitions of Secondary Processor-Based VM-Execution Controls. */ #define SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES 0x00000001 +#define SECONDARY_EXEC_ENABLE_EPT 0x00000002#define SECONDARY_EXEC_ENABLE_VPID 0x00000020#define SECONDARY_EXEC_WBINVD_EXITING 0x00000040
@@ -100,10 +103,22 @@ enum vmcs_field {VIRTUAL_APIC_PAGE_ADDR_HIGH =0x00002013 ,APIC_ACCESS_ADDR =0x00002014 ,APIC_ACCESS_ADDR_HIGH =0x00002015 , +EPT_POINTER =0x0000201a , +EPT_POINTER_HIGH =0x0000201b , +GUEST_PHYSICAL_ADDRESS =0x00002400 , +GUEST_PHYSICAL_ADDRESS_HIGH =0x00002401 ,VMCS_LINK_POINTER =0x00002800 ,VMCS_LINK_POINTER_HIGH =0x00002801 ,GUEST_IA32_DEBUGCTL =0x00002802 ,GUEST_IA32_DEBUGCTL_HIGH =0x00002803 , +GUEST_PDPTR0 =0x0000280a , +GUEST_PDPTR0_HIGH =0x0000280b , +GUEST_PDPTR1 =0x0000280c , +GUEST_PDPTR1_HIGH =0x0000280d , +GUEST_PDPTR2 =0x0000280e , +GUEST_PDPTR2_HIGH =0x0000280f , +GUEST_PDPTR3 =0x00002810 , +GUEST_PDPTR3_HIGH =0x00002811 ,PIN_BASED_VM_EXEC_CONTROL =0x00004000 ,CPU_BASED_VM_EXEC_CONTROL =0x00004002 , EXCEPTION_BITMAP = 0x00004004,
@@ -226,6 +241,8 @@ enum vmcs_field {#define EXIT_REASON_MWAIT_INSTRUCTION 36#define EXIT_REASON_TPR_BELOW_THRESHOLD 43#define EXIT_REASON_APIC_ACCESS 44 +#define EXIT_REASON_EPT_VIOLATION 48 +#define EXIT_REASON_EPT_MISCONFIG 49#define EXIT_REASON_WBINVD 54/*
@@ -316,6 +333,7 @@ enum vmcs_field {#define MSR_IA32_VMX_CR4_FIXED1 0x489#define MSR_IA32_VMX_VMCS_ENUM 0x48a#define MSR_IA32_VMX_PROCBASED_CTLS2 0x48b +#define MSR_IA32_VMX_EPT_VPID_CAP 0x48c#define MSR_IA32_FEATURE_CONTROL 0x3a#define MSR_IA32_FEATURE_CONTROL_LOCKED 0x1
@@ -327,4 +345,11 @@ enum vmcs_field {#define VMX_VPID_EXTENT_SINGLE_CONTEXT 1#define VMX_VPID_EXTENT_ALL_CONTEXT 2 +#define VMX_EPT_EXTENT_INDIVIDUAL_ADDR 0 +#define VMX_EPT_EXTENT_CONTEXT 1 +#define VMX_EPT_EXTENT_GLOBAL 2 +#define VMX_EPT_EXTENT_INDIVIDUAL_BIT (1ul << 24) +#define VMX_EPT_EXTENT_CONTEXT_BIT (1ul << 25) +#define VMX_EPT_EXTENT_GLOBAL_BIT (1ul << 26) +#endif
Signature · 1 line
1.5.4.5
-------------------------------------------------------------------------
This SF.net email is sponsored by the 2008 JavaOne(SM) Conference Don't miss this year's exciting event. There's still time to save $100. Use priority code J8TL2D2.
http://ad.doubleclick.net/clk;198757673;13503038;p?http://java.sun.com/javaone
_______________________________________________
kvm-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/kvm-devel