Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ea152987 authored by Vitaly Kuznetsov's avatar Vitaly Kuznetsov Committed by Radim Krčmář
Browse files

KVM: x86: hyper-v: don't crash on KVM_GET_SUPPORTED_HV_CPUID when kvm_intel.nested is disabled



If kvm_intel is loaded with nested=0 parameter an attempt to perform
KVM_GET_SUPPORTED_HV_CPUID results in OOPS as nested_get_evmcs_version hook
in kvm_x86_ops is NULL (we assign it in nested_vmx_hardware_setup() and
this only happens in case nested is enabled).

Check that kvm_x86_ops->nested_get_evmcs_version is not NULL before
calling it. With this, we can remove the stub from svm as it is no
longer needed.

Cc: <stable@vger.kernel.org>
Fixes: e2e871ab ("x86/kvm/hyper-v: Introduce nested_get_evmcs_version() helper")
Signed-off-by: default avatarVitaly Kuznetsov <vkuznets@redhat.com>
Reviewed-by: default avatarJim Mattson <jmattson@google.com>
Signed-off-by: default avatarRadim Krčmář <rkrcmar@redhat.com>
parent c91ff721
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -1781,7 +1781,7 @@ int kvm_vm_ioctl_hv_eventfd(struct kvm *kvm, struct kvm_hyperv_eventfd *args)
int kvm_vcpu_ioctl_get_hv_cpuid(struct kvm_vcpu *vcpu, struct kvm_cpuid2 *cpuid,
				struct kvm_cpuid_entry2 __user *entries)
{
	uint16_t evmcs_ver = kvm_x86_ops->nested_get_evmcs_version(vcpu);
	uint16_t evmcs_ver = 0;
	struct kvm_cpuid_entry2 cpuid_entries[] = {
		{ .function = HYPERV_CPUID_VENDOR_AND_MAX_FUNCTIONS },
		{ .function = HYPERV_CPUID_INTERFACE },
@@ -1793,6 +1793,9 @@ int kvm_vcpu_ioctl_get_hv_cpuid(struct kvm_vcpu *vcpu, struct kvm_cpuid2 *cpuid,
	};
	int i, nent = ARRAY_SIZE(cpuid_entries);

	if (kvm_x86_ops->nested_get_evmcs_version)
		evmcs_ver = kvm_x86_ops->nested_get_evmcs_version(vcpu);

	/* Skip NESTED_FEATURES if eVMCS is not supported */
	if (!evmcs_ver)
		--nent;
+1 −7
Original line number Diff line number Diff line
@@ -7128,12 +7128,6 @@ static int svm_unregister_enc_region(struct kvm *kvm,
	return ret;
}

static uint16_t nested_get_evmcs_version(struct kvm_vcpu *vcpu)
{
	/* Not supported */
	return 0;
}

static int nested_enable_evmcs(struct kvm_vcpu *vcpu,
				   uint16_t *vmcs_version)
{
@@ -7332,7 +7326,7 @@ static struct kvm_x86_ops svm_x86_ops __ro_after_init = {
	.mem_enc_unreg_region = svm_unregister_enc_region,

	.nested_enable_evmcs = nested_enable_evmcs,
	.nested_get_evmcs_version = nested_get_evmcs_version,
	.nested_get_evmcs_version = NULL,

	.need_emulation_on_page_fault = svm_need_emulation_on_page_fault,
};
+1 −0
Original line number Diff line number Diff line
@@ -7797,6 +7797,7 @@ static struct kvm_x86_ops vmx_x86_ops __ro_after_init = {
	.set_nested_state = NULL,
	.get_vmcs12_pages = NULL,
	.nested_enable_evmcs = NULL,
	.nested_get_evmcs_version = NULL,
	.need_emulation_on_page_fault = vmx_need_emulation_on_page_fault,
};