All of lore.kernel.org
 help / color / mirror / Atom feed
From: Liran Alon <liran.alon@oracle.com>
To: pbonzini@redhat.com, rkrcmar@redhat.com, kvm@vger.kernel.org
Cc: jmattson@google.com, idan.brown@oracle.com,
	Liran Alon <liran.alon@oracle.com>,
	Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Subject: [PATCH 4/4] KVM: nVMX: APICv: Always sync PIR to Virtual-APIC-Page on processing KVM_REQ_EVENT
Date: Sun,  5 Nov 2017 16:07:46 +0200	[thread overview]
Message-ID: <1509890866-8736-5-git-send-email-liran.alon@oracle.com> (raw)
In-Reply-To: <1509890866-8736-1-git-send-email-liran.alon@oracle.com>

Consider the case L2 exits to L0 during event-delivery.
In this case, vmx_complete_interrupts() will see IDT-vectoring-info is
valid and therefore update KVM structs for event reinjection on next L2
resume.

Assume that before L0 reaches vcpu_enter_guest(), another L1 CPU sends
an IPI via virtual-posted-interrupts. That CPU will write a new vector
to destination nested.pi_desc->pir and then will trigger an
IPI with vector nested.posted_intr_nv. This will reach
vmx_deliver_nested_posted_interrupt() which won't send a physical IPI
(as vcpu->mode != IN_GUEST_MODE) but instead just signal
nested.pi_pending=true and set KVM_REQ_EVENT.

When destination CPU will reach vcpu_enter_guest(), it will consume the
KVM_REQ_EVENT and call inject_pending_event() which will call
check_nested_events(). However, because we have an event for reinjection
to L2, vmx_check_nested_events() will return before calling
vmx_complete_nested_posted_interrupt()! Therefore, not updating
L1 virtual-apic-page and vmcs02's RVI.

Assume that at this point we exit L2 and some L1
interrupt is raised afterwards (For example, another L1 CPU IPI).
We will reach again vcpu_enter_guest() and call check_nested_events()
that will exit from L2 to L1 due to pending interrupt and return from
check_nested_events(). Again, without calling
vmx_complete_nested_posted_interrupts()!
At this point KVM_REQ_EVENT was already consumed and therefore cleared.

When L1 will again VMRESUME into L2, it will run L2 without updated
virtual-apic-page, with bad RVI and with PIR.ON set. Which is of course
a bug...

Fix this entire complex issue by just make vmx_check_nested_events()
always call vmx_complete_nested_posted_interrupt().

Fixes: 705699a13994 ("KVM: nVMX: Enable nested posted interrupt processing")

Signed-off-by: Liran Alon <liran.alon@oracle.com>
Reviewed-by: Nikita Leshenko <nikita.leshchenko@oracle.com>
Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
---
 arch/x86/kvm/vmx.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index c440df4a1604..d1981620c13a 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -11029,6 +11029,8 @@ static int vmx_check_nested_events(struct kvm_vcpu *vcpu, bool external_intr)
 	bool block_nested_events =
 	    vmx->nested.nested_run_pending || kvm_event_needs_reinjection(vcpu);
 
+	vmx_complete_nested_posted_interrupt(vcpu);
+
 	if (vcpu->arch.exception.pending &&
 		nested_vmx_check_exception(vcpu, &exit_qual)) {
 		if (block_nested_events)
@@ -11069,7 +11071,6 @@ static int vmx_check_nested_events(struct kvm_vcpu *vcpu, bool external_intr)
 		return 0;
 	}
 
-	vmx_complete_nested_posted_interrupt(vcpu);
 	return 0;
 }
 
-- 
1.9.1

  parent reply	other threads:[~2017-11-05 14:08 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-11-05 14:07 [PATCH 0/4] KVM: nVMX: Fix pending event injection on nested scenarios Liran Alon
2017-11-05 14:07 ` [PATCH 1/4] KVM: nVMX: Fix vmx_check_nested_events() return value in case an event was reinjected to L2 Liran Alon
2017-11-10 21:44   ` Radim Krčmář
2017-11-05 14:07 ` [PATCH 2/4] KVM: nVMX: Require immediate-exit when event reinjected to L2 and L1 event pending Liran Alon
2017-11-10 23:26   ` Paolo Bonzini
2017-11-11  1:44     ` Liran Alon
2017-11-13  8:38       ` Paolo Bonzini
2017-11-05 14:07 ` [PATCH 3/4] KVM: nVMX: Optimization: Dont set KVM_REQ_EVENT when VMExit with nested_run_pending Liran Alon
2017-11-05 14:07 ` Liran Alon [this message]
2017-11-07 14:25 ` [PATCH 0/4] KVM: nVMX: Fix pending event injection on nested scenarios Paolo Bonzini
2017-11-08  0:40   ` Liran Alon

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=1509890866-8736-5-git-send-email-liran.alon@oracle.com \
    --to=liran.alon@oracle.com \
    --cc=idan.brown@oracle.com \
    --cc=jmattson@google.com \
    --cc=konrad.wilk@oracle.com \
    --cc=kvm@vger.kernel.org \
    --cc=pbonzini@redhat.com \
    --cc=rkrcmar@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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.