public inbox for kvm@vger.kernel.org
 help / color / mirror / Atom feed
From: "Radim Krčmář" <rkrcmar@redhat.com>
To: Paolo Bonzini <pbonzini@redhat.com>
Cc: Liran Alon <liran.alon@oracle.com>,
	kvm@vger.kernel.org, jmattson@google.com, wanpeng.li@hotmail.com,
	idan.brown@oracle.com,
	Krish Sadhukhan <krish.sadhukhan@oracle.com>
Subject: Re: [PATCH] KVM: nVMX: Fix races when sending nested PI while dest enters/leaves L2
Date: Fri, 10 Nov 2017 19:06:19 +0100	[thread overview]
Message-ID: <20171110180616.GE15561@flask> (raw)
In-Reply-To: <a9bf526f-032d-0515-0d69-e56425943251@redhat.com>

2017-11-10 18:06+0100, Paolo Bonzini:
> On 09/11/2017 19:27, Liran Alon wrote:
> > Consider the following scenario:
> > 1. CPU A calls vmx_deliver_nested_posted_interrupt() to send an IPI
> > to CPU B via virtual posted-interrupt mechanism.
> > 2. CPU B is currently executing L2 guest.
> > 3. vmx_deliver_nested_posted_interrupt() calls
> > kvm_vcpu_trigger_posted_interrupt() which will note that
> > vcpu->mode == IN_GUEST_MODE.
> > 4. Assume that before CPU A sends the physical POSTED_INTR_NESTED_VECTOR
> > IPI, CPU B exits from L2 to L0 during event-delivery
> > (valid IDT-vectoring-info).
> > 5. CPU A now sends the physical IPI. The IPI is received in host and
> > it's handler (smp_kvm_posted_intr_nested_ipi()) does nothing.
> > 6. Assume that before CPU A sets pi_pending=true and KVM_REQ_EVENT,
> > CPU B continues to run in L0 and reach vcpu_enter_guest(). As
> > KVM_REQ_EVENT is not set yet, vcpu_enter_guest() will continue and resume
> > L2 guest.
> > 7. At this point, CPU A sets pi_pending=true and KVM_REQ_EVENT but
> > it's too late! CPU B already entered L2 and KVM_REQ_EVENT will only be
> > consumed at next L2 entry!
> 
> The bug is real (great debugging!) but I think the fix is wrong.  The
> basic issue is that we're not kicking the VCPU, so this should also fix it:
> 
> 	/* the PIR and ON have been set by L1. */
> 	if (!kvm_vcpu_trigger_posted_interrupt(vcpu, true)) {

This would still fail on the exiting case.

If one VCPU was just after a VM exit, then the sender would see it
IN_GUEST_MODE, send the posted notification and return true, but the
notification would do nothing and we didn't set vmx->nested.pi_pending =
true, so the interrupt would not get handled until the next posted
notification or nested VM entry.

> 		/*
> 		 * If a posted intr is not recognized by hardware,
> 		 * we will accomplish it in the next vmentry.
> 		 */
> 		vmx->nested.pi_pending = true;
> 		kvm_make_request(KVM_REQ_EVENT, vcpu);
> 		kvm_vcpu_kick(vcpu);
> 	}
> 
> See the comments around the setting of IN_GUEST_MODE, introduced by
> commit b95234c84004 ("kvm: x86: do not use KVM_REQ_EVENT for APICv
> interrupt injection", 2017-02-15).
> 
> Even though nested PI must use KVM_REQ_EVENT, the reasoning behind the
> ordering of cli and vcpu->mode = IN_GUEST_MODE should hold in both cases.

I think the fix is correct, but the code is using very awkward
synchronization through vmx->nested.pi_pending and slaps KVM_REQ_EVENT
on top.
If we checked vmx->nested.pi_pending after cli, we could get rid of
KVM_REQ_EVENT and if we want to support nested posted interrupts from
PCI devices, we should explicitly check for pi.on during VM entry.

Kicks do not seem necessary as the only case where we need the kick is
the same case where kvm_vcpu_trigger_posted_interrupt() should just
deliver the interrupt.

  reply	other threads:[~2017-11-10 18:06 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-11-09 18:27 [PATCH] KVM: nVMX: Fix races when sending nested PI while dest enters/leaves L2 Liran Alon
2017-11-10 17:06 ` Paolo Bonzini
2017-11-10 18:06   ` Radim Krčmář [this message]
2017-11-10 20:40     ` Liran Alon
2017-11-10 21:24       ` Radim Krčmář
2017-11-10 21:30         ` Paolo Bonzini
2017-11-10 21:37     ` Paolo Bonzini
2017-11-10 22:30       ` Radim Krčmář
2017-11-10 22:47         ` Liran Alon
2017-11-10 22:51           ` Paolo Bonzini
2017-11-10 22:59             ` Liran Alon
2017-11-10 22:37       ` Liran Alon
2017-11-16 17:37         ` Radim Krčmář
2017-11-16 18:36           ` Liran Alon
2017-11-16 19:47             ` Paolo Bonzini

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=20171110180616.GE15561@flask \
    --to=rkrcmar@redhat.com \
    --cc=idan.brown@oracle.com \
    --cc=jmattson@google.com \
    --cc=krish.sadhukhan@oracle.com \
    --cc=kvm@vger.kernel.org \
    --cc=liran.alon@oracle.com \
    --cc=pbonzini@redhat.com \
    --cc=wanpeng.li@hotmail.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