FAILED: patch "[PATCH] KVM: VMX: Fix handling of #MC that occurs during VM-Entry" failed to apply to 4.19-stable tree
Subsystems (3)
[email protected]
maintainerThe patch below does not apply to the 4.19-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From beb8d93b3e423043e079ef3dda19dad7b28467a8 Mon Sep 17 00:00:00 2001
From: Sean Christopherson <[email protected]>
Date: Fri, 19 Apr 2019 22:50:55 -0700
Subject: [PATCH] KVM: VMX: Fix handling of #MC that occurs during VM-Entry
A previous fix to prevent KVM from consuming stale VMCS state after a failed VM-Entry inadvertantly blocked KVM's handling of machine checks that occur during VM-Entry.
Per Intel's SDM, a #MC during VM-Entry is handled in one of three ways, depending on when the #MC is recognoized. As it pertains to this bug fix, the third case explicitly states EXIT_REASON_MCE_DURING_VMENTRY is handled like any other VM-Exit during VM-Entry, i.e. sets bit 31 to indicate the VM-Entry failed.
If a machine-check event occurs during a VM entry, one of the following occurs:
- The machine-check event is handled as if it occurred before the VM entry:
...
- The machine-check event is handled after VM entry completes:
...- A VM-entry failure occurs as described in Section 26.7. The basic exit reason is 41, for "VM-entry failure due to machine-check event".
Explicitly handle EXIT_REASON_MCE_DURING_VMENTRY as a one-off case in vmx_vcpu_run() instead of binning it into vmx_complete_atomic_exit(). Doing so allows vmx_vcpu_run() to handle VMX_EXIT_REASONS_FAILED_VMENTRY in a sane fashion and also simplifies vmx_complete_atomic_exit() since VMCS.VM_EXIT_INTR_INFO is guaranteed to be fresh.
arch/x86/kvm/vmx/vmx.c +8 -12
@@ -6107,28 +6107,21 @@ static void vmx_apicv_post_state_restore(struct kvm_vcpu *vcpu)static void vmx_complete_atomic_exit (struct vcpu_vmx *vmx) { -u32 exit_intr_info =0 ; -u16 basic_exit_reason = (u16 )vmx->exit_reason; - -if (!(basic_exit_reason ==EXIT_REASON_MCE_DURING_VMENTRY - || basic_exit_reason ==EXIT_REASON_EXCEPTION_NMI )) +if (vmx->exit_reason !=EXIT_REASON_EXCEPTION_NMI )return ; -if (!(vmx->exit_reason &VMX_EXIT_REASONS_FAILED_VMENTRY )) - exit_intr_info =vmcs_read32 (VM_EXIT_INTR_INFO ); - vmx->exit_intr_info = exit_intr_info; + vmx->exit_intr_info =vmcs_read32 (VM_EXIT_INTR_INFO );/* if exit due to PF check for async PF */ -if (is_page_fault (exit_intr_info)) +if (is_page_fault (vmx->exit_intr_info)) vmx->vcpu.arch.apf.host_apf_reason =kvm_read_and_reset_pf_reason ();/* Handle machine checks before interrupts are enabled */ -if (basic_exit_reason ==EXIT_REASON_MCE_DURING_VMENTRY || -is_machine_check (exit_intr_info)) +if (is_machine_check (vmx->exit_intr_info))kvm_machine_check ();/* We need to handle NMIs before interrupts are enabled */ -if (is_nmi (exit_intr_info)) { +if (is_nmi (vmx->exit_intr_info)) {kvm_before_interrupt (&vmx->vcpu); asm("int $2" );kvm_after_interrupt (&vmx->vcpu);
@@ -6535,6 +6528,9 @@ static void vmx_vcpu_run(struct kvm_vcpu *vcpu) vmx->idt_vectoring_info =0 ; vmx->exit_reason = vmx->fail ?0xdead :vmcs_read32 (VM_EXIT_REASON ); +if ((u16 )vmx->exit_reason ==EXIT_REASON_MCE_DURING_VMENTRY ) +kvm_machine_check (); +if (vmx->fail || (vmx->exit_reason &VMX_EXIT_REASONS_FAILED_VMENTRY ))return ;