Message ID | 20231009212919.221810-1-seanjc@google.com |
---|---|
State | New |
Headers |
Return-Path: <linux-kernel-owner@vger.kernel.org> Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:a888:0:b0:403:3b70:6f57 with SMTP id x8csp2130431vqo; Mon, 9 Oct 2023 14:30:02 -0700 (PDT) X-Google-Smtp-Source: AGHT+IGo87tDhWQUJgg/zEn3u1vOrDUnq8oGB/PjhFmC4fQuhXqKXKBLlPwfJvGvjxa4QkEEBf3F X-Received: by 2002:a17:902:8343:b0:1c2:82e:32de with SMTP id z3-20020a170902834300b001c2082e32demr15613716pln.0.1696887001755; Mon, 09 Oct 2023 14:30:01 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1696887001; cv=none; d=google.com; s=arc-20160816; b=L4KwBEg0FsVut0tbKpTDrplpvIffgcVlTqOkhdu37hB9fuFe+r6Ibf1SXSxa2Dj25F c3514FplLU3qwMU+IB+ECq15kUpKgxzT0vy1HW9YhFXm78GjTzb6r+k8HFldxV9lg+N0 0TRDupjsMW3Euqh9OfGAnk6K6dbezEgN+XBXO73nQhllRZDtxsCM5UhVpEe0qNI4GG6c H0icE/o/6wIa40Vz40bt2/8lcKFq7es2rddsvlnr2SsEHKLKIIftJeclc9yiO/9+s0h8 mJhJszbokrfPpooNJVzU1P2dl5HKbjRahA2NnhoYK6U+xIKE3pJBl0pVxk0bBhgMWFtj jEIA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:cc:to:from:subject:message-id:mime-version:date :reply-to:dkim-signature; bh=bYkvhBthhHqIlQG5LO3kogv7cSVxxNevxV9LcQnZMPA=; fh=cGxChTyJuuVJP3J+deyn46esXkCjzHca8wSVhaJyeTE=; b=s4+wHpvt4cuYXkowtW5ss7IByrnuntsXQHKqGquPidspqljXcL+BIXMByjyCbcwrmS sAA4Iek0jG/WhO6CbVbjN38YaP4WZhIDxc292MKPRzGhPhkaxEy/ayDuvliwg6EtibQf HQRiGYTc5dNdLPwvLNM5WGpsjGCUyJkrrtaphmRSs2gpAEsqR3BgjlsOO23H4NOLVtPe 3b2tuOELjHjae+BdSE2oRu5JJcq0YOG6cQxGl6r6dDuYyqQQiqspngTzUq7un3DefF/z rw01Sc1svyeCktf/uc7FlxAsHmhIgHep/kpMsH4RlT/nJI5eTEYKZCE7NFX7hSbJmBUb gl3Q== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@google.com header.s=20230601 header.b=rFYxNkk9; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.38 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Received: from fry.vger.email (fry.vger.email. [23.128.96.38]) by mx.google.com with ESMTPS id a14-20020a170902ecce00b001c5f8995611si5384968plh.483.2023.10.09.14.30.01 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 09 Oct 2023 14:30:01 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.38 as permitted sender) client-ip=23.128.96.38; Authentication-Results: mx.google.com; dkim=pass header.i=@google.com header.s=20230601 header.b=rFYxNkk9; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.38 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Received: from out1.vger.email (depot.vger.email [IPv6:2620:137:e000::3:0]) by fry.vger.email (Postfix) with ESMTP id 6430981E5D2F; Mon, 9 Oct 2023 14:29:59 -0700 (PDT) X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.103.10 at fry.vger.email Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1378729AbjJIV3a (ORCPT <rfc822;makky5685@gmail.com> + 19 others); Mon, 9 Oct 2023 17:29:30 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58332 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1378724AbjJIV3Y (ORCPT <rfc822;linux-kernel@vger.kernel.org>); Mon, 9 Oct 2023 17:29:24 -0400 Received: from mail-pl1-x64a.google.com (mail-pl1-x64a.google.com [IPv6:2607:f8b0:4864:20::64a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A846CA7 for <linux-kernel@vger.kernel.org>; Mon, 9 Oct 2023 14:29:22 -0700 (PDT) Received: by mail-pl1-x64a.google.com with SMTP id d9443c01a7336-1c9b1ce8f0fso878595ad.0 for <linux-kernel@vger.kernel.org>; Mon, 09 Oct 2023 14:29:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1696886962; x=1697491762; darn=vger.kernel.org; h=cc:to:from:subject:message-id:mime-version:date:reply-to:from:to:cc :subject:date:message-id:reply-to; bh=bYkvhBthhHqIlQG5LO3kogv7cSVxxNevxV9LcQnZMPA=; b=rFYxNkk9qBXjJBvBs+kYp2Ta1CjsEtXbIyjVgdqBaXOpgQc4NN/J98TdGfl2jD0/un nAVwwYtR4y5Tv0HZPi7ns1azUjlRkdA4ZdxRD+MzaPsN+kPGiBg1ZY9vgw+dOF5G8F5+ 4hrAMG749yzkGYpBDW1PwrowN4SRJDrL+EWigl+FU//7GnfXDRBXO2BpNYBWEYCBlVjT fBPIubJ4WUqbfWRlE95SxuqBb76FmfHHVOt8MIomSEuHt0Dc6/KRKEkne5rS38TH0fOp H7YzYlPhMk8E9Kr8YQ9VcIK9kferNJeItfXK0EOJx+Uq1cIOZhu3Uyne8V7ujeu5jwxy dIeA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1696886962; x=1697491762; h=cc:to:from:subject:message-id:mime-version:date:reply-to :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=bYkvhBthhHqIlQG5LO3kogv7cSVxxNevxV9LcQnZMPA=; b=mnflzSuneSPoXbXIVsOZ/r586zIYKI7GSShfKz2Q0tNSH4QZsFS1J3GwntQ+XbQMfx m7EPA8NUg8cjBQsngML5wHdRY8MNdCVARcDxR+sisGb60VAMwdrQKKsMnU2UPmmDt/He HuqLwfhDjbmCbu0g82A3WtRyE1fPhLI93XnHonEy/SjFtgpWxfvnZNmrbuqFyp//FMzv eBu3CzK0VqH5jNSUv24eZsY2Bh7Avqp6uY/0UNqgifk3ErrFzkei0BrF2hs9jJMwRrIr HFLwuPF2m0DksVbE/f7Yfz4LbkurqebvoKo948KCakg3G8c375T4AZ4XcbeuKdKYnb7S uOjA== X-Gm-Message-State: AOJu0YyFWTp1svrPbW8ikpB3tySOurKpYw/Ca4ffLMxzhSE9uNjycvaa ztaBAcL4yyIIZr2x89EVA/7ajCpxbC8= X-Received: from zagreus.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:5c37]) (user=seanjc job=sendgmr) by 2002:a17:902:d4c8:b0:1c1:fc5c:b32e with SMTP id o8-20020a170902d4c800b001c1fc5cb32emr276837plg.10.1696886962172; Mon, 09 Oct 2023 14:29:22 -0700 (PDT) Reply-To: Sean Christopherson <seanjc@google.com> Date: Mon, 9 Oct 2023 14:29:19 -0700 Mime-Version: 1.0 X-Mailer: git-send-email 2.42.0.609.gbb76f46606-goog Message-ID: <20231009212919.221810-1-seanjc@google.com> Subject: [PATCH] KVM: SVM: Don't intercept IRET when injecting NMI and vNMI is enabled From: Sean Christopherson <seanjc@google.com> To: Sean Christopherson <seanjc@google.com>, Paolo Bonzini <pbonzini@redhat.com> Cc: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, Santosh Shukla <santosh.shukla@amd.com> Content-Type: text/plain; charset="UTF-8" X-Spam-Status: No, score=-4.8 required=5.0 tests=DKIMWL_WL_MED,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, MAILING_LIST_MULTI,RCVD_IN_SBL_CSS,SPF_HELO_NONE,SPF_PASS, USER_IN_DEF_DKIM_WL autolearn=no autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on fry.vger.email Precedence: bulk List-ID: <linux-kernel.vger.kernel.org> X-Mailing-List: linux-kernel@vger.kernel.org X-Greylist: Sender passed SPF test, not delayed by milter-greylist-4.6.4 (fry.vger.email [0.0.0.0]); Mon, 09 Oct 2023 14:29:59 -0700 (PDT) X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1779314984796865620 X-GMAIL-MSGID: 1779314984796865620 |
Series |
KVM: SVM: Don't intercept IRET when injecting NMI and vNMI is enabled
|
|
Commit Message
Sean Christopherson
Oct. 9, 2023, 9:29 p.m. UTC
When vNMI is enabled, rely entirely on hardware to correctly handle NMI
blocking, i.e. don't intercept IRET to detect when NMIs are no longer
blocked. KVM already correctly ignores svm->nmi_masked when vNMI is
enabled, so the effect of the bug is essentially an unnecessary VM-Exit.
Note, per the APM, hardware sets the BLOCKING flag when software directly
directly injects an NMI:
If Event Injection is used to inject an NMI when NMI Virtualization is
enabled, VMRUN sets V_NMI_MASK in the guest state.
Fixes: fa4c027a7956 ("KVM: x86: Add support for SVM's Virtual NMI")
Link: https://lore.kernel.org/all/ZOdnuDZUd4mevCqe@google.como
Cc: Santosh Shukla <santosh.shukla@amd.com>
Signed-off-by: Sean Christopherson <seanjc@google.com>
---
Santosh, can you verify that I didn't break vNMI? I don't have access to the
right hardware. Thanks!
arch/x86/kvm/svm/svm.c | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
base-commit: 86701e115030e020a052216baa942e8547e0b487
Comments
У пн, 2023-10-09 у 14:29 -0700, Sean Christopherson пише: > When vNMI is enabled, rely entirely on hardware to correctly handle NMI > blocking, i.e. don't intercept IRET to detect when NMIs are no longer > blocked. KVM already correctly ignores svm->nmi_masked when vNMI is > enabled, so the effect of the bug is essentially an unnecessary VM-Exit. I would re-phrase this like that: KVM intercepts IRET for two reasons: - To track NMI masking to be able to know at any point of time if NMI is masked. - To track NMI window (to inject another NMI after IRET finishes executing). When L1 uses vNMI, both cases are fulfilled by the vNMI hardware: - NMI masking state resides in V_NMI_BLOCKING bit of int_ctl and can be read by KVM at will. - vNMI hardware injects the NMIs autonomically every time NMI is unblocked. Thus there is no need to intercept IRET while vNMI is active. However, even when vNMI is active in L1, the svm_inject_nmi() can still be called to do a direct NMI injection to support the case when KVM is trying to inject two NMIs simultaneously. In this case there is no need to enable IRET interception. Note that the effect of this bug is essentially an unnecessary VM-Exit. Also note that even when vNMI is supported and used, running a nested guest disables vNMI of the L1 guest, thus IRET will still be intercepted. In this case if the nested VM exit happens before the NMI is delivered, an unnecessary VM exit can still happen but this is even less likely. > > Note, per the APM, hardware sets the BLOCKING flag when software directly > directly injects an NMI: > > If Event Injection is used to inject an NMI when NMI Virtualization is > enabled, VMRUN sets V_NMI_MASK in the guest state. I think that this comment is not needed in the commit message. It describes a different unrelated concern and can be put somewhere in the code but not in the commit message. > > Fixes: fa4c027a7956 ("KVM: x86: Add support for SVM's Virtual NMI") > Link: https://lore.kernel.org/all/ZOdnuDZUd4mevCqe@google.como > Cc: Santosh Shukla <santosh.shukla@amd.com> > Signed-off-by: Sean Christopherson <seanjc@google.com> > --- > > Santosh, can you verify that I didn't break vNMI? I don't have access to the > right hardware. Thanks! > > arch/x86/kvm/svm/svm.c | 11 +++++++++-- > 1 file changed, 9 insertions(+), 2 deletions(-) > > diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c > index b7472ad183b9..4f22d12b5d60 100644 > --- a/arch/x86/kvm/svm/svm.c > +++ b/arch/x86/kvm/svm/svm.c > @@ -3569,8 +3569,15 @@ static void svm_inject_nmi(struct kvm_vcpu *vcpu) > if (svm->nmi_l1_to_l2) > return; > > - svm->nmi_masked = true; > - svm_set_iret_intercept(svm); > + /* > + * No need to manually track NMI masking when vNMI is enabled, hardware > + * automatically sets V_NMI_BLOCKING_MASK as appropriate, including the > + * case where software directly injects an NMI. > + */ > + if (!is_vnmi_enabled(svm)) { > + svm->nmi_masked = true; > + svm_set_iret_intercept(svm); > + } > ++vcpu->stat.nmi_injections; > } > > > base-commit: 86701e115030e020a052216baa942e8547e0b487 Note that while nested, the 'is_vnmi_enabled()' will return false because L1's vnmi is indeed disabled (I wonder if is_vnmi_enabled should be renamed is_l1_vnmi_enabled() to clarify this), So when nested VM exit happens, that intercept can still continue to be true, which should not cause an issue but this is still something to keep in mind. Best regards, Maxim Levitsky
On Tue, Oct 10, 2023, Maxim Levitsky wrote: > У пн, 2023-10-09 у 14:29 -0700, Sean Christopherson пише: > > Note, per the APM, hardware sets the BLOCKING flag when software directly > > directly injects an NMI: > > > > If Event Injection is used to inject an NMI when NMI Virtualization is > > enabled, VMRUN sets V_NMI_MASK in the guest state. > > I think that this comment is not needed in the commit message. It describes > a different unrelated concern and can be put somewhere in the code but > not in the commit message. I strongly disagree, this blurb in the APM directly affects the patch. If hardware didn't set V_NMI_MASK, then the patch would need to be at least this: -- diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c index b7472ad183b9..d34ee3b8293e 100644 --- a/arch/x86/kvm/svm/svm.c +++ b/arch/x86/kvm/svm/svm.c @@ -3569,8 +3569,12 @@ static void svm_inject_nmi(struct kvm_vcpu *vcpu) if (svm->nmi_l1_to_l2) return; - svm->nmi_masked = true; - svm_set_iret_intercept(svm); + if (is_vnmi_enabled(svm)) { + svm->vmcb->control.int_ctl |= V_NMI_BLOCKING_MASK; + } else { + svm->nmi_masked = true; + svm_set_iret_intercept(svm); + } ++vcpu->stat.nmi_injections; } base-commit: 86701e115030e020a052216baa942e8547e0b487
У вт, 2023-10-10 у 07:46 -0700, Sean Christopherson пише: > On Tue, Oct 10, 2023, Maxim Levitsky wrote: > > У пн, 2023-10-09 у 14:29 -0700, Sean Christopherson пише: > > > Note, per the APM, hardware sets the BLOCKING flag when software directly > > > directly injects an NMI: > > > > > > If Event Injection is used to inject an NMI when NMI Virtualization is > > > enabled, VMRUN sets V_NMI_MASK in the guest state. > > > > I think that this comment is not needed in the commit message. It describes > > a different unrelated concern and can be put somewhere in the code but > > not in the commit message. > > I strongly disagree, this blurb in the APM directly affects the patch. If hardware > didn't set V_NMI_MASK, then the patch would need to be at least this: I don't see how 'the blurb in the APM' relates to the removal of the IRET intercept, which is what this patch is about. If the hardware was not to set the V_NMI_BLOCKING_MASK during EVENTINJ NMI injection, we would have had a bigger problem, a problem which would have to be addressed before this patch, because kvm reads back the V_NMI_BLOCKING_MASK (see: svm_get_nmi_mask()) to check if NMI is blocked, something that has no relation to the IRET interception. Best regards, Maxim Levtsky > > -- > diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c > index b7472ad183b9..d34ee3b8293e 100644 > --- a/arch/x86/kvm/svm/svm.c > +++ b/arch/x86/kvm/svm/svm.c > @@ -3569,8 +3569,12 @@ static void svm_inject_nmi(struct kvm_vcpu *vcpu) > if (svm->nmi_l1_to_l2) > return; > > - svm->nmi_masked = true; > - svm_set_iret_intercept(svm); > + if (is_vnmi_enabled(svm)) { > + svm->vmcb->control.int_ctl |= V_NMI_BLOCKING_MASK; > + } else { > + svm->nmi_masked = true; > + svm_set_iret_intercept(svm); > + } > ++vcpu->stat.nmi_injections; > } > > > base-commit: 86701e115030e020a052216baa942e8547e0b487
On Tue, Oct 10, 2023, Maxim Levitsky wrote: > У вт, 2023-10-10 у 07:46 -0700, Sean Christopherson пише: > > On Tue, Oct 10, 2023, Maxim Levitsky wrote: > > > У пн, 2023-10-09 у 14:29 -0700, Sean Christopherson пише: > > > > Note, per the APM, hardware sets the BLOCKING flag when software directly > > > > directly injects an NMI: > > > > > > > > If Event Injection is used to inject an NMI when NMI Virtualization is > > > > enabled, VMRUN sets V_NMI_MASK in the guest state. > > > > > > I think that this comment is not needed in the commit message. It describes > > > a different unrelated concern and can be put somewhere in the code but > > > not in the commit message. > > > > I strongly disagree, this blurb in the APM directly affects the patch. If hardware > > didn't set V_NMI_MASK, then the patch would need to be at least this: > > I don't see how 'the blurb in the APM' relates to the removal of the > IRET intercept, which is what this patch is about. No, it's not *just* about IRET interception. This patch also guards: svm->nmi_masked = true; If the reader doesn't already know that hardware sets V_NMI_BLOCK_MASK on direct injection, as was the case for me when I stumbled upon this issue, it's not at all obvious that not doing something analogous to setting nmi_masked is correct. I mentioned only IRET interception in the shortlog because that's the only practical impact of the change. I can massage the shortlog if it's confusing/misleading, but I really don't want to drop the reference to hardware setting V_NMI_BLOCK_MASK.
On 10/10/2023 8:16 PM, Sean Christopherson wrote: > On Tue, Oct 10, 2023, Maxim Levitsky wrote: >> У пн, 2023-10-09 у 14:29 -0700, Sean Christopherson пише: >>> Note, per the APM, hardware sets the BLOCKING flag when software directly >>> directly injects an NMI: >>> >>> If Event Injection is used to inject an NMI when NMI Virtualization is >>> enabled, VMRUN sets V_NMI_MASK in the guest state. >> >> I think that this comment is not needed in the commit message. It describes >> a different unrelated concern and can be put somewhere in the code but >> not in the commit message. > > I strongly disagree, this blurb in the APM directly affects the patch. If hardware > didn't set V_NMI_MASK, then the patch would need to be at least this: > > -- > diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c > index b7472ad183b9..d34ee3b8293e 100644 > --- a/arch/x86/kvm/svm/svm.c > +++ b/arch/x86/kvm/svm/svm.c > @@ -3569,8 +3569,12 @@ static void svm_inject_nmi(struct kvm_vcpu *vcpu) > if (svm->nmi_l1_to_l2) > return; > > - svm->nmi_masked = true; > - svm_set_iret_intercept(svm); > + if (is_vnmi_enabled(svm)) { > + svm->vmcb->control.int_ctl |= V_NMI_BLOCKING_MASK; > + } else { > + svm->nmi_masked = true; > + svm_set_iret_intercept(svm); > + } > ++vcpu->stat.nmi_injections; > } > > quick testing worked fine, KUT test ran fine and tested for non-nested mode so far. Will do more nested testing and share the feedback. Thanks, Santosh > base-commit: 86701e115030e020a052216baa942e8547e0b487
On 10/14/2023 3:46 PM, Santosh Shukla wrote: > > > On 10/10/2023 8:16 PM, Sean Christopherson wrote: >> On Tue, Oct 10, 2023, Maxim Levitsky wrote: >>> У пн, 2023-10-09 у 14:29 -0700, Sean Christopherson пише: >>>> Note, per the APM, hardware sets the BLOCKING flag when software directly >>>> directly injects an NMI: >>>> >>>> If Event Injection is used to inject an NMI when NMI Virtualization is >>>> enabled, VMRUN sets V_NMI_MASK in the guest state. >>> >>> I think that this comment is not needed in the commit message. It describes >>> a different unrelated concern and can be put somewhere in the code but >>> not in the commit message. >> >> I strongly disagree, this blurb in the APM directly affects the patch. If hardware >> didn't set V_NMI_MASK, then the patch would need to be at least this: >> HW sets the V_NMI_MASK. >> -- >> diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c >> index b7472ad183b9..d34ee3b8293e 100644 >> --- a/arch/x86/kvm/svm/svm.c >> +++ b/arch/x86/kvm/svm/svm.c >> @@ -3569,8 +3569,12 @@ static void svm_inject_nmi(struct kvm_vcpu *vcpu) >> if (svm->nmi_l1_to_l2) >> return; >> >> - svm->nmi_masked = true; >> - svm_set_iret_intercept(svm); >> + if (is_vnmi_enabled(svm)) { >> + svm->vmcb->control.int_ctl |= V_NMI_BLOCKING_MASK; >> + } else { >> + svm->nmi_masked = true; >> + svm_set_iret_intercept(svm); >> + } >> ++vcpu->stat.nmi_injections; >> } >> >> > > quick testing worked fine, KUT test ran fine and tested for non-nested mode so far. > Will do more nested testing and share the feedback. > Sean - I have tested original patch[1] for nested and KUT, worked fine. Thanks, Santosh [1] https://lore.kernel.org/r/20231009212919.221810-1-seanjc@google.com > Thanks, > Santosh > >> base-commit: 86701e115030e020a052216baa942e8547e0b487 >
diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c index b7472ad183b9..4f22d12b5d60 100644 --- a/arch/x86/kvm/svm/svm.c +++ b/arch/x86/kvm/svm/svm.c @@ -3569,8 +3569,15 @@ static void svm_inject_nmi(struct kvm_vcpu *vcpu) if (svm->nmi_l1_to_l2) return; - svm->nmi_masked = true; - svm_set_iret_intercept(svm); + /* + * No need to manually track NMI masking when vNMI is enabled, hardware + * automatically sets V_NMI_BLOCKING_MASK as appropriate, including the + * case where software directly injects an NMI. + */ + if (!is_vnmi_enabled(svm)) { + svm->nmi_masked = true; + svm_set_iret_intercept(svm); + } ++vcpu->stat.nmi_injections; }