| From 8d68bad6d869fae8f4d50ab6423538dec7da72d1 Mon Sep 17 00:00:00 2001 |
| From: Vitaly Kuznetsov <vkuznets@redhat.com> |
| Date: Tue, 7 Sep 2021 18:35:30 +0200 |
| Subject: KVM: nVMX: Filter out all unsupported controls when eVMCS was activated |
| |
| From: Vitaly Kuznetsov <vkuznets@redhat.com> |
| |
| commit 8d68bad6d869fae8f4d50ab6423538dec7da72d1 upstream. |
| |
| Windows Server 2022 with Hyper-V role enabled failed to boot on KVM when |
| enlightened VMCS is advertised. Debugging revealed there are two exposed |
| secondary controls it is not happy with: SECONDARY_EXEC_ENABLE_VMFUNC and |
| SECONDARY_EXEC_SHADOW_VMCS. These controls are known to be unsupported, |
| as there are no corresponding fields in eVMCSv1 (see the comment above |
| EVMCS1_UNSUPPORTED_2NDEXEC definition). |
| |
| Previously, commit 31de3d2500e4 ("x86/kvm/hyper-v: move VMX controls |
| sanitization out of nested_enable_evmcs()") introduced the required |
| filtering mechanism for VMX MSRs but for some reason put only known |
| to be problematic (and not full EVMCS1_UNSUPPORTED_* lists) controls |
| there. |
| |
| Note, Windows Server 2022 seems to have gained some sanity check for VMX |
| MSRs: it doesn't even try to launch a guest when there's something it |
| doesn't like, nested_evmcs_check_controls() mechanism can't catch the |
| problem. |
| |
| Let's be bold this time and instead of playing whack-a-mole just filter out |
| all unsupported controls from VMX MSRs. |
| |
| Fixes: 31de3d2500e4 ("x86/kvm/hyper-v: move VMX controls sanitization out of nested_enable_evmcs()") |
| Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com> |
| Message-Id: <20210907163530.110066-1-vkuznets@redhat.com> |
| Cc: stable@vger.kernel.org |
| Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| arch/x86/kvm/vmx/evmcs.c | 12 +++++++++--- |
| arch/x86/kvm/vmx/vmx.c | 9 +++++---- |
| 2 files changed, 14 insertions(+), 7 deletions(-) |
| |
| --- a/arch/x86/kvm/vmx/evmcs.c |
| +++ b/arch/x86/kvm/vmx/evmcs.c |
| @@ -352,14 +352,20 @@ void nested_evmcs_filter_control_msr(u32 |
| switch (msr_index) { |
| case MSR_IA32_VMX_EXIT_CTLS: |
| case MSR_IA32_VMX_TRUE_EXIT_CTLS: |
| - ctl_high &= ~VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL; |
| + ctl_high &= ~EVMCS1_UNSUPPORTED_VMEXIT_CTRL; |
| break; |
| case MSR_IA32_VMX_ENTRY_CTLS: |
| case MSR_IA32_VMX_TRUE_ENTRY_CTLS: |
| - ctl_high &= ~VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL; |
| + ctl_high &= ~EVMCS1_UNSUPPORTED_VMENTRY_CTRL; |
| break; |
| case MSR_IA32_VMX_PROCBASED_CTLS2: |
| - ctl_high &= ~SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES; |
| + ctl_high &= ~EVMCS1_UNSUPPORTED_2NDEXEC; |
| + break; |
| + case MSR_IA32_VMX_PINBASED_CTLS: |
| + ctl_high &= ~EVMCS1_UNSUPPORTED_PINCTRL; |
| + break; |
| + case MSR_IA32_VMX_VMFUNC: |
| + ctl_low &= ~EVMCS1_UNSUPPORTED_VMFUNC; |
| break; |
| } |
| |
| --- a/arch/x86/kvm/vmx/vmx.c |
| +++ b/arch/x86/kvm/vmx/vmx.c |
| @@ -1867,10 +1867,11 @@ static int vmx_get_msr(struct kvm_vcpu * |
| &msr_info->data)) |
| return 1; |
| /* |
| - * Enlightened VMCS v1 doesn't have certain fields, but buggy |
| - * Hyper-V versions are still trying to use corresponding |
| - * features when they are exposed. Filter out the essential |
| - * minimum. |
| + * Enlightened VMCS v1 doesn't have certain VMCS fields but |
| + * instead of just ignoring the features, different Hyper-V |
| + * versions are either trying to use them and fail or do some |
| + * sanity checking and refuse to boot. Filter all unsupported |
| + * features out. |
| */ |
| if (!msr_info->host_initiated && |
| vmx->nested.enlightened_vmcs_enabled) |