Commit 6cce93de authored by Sean Christopherson's avatar Sean Christopherson Committed by Paolo Bonzini
Browse files

KVM: nVMX: Use CC() macro to handle eVMCS unsupported controls checks



Locally #define and use the nested virtualization Consistency Check (CC)
macro to handle eVMCS unsupported controls checks.  Using the macro loses
the existing printing of the unsupported controls, but that's a feature
and not a bug.  The existing approach is flawed because the @err param to
trace_kvm_nested_vmenter_failed() is the error code, not the error value.

The eVMCS trickery mostly works as __print_symbolic() falls back to
printing the raw hex value, but that subtly relies on not having a match
between the unsupported value and VMX_VMENTER_INSTRUCTION_ERRORS.

If it's really truly necessary to snapshot the bad value, then the
tracepoint can be extended in the future.

Signed-off-by: default avatarSean Christopherson <seanjc@google.com>
Signed-off-by: default avatarVitaly Kuznetsov <vkuznets@redhat.com>
Signed-off-by: default avatarSean Christopherson <seanjc@google.com>
Link: https://lore.kernel.org/r/20220830133737.1539624-9-vkuznets@redhat.com


Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
parent f4d361b4
Loading
Loading
Loading
Loading
+24 −44
Original line number Diff line number Diff line
@@ -10,6 +10,8 @@
#include "vmx.h"
#include "trace.h"

#define CC KVM_NESTED_VMENTER_CONSISTENCY_CHECK

DEFINE_STATIC_KEY_FALSE(enable_evmcs);

#define EVMCS1_OFFSET(x) offsetof(struct hv_enlightened_vmcs, x)
@@ -417,57 +419,35 @@ void nested_evmcs_filter_control_msr(u32 msr_index, u64 *pdata)
	*pdata = ctl_low | ((u64)ctl_high << 32);
}

int nested_evmcs_check_controls(struct vmcs12 *vmcs12)
static bool nested_evmcs_is_valid_controls(enum evmcs_ctrl_type ctrl_type,
					   u32 val)
{
	int ret = 0;
	u32 unsupp_ctl;

	unsupp_ctl = vmcs12->pin_based_vm_exec_control &
		evmcs_get_unsupported_ctls(EVMCS_PINCTRL);
	if (unsupp_ctl) {
		trace_kvm_nested_vmenter_failed(
			"eVMCS: unsupported pin-based VM-execution controls",
			unsupp_ctl);
		ret = -EINVAL;
	return !(val & evmcs_get_unsupported_ctls(ctrl_type));
}

	unsupp_ctl = vmcs12->secondary_vm_exec_control &
		evmcs_get_unsupported_ctls(EVMCS_2NDEXEC);
	if (unsupp_ctl) {
		trace_kvm_nested_vmenter_failed(
			"eVMCS: unsupported secondary VM-execution controls",
			unsupp_ctl);
		ret = -EINVAL;
	}
int nested_evmcs_check_controls(struct vmcs12 *vmcs12)
{
	if (CC(!nested_evmcs_is_valid_controls(EVMCS_PINCTRL,
					       vmcs12->pin_based_vm_exec_control)))
		return -EINVAL;

	unsupp_ctl = vmcs12->vm_exit_controls &
		evmcs_get_unsupported_ctls(EVMCS_EXIT_CTRLS);
	if (unsupp_ctl) {
		trace_kvm_nested_vmenter_failed(
			"eVMCS: unsupported VM-exit controls",
			unsupp_ctl);
		ret = -EINVAL;
	}
	if (CC(!nested_evmcs_is_valid_controls(EVMCS_2NDEXEC,
					       vmcs12->secondary_vm_exec_control)))
		return -EINVAL;

	unsupp_ctl = vmcs12->vm_entry_controls &
		evmcs_get_unsupported_ctls(EVMCS_ENTRY_CTRLS);
	if (unsupp_ctl) {
		trace_kvm_nested_vmenter_failed(
			"eVMCS: unsupported VM-entry controls",
			unsupp_ctl);
		ret = -EINVAL;
	}
	if (CC(!nested_evmcs_is_valid_controls(EVMCS_EXIT_CTRLS,
					       vmcs12->vm_exit_controls)))
		return -EINVAL;

	unsupp_ctl = vmcs12->vm_function_control &
		evmcs_get_unsupported_ctls(EVMCS_VMFUNC);
	if (unsupp_ctl) {
		trace_kvm_nested_vmenter_failed(
			"eVMCS: unsupported VM-function controls",
			unsupp_ctl);
		ret = -EINVAL;
	}
	if (CC(!nested_evmcs_is_valid_controls(EVMCS_ENTRY_CTRLS,
					       vmcs12->vm_entry_controls)))
		return -EINVAL;

	return ret;
	if (CC(!nested_evmcs_is_valid_controls(EVMCS_VMFUNC,
					       vmcs12->vm_function_control)))
		return -EINVAL;

	return 0;
}

int nested_enable_evmcs(struct kvm_vcpu *vcpu,