]> git.ipfire.org Git - thirdparty/kernel/linux.git/commit
KVM: nSVM: Clear tracking of L1->L2 NMI and soft IRQ on nested #VMEXIT
authorYosry Ahmed <yosry@kernel.org>
Tue, 3 Mar 2026 00:34:06 +0000 (00:34 +0000)
committerSean Christopherson <seanjc@google.com>
Thu, 5 Mar 2026 00:08:50 +0000 (16:08 -0800)
commit8998e1d012f3f45d0456f16706682cef04c3c436
treee7e08cafd63eec792c688c35cfa658726d68adc0
parent69b721a86d0dcb026f6db7d111dcde7550442d2e
KVM: nSVM: Clear tracking of L1->L2 NMI and soft IRQ on nested #VMEXIT

KVM clears tracking of L1->L2 injected NMIs (i.e. nmi_l1_to_l2) and soft
IRQs (i.e. soft_int_injected) on a synthesized #VMEXIT(INVALID) due to
failed VMRUN. However, they are not explicitly cleared in other
synthesized #VMEXITs.

soft_int_injected is always cleared after the first VMRUN of L2 when
completing interrupts, as any re-injection is then tracked by KVM
(instead of purely in vmcb02).

nmi_l1_to_l2 is not cleared after the first VMRUN if NMI injection
failed, as KVM still needs to keep track that the NMI originated from L1
to avoid blocking NMIs for L1. It is only cleared when the NMI injection
succeeds.

KVM could synthesize a #VMEXIT to L1 before successfully injecting the
NMI into L2 (e.g. due to a #NPF on L2's NMI handler in L1's NPTs). In
this case, nmi_l1_to_l2 will remain true, and KVM may not correctly mask
NMIs and intercept IRET when injecting an NMI into L1.

Clear both nmi_l1_to_l2 and soft_int_injected in nested_svm_vmexit(), i.e.
for all #VMEXITs except those that occur due to failed consistency checks,
as those happen before nmi_l1_to_l2 or soft_int_injected are set.

Fixes: 159fc6fa3b7d ("KVM: nSVM: Transparently handle L1 -> L2 NMI re-injection")
Cc: stable@vger.kernel.org
Signed-off-by: Yosry Ahmed <yosry@kernel.org>
Link: https://patch.msgid.link/20260303003421.2185681-13-yosry@kernel.org
Signed-off-by: Sean Christopherson <seanjc@google.com>
arch/x86/kvm/svm/nested.c