@@ -1301,6 +1301,7 @@ struct kvm_x86_ops {
bool (*gpt_translation_fault)(struct kvm_vcpu *vcpu);
void (*control_singlestep)(struct kvm_vcpu *vcpu, bool enable);
bool (*get_vmfunc_status)(void);
+ bool (*get_eptp_switching_status)(void);
};
struct kvm_x86_nested_ops {
@@ -1422,6 +1423,7 @@ extern u64 kvm_max_tsc_scaling_ratio;
extern u64 kvm_default_tsc_scaling_ratio;
extern u64 kvm_mce_cap_supported;
+extern bool kvm_eptp_switching_supported;
/*
* EMULTYPE_NO_DECODE - Set when re-emulating an instruction (after completing
@@ -219,6 +219,14 @@ static inline bool cpu_has_vmx_vmfunc(void)
SECONDARY_EXEC_ENABLE_VMFUNC;
}
+static inline bool cpu_has_vmx_eptp_switching(void)
+{
+ u64 vmx_msr;
+
+ rdmsrl(MSR_IA32_VMX_VMFUNC, vmx_msr);
+ return vmx_msr & VMX_VMFUNC_EPTP_SWITCHING;
+}
+
static inline bool cpu_has_vmx_shadow_vmcs(void)
{
u64 vmx_msr;
@@ -7997,6 +7997,11 @@ static bool vmx_get_vmfunc_status(void)
return cpu_has_vmx_vmfunc();
}
+static bool vmx_get_eptp_switching_status(void)
+{
+ return kvm_eptp_switching_supported;
+}
+
static struct kvm_x86_ops vmx_x86_ops __initdata = {
.hardware_unsetup = hardware_unsetup,
@@ -8139,6 +8144,7 @@ static struct kvm_x86_ops vmx_x86_ops __initdata = {
.gpt_translation_fault = vmx_gpt_translation_fault,
.control_singlestep = vmx_control_singlestep,
.get_vmfunc_status = vmx_get_vmfunc_status,
+ .get_eptp_switching_status = vmx_get_eptp_switching_status,
};
static __init int hardware_setup(void)
@@ -8178,6 +8184,8 @@ static __init int hardware_setup(void)
!cpu_has_vmx_invept_global())
enable_ept = 0;
+ kvm_eptp_switching_supported = cpu_has_vmx_eptp_switching();
+
if (!cpu_has_vmx_ept_ad_bits() || !enable_ept)
enable_ept_ad_bits = 0;
@@ -161,6 +161,9 @@ module_param(force_emulation_prefix, bool, S_IRUGO);
int __read_mostly pi_inject_timer = -1;
module_param(pi_inject_timer, bint, S_IRUGO | S_IWUSR);
+bool __read_mostly kvm_eptp_switching_supported;
+EXPORT_SYMBOL_GPL(kvm_eptp_switching_supported);
+
#define KVM_NR_SHARED_MSRS 16
struct kvm_shared_msrs_global {