From: Sean Christopherson <seanjc@google.com>
To: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Santosh Shukla <santosh.shukla@amd.com>,
Maxim Levitsky <mlevitsk@redhat.com>,
pbonzini@redhat.com, jmattson@google.com, kvm@vger.kernel.org,
joro@8bytes.org, linux-kernel@vger.kernel.org,
mail@maciej.szmigiero.name, vkuznets@redhat.com
Subject: Re: [PATCHv5 0/8] Virtual NMI feature
Date: Wed, 16 Nov 2022 16:59:23 +0000 [thread overview]
Message-ID: <Y3UW672P8ruO48Ct@google.com> (raw)
In-Reply-To: <bc7fd8db-88e6-ea9c-2266-d0e129025e6b@amd.com>
On Wed, Nov 16, 2022, Tom Lendacky wrote:
> On 11/16/22 09:44, Santosh Shukla wrote:
> > Hello Maxim,.
> >
> > On 11/16/2022 2:51 PM, Maxim Levitsky wrote:
> > > On Wed, 2022-11-16 at 11:10 +0530, Santosh Shukla wrote:
> > > > Hi Maxim,
> > > >
> > > > On 11/14/2022 8:01 PM, Maxim Levitsky wrote:
> > > > > On Mon, 2022-11-14 at 13:32 +0530, Santosh Shukla wrote:
> > > > > I started reviewing it today and I think there are still few issues,
> > > > > and the biggest one is that if a NMI arrives while vNMI injection
> > > > > is pending, current code just drops such NMI.
I don't think it gets dropped, just improperly delayed.
> > > > > We had a discussion about this, like forcing immeditate vm exit
> > > >
> > > > I believe, We discussed above case in [1] i.e.. HW can handle
> > > > the second (/pending)virtual NMI while the guest processing first virtual NMI w/o vmexit.
> > > > is it same scenario or different one that you are mentioning?
> > > >
> > > > [1] https://lore.kernel.org/lkml/1782cdbb-8274-8c3d-fa98-29147f1e5d1e@amd.com/>>
> > > You misunderstood the issue.
> > >
> > > Hardware can handle the case when a NMI is in service (that is V_NMI_MASK
> > > is set) and another one is injected (V_NMI_PENDING can be set),
> > >
> > > but it is not possible to handle the case when a NMI is already injected
> > > (V_NMI_PENDING set) but and KVM wants to inject another one before the
> > > first one went into the service (that is V_NMI_MASK is not set yet).
> >
> > In this case, HW will collapse the NMI.
Yes, but practically speaking two NMIs can't arrive at the exact same instance on
bare metal. One NMI will always arrive first and get vectored, and then the second
NMI will arrive and be pended. In a virtual environment, two NMIs that are sent
far apart can arrive together, e.g. if the vCPU is scheduled out for an extended
period of time. KVM mitigates this side effect by allowing two NMIs to be pending.
The problem here isn't that second the NMI is lost, it's that KVM can't get control
when the first NMI completes (IRETs). KVM can pend both NMIs and queue the first
for injection/vectoring (set V_NMI_PENDING), but AIUI there is no mechanism (and no
code) to force a VM-Exit on the IRET so that KVM can inject the second NMI.
Santosh's response in v2[*] suggested that hardware would allow KVM to "post" an
NMI while the vCPU is running, but I don't see any code in this series to actually
do that. svm_inject_nmi() is only called from the vCPU's run loop, i.e. requires
a VM-Exit.
[*] https://lore.kernel.org/all/1782cdbb-8274-8c3d-fa98-29147f1e5d1e@amd.com
> > Note that the HW will take the pending NMI at the boundary of IRET instruction such that
> > it will check for the V_NMI_PENDING and if its set then HW will *take* the NMI,
> > HW will clear the V_NMI_PENDING bit and set the V_NMI_MASK w/o the VMEXIT!,.
> >
> >
> > > Also same can happen when NMIs are blocked in SMM, since V_NMI_MASK is
> > > set despite no NMI in service, we will be able to inject only one NMI by
> > > setting the V_NMI_PENDING.
I believe this one is a non-issue. Like bare metal, KVM only allows one NMI to
be pending if NMIs are blocked.
static void process_nmi(struct kvm_vcpu *vcpu)
{
unsigned limit = 2;
/*
* x86 is limited to one NMI running, and one NMI pending after it.
* If an NMI is already in progress, limit further NMIs to just one.
* Otherwise, allow two (and we'll inject the first one immediately).
*/
if (static_call(kvm_x86_get_nmi_mask)(vcpu) || vcpu->arch.nmi_injected)
limit = 1;
vcpu->arch.nmi_pending += atomic_xchg(&vcpu->arch.nmi_queued, 0);
vcpu->arch.nmi_pending = min(vcpu->arch.nmi_pending, limit);
kvm_make_request(KVM_REQ_EVENT, vcpu);
}
> > Ditto,. HW will collapse the NMI.
>
> Note, this is how bare-metal NMIs are also handled. Multiple NMIs are
> collapsed into a single NMI if they are received while an NMI is currently
> being processed.
prev parent reply other threads:[~2022-11-16 16:59 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-10-27 8:38 [PATCHv5 0/8] Virtual NMI feature Santosh Shukla
2022-10-27 8:38 ` [PATCHv5 1/8] x86/cpu: Add CPUID feature bit for VNMI Santosh Shukla
2022-10-27 8:38 ` [PATCHv5 2/8] KVM: SVM: Add VNMI bit definition Santosh Shukla
2022-10-27 8:38 ` [PATCHv5 3/8] KVM: SVM: Add VNMI support in get/set_nmi_mask Santosh Shukla
2022-10-27 8:38 ` [PATCHv5 4/8] KVM: SVM: Report NMI not allowed when Guest busy handling VNMI Santosh Shukla
2022-10-27 8:38 ` [PATCHv5 5/8] KVM: SVM: Add VNMI support in inject_nmi Santosh Shukla
2022-10-27 8:38 ` [PATCHv5 6/8] KVM: nSVM: implement nested VNMI Santosh Shukla
2022-10-27 8:38 ` [PATCHv5 7/8] KVM: nSVM: emulate VMEXIT_INVALID case for " Santosh Shukla
2022-10-27 8:38 ` [PATCHv5 8/8] KVM: SVM: Enable VNMI feature Santosh Shukla
2022-11-14 8:02 ` [PATCHv5 0/8] Virtual NMI feature Santosh Shukla
2022-11-14 14:31 ` Maxim Levitsky
2022-11-16 5:40 ` Santosh Shukla
2022-11-16 9:21 ` Maxim Levitsky
2022-11-16 15:44 ` Santosh Shukla
2022-11-16 15:55 ` Tom Lendacky
2022-11-16 16:59 ` Sean Christopherson [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=Y3UW672P8ruO48Ct@google.com \
--to=seanjc@google.com \
--cc=jmattson@google.com \
--cc=joro@8bytes.org \
--cc=kvm@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mail@maciej.szmigiero.name \
--cc=mlevitsk@redhat.com \
--cc=pbonzini@redhat.com \
--cc=santosh.shukla@amd.com \
--cc=thomas.lendacky@amd.com \
--cc=vkuznets@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox