Skip to content

Commit 400fee8

Browse files
committed
KVM: x86: Tweak the code and comment related to handling concurrent NMIs
Tweak the code and comment that deals with concurrent NMIs to explicitly call out that x86 allows exactly one pending NMI, but that KVM needs to temporarily allow two pending NMIs in order to workaround the fact that the target vCPU cannot immediately recognize an incoming NMI, unlike bare metal. No functional change intended. Signed-off-by: Santosh Shukla <Santosh.Shukla@amd.com> Link: https://lore.kernel.org/r/20230227084016.3368-7-santosh.shukla@amd.com Signed-off-by: Sean Christopherson <seanjc@google.com>
1 parent 2cb9317 commit 400fee8

1 file changed

Lines changed: 11 additions & 4 deletions

File tree

arch/x86/kvm/x86.c

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10138,15 +10138,22 @@ static int kvm_check_and_inject_events(struct kvm_vcpu *vcpu,
1013810138

1013910139
static void process_nmi(struct kvm_vcpu *vcpu)
1014010140
{
10141-
unsigned limit = 2;
10141+
unsigned int limit;
1014210142

1014310143
/*
10144-
* x86 is limited to one NMI running, and one NMI pending after it.
10145-
* If an NMI is already in progress, limit further NMIs to just one.
10146-
* Otherwise, allow two (and we'll inject the first one immediately).
10144+
* x86 is limited to one NMI pending, but because KVM can't react to
10145+
* incoming NMIs as quickly as bare metal, e.g. if the vCPU is
10146+
* scheduled out, KVM needs to play nice with two queued NMIs showing
10147+
* up at the same time. To handle this scenario, allow two NMIs to be
10148+
* (temporarily) pending so long as NMIs are not blocked and KVM is not
10149+
* waiting for a previous NMI injection to complete (which effectively
10150+
* blocks NMIs). KVM will immediately inject one of the two NMIs, and
10151+
* will request an NMI window to handle the second NMI.
1014710152
*/
1014810153
if (static_call(kvm_x86_get_nmi_mask)(vcpu) || vcpu->arch.nmi_injected)
1014910154
limit = 1;
10155+
else
10156+
limit = 2;
1015010157

1015110158
vcpu->arch.nmi_pending += atomic_xchg(&vcpu->arch.nmi_queued, 0);
1015210159
vcpu->arch.nmi_pending = min(vcpu->arch.nmi_pending, limit);

0 commit comments

Comments
 (0)