diff --git a/arch/x86/kvm/vmx/evmcs.c b/arch/x86/kvm/vmx/evmcs.c index 9139c70b6008..a82af2482f84 100644 --- a/arch/x86/kvm/vmx/evmcs.c +++ b/arch/x86/kvm/vmx/evmcs.c @@ -345,6 +345,45 @@ uint16_t nested_get_evmcs_version(struct kvm_vcpu *vcpu) return 0; } +enum evmcs_revision { + EVMCSv1_LEGACY, + NR_EVMCS_REVISIONS, +}; + +enum evmcs_ctrl_type { + EVMCS_EXIT_CTRLS, + EVMCS_ENTRY_CTRLS, + EVMCS_2NDEXEC, + EVMCS_PINCTRL, + EVMCS_VMFUNC, + NR_EVMCS_CTRLS, +}; + +static const u32 evmcs_unsupported_ctrls[NR_EVMCS_CTRLS][NR_EVMCS_REVISIONS] = { + [EVMCS_EXIT_CTRLS] = { + [EVMCSv1_LEGACY] = EVMCS1_UNSUPPORTED_VMEXIT_CTRL, + }, + [EVMCS_ENTRY_CTRLS] = { + [EVMCSv1_LEGACY] = EVMCS1_UNSUPPORTED_VMENTRY_CTRL, + }, + [EVMCS_2NDEXEC] = { + [EVMCSv1_LEGACY] = EVMCS1_UNSUPPORTED_2NDEXEC, + }, + [EVMCS_PINCTRL] = { + [EVMCSv1_LEGACY] = EVMCS1_UNSUPPORTED_PINCTRL, + }, + [EVMCS_VMFUNC] = { + [EVMCSv1_LEGACY] = EVMCS1_UNSUPPORTED_VMFUNC, + }, +}; + +static u32 evmcs_get_unsupported_ctls(enum evmcs_ctrl_type ctrl_type) +{ + enum evmcs_revision evmcs_rev = EVMCSv1_LEGACY; + + return evmcs_unsupported_ctrls[ctrl_type][evmcs_rev]; +} + void nested_evmcs_filter_control_msr(u32 msr_index, u64 *pdata) { u32 ctl_low = (u32)*pdata; @@ -357,21 +396,21 @@ void nested_evmcs_filter_control_msr(u32 msr_index, u64 *pdata) switch (msr_index) { case MSR_IA32_VMX_EXIT_CTLS: case MSR_IA32_VMX_TRUE_EXIT_CTLS: - ctl_high &= ~EVMCS1_UNSUPPORTED_VMEXIT_CTRL; + ctl_high &= ~evmcs_get_unsupported_ctls(EVMCS_EXIT_CTRLS); break; case MSR_IA32_VMX_ENTRY_CTLS: case MSR_IA32_VMX_TRUE_ENTRY_CTLS: - ctl_high &= ~EVMCS1_UNSUPPORTED_VMENTRY_CTRL; + ctl_high &= ~evmcs_get_unsupported_ctls(EVMCS_ENTRY_CTRLS); break; case MSR_IA32_VMX_PROCBASED_CTLS2: - ctl_high &= ~EVMCS1_UNSUPPORTED_2NDEXEC; + ctl_high &= ~evmcs_get_unsupported_ctls(EVMCS_2NDEXEC); break; case MSR_IA32_VMX_TRUE_PINBASED_CTLS: case MSR_IA32_VMX_PINBASED_CTLS: - ctl_high &= ~EVMCS1_UNSUPPORTED_PINCTRL; + ctl_high &= ~evmcs_get_unsupported_ctls(EVMCS_PINCTRL); break; case MSR_IA32_VMX_VMFUNC: - ctl_low &= ~EVMCS1_UNSUPPORTED_VMFUNC; + ctl_low &= ~evmcs_get_unsupported_ctls(EVMCS_VMFUNC); break; } @@ -384,7 +423,7 @@ int nested_evmcs_check_controls(struct vmcs12 *vmcs12) u32 unsupp_ctl; unsupp_ctl = vmcs12->pin_based_vm_exec_control & - EVMCS1_UNSUPPORTED_PINCTRL; + evmcs_get_unsupported_ctls(EVMCS_PINCTRL); if (unsupp_ctl) { trace_kvm_nested_vmenter_failed( "eVMCS: unsupported pin-based VM-execution controls", @@ -393,7 +432,7 @@ int nested_evmcs_check_controls(struct vmcs12 *vmcs12) } unsupp_ctl = vmcs12->secondary_vm_exec_control & - EVMCS1_UNSUPPORTED_2NDEXEC; + evmcs_get_unsupported_ctls(EVMCS_2NDEXEC); if (unsupp_ctl) { trace_kvm_nested_vmenter_failed( "eVMCS: unsupported secondary VM-execution controls", @@ -402,7 +441,7 @@ int nested_evmcs_check_controls(struct vmcs12 *vmcs12) } unsupp_ctl = vmcs12->vm_exit_controls & - EVMCS1_UNSUPPORTED_VMEXIT_CTRL; + evmcs_get_unsupported_ctls(EVMCS_EXIT_CTRLS); if (unsupp_ctl) { trace_kvm_nested_vmenter_failed( "eVMCS: unsupported VM-exit controls", @@ -411,7 +450,7 @@ int nested_evmcs_check_controls(struct vmcs12 *vmcs12) } unsupp_ctl = vmcs12->vm_entry_controls & - EVMCS1_UNSUPPORTED_VMENTRY_CTRL; + evmcs_get_unsupported_ctls(EVMCS_ENTRY_CTRLS); if (unsupp_ctl) { trace_kvm_nested_vmenter_failed( "eVMCS: unsupported VM-entry controls", @@ -419,7 +458,8 @@ int nested_evmcs_check_controls(struct vmcs12 *vmcs12) ret = -EINVAL; } - unsupp_ctl = vmcs12->vm_function_control & EVMCS1_UNSUPPORTED_VMFUNC; + 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",