All of lore.kernel.org
 help / color / mirror / Atom feed
From: Sean Christopherson <sean.j.christopherson@intel.com>
To: Paolo Bonzini <pbonzini@redhat.com>
Cc: Sean Christopherson <sean.j.christopherson@intel.com>,
	Vitaly Kuznetsov <vkuznets@redhat.com>,
	Wanpeng Li <wanpengli@tencent.com>,
	Jim Mattson <jmattson@google.com>, Joerg Roedel <joro@8bytes.org>,
	kvm@vger.kernel.org, linux-kernel@vger.kernel.org,
	Oliver Upton <oupton@google.com>, Peter Shier <pshier@google.com>
Subject: [PATCH 12/13] KVM: x86: Replace late check_nested_events() hack with more precise fix
Date: Wed, 22 Apr 2020 19:25:49 -0700	[thread overview]
Message-ID: <20200423022550.15113-13-sean.j.christopherson@intel.com> (raw)
In-Reply-To: <20200423022550.15113-1-sean.j.christopherson@intel.com>

Add a separate hook for checking if interrupt injection is blocked and
use the hook to handle the case where an interrupt arrives between
check_nested_events() and the injection logic.  Drop the retry of
check_nested_events() that hack-a-fixed the same condition.

Blocking injection is also a bit of a hack, e.g. KVM should do exiting
and non-exiting interrupt processing in a single pass, but it's a more
precise hack.  The old comment is also misleading, e.g. KVM_REQ_EVENT is
purely an optimization, setting it on every run loop (which KVM doesn't
do) should not affect functionality, only performance.

Signed-off-by: Sean Christopherson <sean.j.christopherson@intel.com>
---
 arch/x86/include/asm/kvm_host.h |  1 +
 arch/x86/kvm/svm/svm.c          |  1 +
 arch/x86/kvm/vmx/vmx.c          | 13 +++++++++++++
 arch/x86/kvm/x86.c              | 22 ++++------------------
 4 files changed, 19 insertions(+), 18 deletions(-)

diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 787636acd648..16fdeddb4a65 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -1140,6 +1140,7 @@ struct kvm_x86_ops {
 	void (*queue_exception)(struct kvm_vcpu *vcpu);
 	void (*cancel_injection)(struct kvm_vcpu *vcpu);
 	bool (*interrupt_allowed)(struct kvm_vcpu *vcpu);
+	bool (*interrupt_injection_allowed)(struct kvm_vcpu *vcpu);
 	bool (*nmi_allowed)(struct kvm_vcpu *vcpu);
 	bool (*get_nmi_mask)(struct kvm_vcpu *vcpu);
 	void (*set_nmi_mask)(struct kvm_vcpu *vcpu, bool masked);
diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c
index f21f734861dd..6d3ccbfc9e6a 100644
--- a/arch/x86/kvm/svm/svm.c
+++ b/arch/x86/kvm/svm/svm.c
@@ -3993,6 +3993,7 @@ static struct kvm_x86_ops svm_x86_ops __initdata = {
 	.queue_exception = svm_queue_exception,
 	.cancel_injection = svm_cancel_injection,
 	.interrupt_allowed = svm_interrupt_allowed,
+	.interrupt_injection_allowed = svm_interrupt_allowed,
 	.nmi_allowed = svm_nmi_allowed,
 	.get_nmi_mask = svm_get_nmi_mask,
 	.set_nmi_mask = svm_set_nmi_mask,
diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
index 2f8cacb3aa9b..68b3748b5383 100644
--- a/arch/x86/kvm/vmx/vmx.c
+++ b/arch/x86/kvm/vmx/vmx.c
@@ -4550,6 +4550,18 @@ static bool vmx_interrupt_allowed(struct kvm_vcpu *vcpu)
 	return !vmx_interrupt_blocked(vcpu);
 }
 
+static bool vmx_interrupt_injection_allowed(struct kvm_vcpu *vcpu)
+{
+	/*
+	 * An IRQ must not be injected into L2 if it's supposed to VM-Exit,
+	 * e.g. if the IRQ arrived asynchronously after checking nested events.
+	 */
+	if (is_guest_mode(vcpu) && nested_exit_on_intr(vcpu))
+		return false;
+
+	return vmx_interrupt_allowed(vcpu);
+}
+
 static int vmx_set_tss_addr(struct kvm *kvm, unsigned int addr)
 {
 	int ret;
@@ -7823,6 +7835,7 @@ static struct kvm_x86_ops vmx_x86_ops __initdata = {
 	.queue_exception = vmx_queue_exception,
 	.cancel_injection = vmx_cancel_injection,
 	.interrupt_allowed = vmx_interrupt_allowed,
+	.interrupt_injection_allowed = vmx_interrupt_injection_allowed,
 	.nmi_allowed = vmx_nmi_allowed,
 	.get_nmi_mask = vmx_get_nmi_mask,
 	.set_nmi_mask = vmx_set_nmi_mask,
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 7c49a7dc601f..d9d6028a77e0 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -7755,24 +7755,10 @@ static int inject_pending_event(struct kvm_vcpu *vcpu)
 		--vcpu->arch.nmi_pending;
 		vcpu->arch.nmi_injected = true;
 		kvm_x86_ops.set_nmi(vcpu);
-	} else if (kvm_cpu_has_injectable_intr(vcpu)) {
-		/*
-		 * Because interrupts can be injected asynchronously, we are
-		 * calling check_nested_events again here to avoid a race condition.
-		 * See https://lkml.org/lkml/2014/7/2/60 for discussion about this
-		 * proposal and current concerns.  Perhaps we should be setting
-		 * KVM_REQ_EVENT only on certain events and not unconditionally?
-		 */
-		if (is_guest_mode(vcpu) && kvm_x86_ops.check_nested_events) {
-			r = kvm_x86_ops.check_nested_events(vcpu);
-			if (r != 0)
-				return r;
-		}
-		if (kvm_x86_ops.interrupt_allowed(vcpu)) {
-			kvm_queue_interrupt(vcpu, kvm_cpu_get_interrupt(vcpu),
-					    false);
-			kvm_x86_ops.set_irq(vcpu);
-		}
+	} else if (kvm_cpu_has_injectable_intr(vcpu) &&
+		   kvm_x86_ops.interrupt_injection_allowed(vcpu)) {
+		kvm_queue_interrupt(vcpu, kvm_cpu_get_interrupt(vcpu), false);
+		kvm_x86_ops.set_irq(vcpu);
 	}
 
 	return 0;
-- 
2.26.0


  parent reply	other threads:[~2020-04-23  2:26 UTC|newest]

Thread overview: 39+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-04-23  2:25 [PATCH 00/13] KVM: x86: Event fixes and cleanup Sean Christopherson
2020-04-23  2:25 ` [PATCH 01/13] KVM: nVMX: Preserve exception priority irrespective of exiting behavior Sean Christopherson
2020-04-28 18:54   ` Jim Mattson
2020-04-28 20:07     ` Oliver Upton
2020-04-23  2:25 ` [PATCH 02/13] KVM: nVMX: Open a window for pending nested VMX preemption timer Sean Christopherson
2020-04-28 21:39   ` Jim Mattson
2020-04-23  2:25 ` [PATCH 03/13] KVM: x86: Set KVM_REQ_EVENT if run is canceled with req_immediate_exit set Sean Christopherson
2020-04-28 21:41   ` Jim Mattson
2020-04-23  2:25 ` [PATCH 04/13] KVM: x86: Make return for {interrupt_nmi}_allowed() a bool instead of int Sean Christopherson
2020-04-28 21:42   ` Jim Mattson
2020-04-23  2:25 ` [PATCH 05/13] KVM: nVMX: Move nested_exit_on_nmi() to nested.h Sean Christopherson
2020-04-28 21:44   ` Jim Mattson
2020-04-23  2:25 ` [PATCH 06/13] KVM: nVMX: Report NMIs as allowed when in L2 and Exit-on-NMI is set Sean Christopherson
2020-04-28 21:46   ` Jim Mattson
2020-04-23  2:25 ` [PATCH 07/13] KVM: VMX: Split out architectural interrupt/NMI blocking checks Sean Christopherson
2020-04-28 21:57   ` Jim Mattson
2020-04-23  2:25 ` [PATCH 08/13] KVM: nVMX: Preserve IRQ/NMI priority irrespective of exiting behavior Sean Christopherson
2020-04-28 21:58   ` Jim Mattson
2020-04-23  2:25 ` [PATCH 09/13] KVM: nVMX: Prioritize SMI over nested IRQ/NMI Sean Christopherson
2020-04-28 22:04   ` Jim Mattson
2020-04-28 22:59     ` Sean Christopherson
2020-04-28 23:16       ` Jim Mattson
2020-04-29 14:50         ` Sean Christopherson
2020-04-29 20:06           ` Sean Christopherson
2020-04-28 23:23       ` Jim Mattson
2020-04-23  2:25 ` [PATCH 10/13] KVM: x86: WARN on injected+pending exception even in nested case Sean Christopherson
2020-04-28 22:05   ` Jim Mattson
2020-04-23  2:25 ` [PATCH 11/13] KVM: VMX: Use vmx_interrupt_blocked() directly from vmx_handle_exit() Sean Christopherson
2020-04-28 22:07   ` Jim Mattson
2020-04-23  2:25 ` Sean Christopherson [this message]
2020-04-23 11:00   ` [PATCH 12/13] KVM: x86: Replace late check_nested_events() hack with more precise fix Paolo Bonzini
2020-04-28 22:12   ` Jim Mattson
2020-04-28 22:20     ` Sean Christopherson
2020-04-29  8:36       ` Paolo Bonzini
2020-04-29 16:45         ` Sean Christopherson
2020-04-29 16:58           ` Paolo Bonzini
2020-04-29 17:07             ` Sean Christopherson
2020-04-23  2:25 ` [PATCH 13/13] KVM: VMX: Use vmx_get_rflags() to query RFLAGS in vmx_interrupt_blocked() Sean Christopherson
2020-04-28 22:13   ` Jim Mattson

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=20200423022550.15113-13-sean.j.christopherson@intel.com \
    --to=sean.j.christopherson@intel.com \
    --cc=jmattson@google.com \
    --cc=joro@8bytes.org \
    --cc=kvm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=oupton@google.com \
    --cc=pbonzini@redhat.com \
    --cc=pshier@google.com \
    --cc=vkuznets@redhat.com \
    --cc=wanpengli@tencent.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.