diff options
author | Abel Gordon <abelg@il.ibm.com> | 2013-04-18 07:35:25 -0400 |
---|---|---|
committer | Gleb Natapov <gleb@redhat.com> | 2013-04-22 03:51:21 -0400 |
commit | abc4fc58c5ba1a794092bcd97fdb1680b0b3398d (patch) | |
tree | 9b9558bae034adc6a419c1f52fe5c44f27d769cf /arch/x86/kvm/vmx.c | |
parent | 89662e566c73230dab9f1d99dbe2f6d9c8c189a8 (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.c | 25 |
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); | |||
87 | static bool __read_mostly enable_apicv = 1; | 87 | static bool __read_mostly enable_apicv = 1; |
88 | module_param(enable_apicv, bool, S_IRUGO); | 88 | module_param(enable_apicv, bool, S_IRUGO); |
89 | 89 | ||
90 | static bool __read_mostly enable_shadow_vmcs = 1; | ||
91 | module_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 | ||
945 | static 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 | |||
943 | static inline bool report_flexpriority(void) | 957 | static 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 | ||