| From 50f866d0c44b299b0665a73c22f861d587f21421 Mon Sep 17 00:00:00 2001 |
| From: Vitaly Kuznetsov <vkuznets@redhat.com> |
| Date: Wed, 1 Apr 2020 10:13:48 +0200 |
| Subject: [PATCH] KVM: VMX: fix crash cleanup when KVM wasn't used |
| |
| commit dbef2808af6c594922fe32833b30f55f35e9da6d upstream. |
| |
| If KVM wasn't used at all before we crash the cleanup procedure fails with |
| BUG: unable to handle page fault for address: ffffffffffffffc8 |
| #PF: supervisor read access in kernel mode |
| #PF: error_code(0x0000) - not-present page |
| PGD 23215067 P4D 23215067 PUD 23217067 PMD 0 |
| Oops: 0000 [#8] SMP PTI |
| CPU: 0 PID: 3542 Comm: bash Kdump: loaded Tainted: G D 5.6.0-rc2+ #823 |
| RIP: 0010:crash_vmclear_local_loaded_vmcss.cold+0x19/0x51 [kvm_intel] |
| |
| The root cause is that loaded_vmcss_on_cpu list is not yet initialized, |
| we initialize it in hardware_enable() but this only happens when we start |
| a VM. |
| |
| Previously, we used to have a bitmap with enabled CPUs and that was |
| preventing [masking] the issue. |
| |
| Initialized loaded_vmcss_on_cpu list earlier, right before we assign |
| crash_vmclear_loaded_vmcss pointer. blocked_vcpu_on_cpu list and |
| blocked_vcpu_on_cpu_lock are moved altogether for consistency. |
| |
| Fixes: 31603d4fc2bb ("KVM: VMX: Always VMCLEAR in-use VMCSes during crash with kexec support") |
| Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com> |
| Message-Id: <20200401081348.1345307-1-vkuznets@redhat.com> |
| Reviewed-by: Sean Christopherson <sean.j.christopherson@intel.com> |
| Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> |
| Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> |
| |
| diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c |
| index fd8cdf401de7..455612c1825f 100644 |
| --- a/arch/x86/kvm/vmx/vmx.c |
| +++ b/arch/x86/kvm/vmx/vmx.c |
| @@ -2084,10 +2084,6 @@ static int hardware_enable(void) |
| !hv_get_vp_assist_page(cpu)) |
| return -EFAULT; |
| |
| - INIT_LIST_HEAD(&per_cpu(loaded_vmcss_on_cpu, cpu)); |
| - INIT_LIST_HEAD(&per_cpu(blocked_vcpu_on_cpu, cpu)); |
| - spin_lock_init(&per_cpu(blocked_vcpu_on_cpu_lock, cpu)); |
| - |
| rdmsrl(MSR_IA32_FEATURE_CONTROL, old); |
| |
| test_bits = FEATURE_CONTROL_LOCKED; |
| @@ -7845,7 +7841,7 @@ module_exit(vmx_exit); |
| |
| static int __init vmx_init(void) |
| { |
| - int r; |
| + int r, cpu; |
| |
| #if IS_ENABLED(CONFIG_HYPERV) |
| /* |
| @@ -7896,6 +7892,12 @@ static int __init vmx_init(void) |
| } |
| } |
| |
| + for_each_possible_cpu(cpu) { |
| + INIT_LIST_HEAD(&per_cpu(loaded_vmcss_on_cpu, cpu)); |
| + INIT_LIST_HEAD(&per_cpu(blocked_vcpu_on_cpu, cpu)); |
| + spin_lock_init(&per_cpu(blocked_vcpu_on_cpu_lock, cpu)); |
| + } |
| + |
| #ifdef CONFIG_KEXEC_CORE |
| rcu_assign_pointer(crash_vmclear_loaded_vmcss, |
| crash_vmclear_local_loaded_vmcss); |
| -- |
| 2.7.4 |
| |