aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kvm/vmx.c
diff options
context:
space:
mode:
authorAbel Gordon <abelg@il.ibm.com>2013-04-18 07:35:25 -0400
committerGleb Natapov <gleb@redhat.com>2013-04-22 03:51:21 -0400
commitabc4fc58c5ba1a794092bcd97fdb1680b0b3398d (patch)
tree9b9558bae034adc6a419c1f52fe5c44f27d769cf /arch/x86/kvm/vmx.c
parent89662e566c73230dab9f1d99dbe2f6d9c8c189a8 (diff)
KVM: nVMX: Detect shadow-vmcs capability
Add logic required to detect if shadow-vmcs is supported by the processor. Introduce a new kernel module parameter to specify if L0 should use shadow vmcs (or not) to run L1. Signed-off-by: Abel Gordon <abelg@il.ibm.com> Reviewed-by: Orit Wasserman <owasserm@redhat.com> Signed-off-by: Gleb Natapov <gleb@redhat.com>
Diffstat (limited to 'arch/x86/kvm/vmx.c')
-rw-r--r--arch/x86/kvm/vmx.c25
1 files changed, 24 insertions, 1 deletions
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index a05cca608848..7042b6921961 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -87,6 +87,8 @@ module_param(fasteoi, bool, S_IRUGO);
87static bool __read_mostly enable_apicv = 1; 87static bool __read_mostly enable_apicv = 1;
88module_param(enable_apicv, bool, S_IRUGO); 88module_param(enable_apicv, bool, S_IRUGO);
89 89
90static bool __read_mostly enable_shadow_vmcs = 1;
91module_param_named(enable_shadow_vmcs, enable_shadow_vmcs, bool, S_IRUGO);
90/* 92/*
91 * If nested=1, nested virtualization is supported, i.e., guests may use 93 * If nested=1, nested virtualization is supported, i.e., guests may use
92 * VMX and be a hypervisor for its own guests. If nested=0, guests may not 94 * VMX and be a hypervisor for its own guests. If nested=0, guests may not
@@ -940,6 +942,18 @@ static inline bool cpu_has_vmx_wbinvd_exit(void)
940 SECONDARY_EXEC_WBINVD_EXITING; 942 SECONDARY_EXEC_WBINVD_EXITING;
941} 943}
942 944
945static inline bool cpu_has_vmx_shadow_vmcs(void)
946{
947 u64 vmx_msr;
948 rdmsrl(MSR_IA32_VMX_MISC, vmx_msr);
949 /* check if the cpu supports writing r/o exit information fields */
950 if (!(vmx_msr & MSR_IA32_VMX_MISC_VMWRITE_SHADOW_RO_FIELDS))
951 return false;
952
953 return vmcs_config.cpu_based_2nd_exec_ctrl &
954 SECONDARY_EXEC_SHADOW_VMCS;
955}
956
943static inline bool report_flexpriority(void) 957static inline bool report_flexpriority(void)
944{ 958{
945 return flexpriority_enabled; 959 return flexpriority_enabled;
@@ -2632,7 +2646,8 @@ static __init int setup_vmcs_config(struct vmcs_config *vmcs_conf)
2632 SECONDARY_EXEC_RDTSCP | 2646 SECONDARY_EXEC_RDTSCP |
2633 SECONDARY_EXEC_ENABLE_INVPCID | 2647 SECONDARY_EXEC_ENABLE_INVPCID |
2634 SECONDARY_EXEC_APIC_REGISTER_VIRT | 2648 SECONDARY_EXEC_APIC_REGISTER_VIRT |
2635 SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY; 2649 SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY |
2650 SECONDARY_EXEC_SHADOW_VMCS;
2636 if (adjust_vmx_controls(min2, opt2, 2651 if (adjust_vmx_controls(min2, opt2,
2637 MSR_IA32_VMX_PROCBASED_CTLS2, 2652 MSR_IA32_VMX_PROCBASED_CTLS2,
2638 &_cpu_based_2nd_exec_control) < 0) 2653 &_cpu_based_2nd_exec_control) < 0)
@@ -2833,6 +2848,8 @@ static __init int hardware_setup(void)
2833 2848
2834 if (!cpu_has_vmx_vpid()) 2849 if (!cpu_has_vmx_vpid())
2835 enable_vpid = 0; 2850 enable_vpid = 0;
2851 if (!cpu_has_vmx_shadow_vmcs())
2852 enable_shadow_vmcs = 0;
2836 2853
2837 if (!cpu_has_vmx_ept() || 2854 if (!cpu_has_vmx_ept() ||
2838 !cpu_has_vmx_ept_4levels()) { 2855 !cpu_has_vmx_ept_4levels()) {
@@ -4077,6 +4094,12 @@ static u32 vmx_secondary_exec_control(struct vcpu_vmx *vmx)
4077 exec_control &= ~(SECONDARY_EXEC_APIC_REGISTER_VIRT | 4094 exec_control &= ~(SECONDARY_EXEC_APIC_REGISTER_VIRT |
4078 SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY); 4095 SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY);
4079 exec_control &= ~SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE; 4096 exec_control &= ~SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE;
4097 /* SECONDARY_EXEC_SHADOW_VMCS is enabled when L1 executes VMPTRLD
4098 (handle_vmptrld).
4099 We can NOT enable shadow_vmcs here because we don't have yet
4100 a current VMCS12
4101 */
4102 exec_control &= ~SECONDARY_EXEC_SHADOW_VMCS;
4080 return exec_control; 4103 return exec_control;
4081} 4104}
4082 4105