All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Maciej S. Szmigiero" <mail@maciej.szmigiero.name>
To: Paolo Bonzini <pbonzini@redhat.com>
Cc: Sean Christopherson <seanjc@google.com>,
	Vitaly Kuznetsov <vkuznets@redhat.com>,
	Wanpeng Li <wanpengli@tencent.com>,
	Jim Mattson <jmattson@google.com>, Joerg Roedel <joro@8bytes.org>,
	Tom Lendacky <thomas.lendacky@amd.com>,
	Brijesh Singh <brijesh.singh@amd.com>,
	Jon Grimm <Jon.Grimm@amd.com>,
	David Kaplan <David.Kaplan@amd.com>,
	Boris Ostrovsky <boris.ostrovsky@oracle.com>,
	Liam Merwick <liam.merwick@oracle.com>,
	kvm@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: [PATCH 4/5] KVM: nSVM: Restore next_rip when doing L1 -> L2 event re-injection
Date: Thu, 10 Mar 2022 22:38:40 +0100	[thread overview]
Message-ID: <a5380706e5a1679bf8e5967252335e1f2167065f.1646944472.git.maciej.szmigiero@oracle.com> (raw)
In-Reply-To: <cover.1646944472.git.maciej.szmigiero@oracle.com>

From: "Maciej S. Szmigiero" <maciej.szmigiero@oracle.com>

According to APM 15.7.1 "State Saved on Exit" the next_rip field can be
zero after a VMEXIT in some cases.
Yet, it is used by the CPU for the return address pushed on stack when
injecting INT3 or INTO exception or a software interrupt.

Restore this field to the L1-provided value if zeroed by the CPU when
re-injecting a L1-provided event into L2.

Signed-off-by: Maciej S. Szmigiero <maciej.szmigiero@oracle.com>
---
 arch/x86/kvm/svm/svm.c | 43 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 43 insertions(+)

diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c
index 5b128baa5e57..760dd0e070ea 100644
--- a/arch/x86/kvm/svm/svm.c
+++ b/arch/x86/kvm/svm/svm.c
@@ -385,6 +385,44 @@ static int svm_skip_emulated_instruction(struct kvm_vcpu *vcpu)
 	return 1;
 }
 
+/*
+ * According to APM 15.7.1 "State Saved on Exit" the next_rip field can
+ * be zero after a VMEXIT in some cases.
+ * Yet, it is used by the CPU for the return address pushed on stack when
+ * injecting INT3 or INTO exception or a software interrupt.
+ *
+ * Restore this field to the L1-provided value if zeroed by the CPU when
+ * re-injecting a L1-provided event into L2.
+ */
+static void maybe_fixup_next_rip(struct kvm_vcpu *vcpu, bool uses_err)
+{
+	struct vcpu_svm *svm = to_svm(vcpu);
+	u32 err_vmcb = uses_err ? svm->vmcb->control.event_inj_err : 0;
+	u32 err_inject = uses_err ? svm->nested.ctl.event_inj_err : 0;
+
+	/* No nRIP Save feature? Then nothing to fix up. */
+	if (!nrips)
+		return;
+
+	/* The fix only applies to event injection into a L2. */
+	if (!is_guest_mode(vcpu))
+		return;
+
+	/*
+	 * If the current next_rip field is already non-zero assume the CPU had
+	 * returned the correct address during the last VMEXIT.
+	 */
+	if (svm->vmcb->control.next_rip)
+		return;
+
+	/* Is this a L1 -> L2 event re-injection? */
+	if (!event_inj_same(svm->vmcb->control.event_inj, err_vmcb,
+			    svm->nested.ctl.event_inj, err_inject))
+		return;
+
+	svm->vmcb->control.next_rip = svm->nested.ctl.next_rip;
+}
+
 static void svm_queue_exception(struct kvm_vcpu *vcpu)
 {
 	struct vcpu_svm *svm = to_svm(vcpu);
@@ -415,6 +453,9 @@ static void svm_queue_exception(struct kvm_vcpu *vcpu)
 		| (has_error_code ? SVM_EVTINJ_VALID_ERR : 0)
 		| SVM_EVTINJ_TYPE_EXEPT;
 	svm->vmcb->control.event_inj_err = error_code;
+
+	if (kvm_exception_is_soft(nr))
+		maybe_fixup_next_rip(vcpu, true);
 }
 
 static void svm_init_erratum_383(void)
@@ -3331,6 +3372,8 @@ static void svm_inject_irq(struct kvm_vcpu *vcpu)
 		SVM_EVTINJ_VALID;
 	if (vcpu->arch.interrupt.soft) {
 		svm->vmcb->control.event_inj |= SVM_EVTINJ_TYPE_SOFT;
+
+		maybe_fixup_next_rip(vcpu, false);
 	} else {
 		svm->vmcb->control.event_inj |= SVM_EVTINJ_TYPE_INTR;
 	}

  parent reply	other threads:[~2022-03-10 21:39 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-03-10 21:38 [PATCH 0/5] nSVM: L1 -> L2 event injection fixes and a self-test Maciej S. Szmigiero
2022-03-10 21:38 ` [PATCH 1/5] KVM: nSVM: Sync next_rip field from vmcb12 to vmcb02 Maciej S. Szmigiero
2022-04-01 18:32   ` Sean Christopherson
2022-04-01 19:08     ` Maciej S. Szmigiero
2022-04-01 21:51       ` Sean Christopherson
2022-04-04  9:50         ` Maxim Levitsky
2022-03-10 21:38 ` [PATCH 2/5] KVM: SVM: Downgrade BUG_ON() to WARN_ON() in svm_inject_irq() Maciej S. Szmigiero
2022-04-04  9:50   ` Maxim Levitsky
2022-03-10 21:38 ` [PATCH 3/5] KVM: nSVM: Don't forget about L1-injected events Maciej S. Szmigiero
2022-03-30 21:59   ` Sean Christopherson
2022-03-30 22:16     ` Maciej S. Szmigiero
2022-03-30 23:20       ` Sean Christopherson
2022-03-31 23:09         ` Maciej S. Szmigiero
2022-04-01  0:08           ` Sean Christopherson
2022-04-01 16:05             ` Maciej S. Szmigiero
2022-04-01 22:07               ` Sean Christopherson
2022-04-04  9:53   ` Maxim Levitsky
2022-04-04 21:05     ` Maciej S. Szmigiero
2022-03-10 21:38 ` Maciej S. Szmigiero [this message]
2022-03-10 21:38 ` [PATCH 5/5] KVM: selftests: nSVM: Add svm_nested_soft_inject_test Maciej S. Szmigiero

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=a5380706e5a1679bf8e5967252335e1f2167065f.1646944472.git.maciej.szmigiero@oracle.com \
    --to=mail@maciej.szmigiero.name \
    --cc=David.Kaplan@amd.com \
    --cc=Jon.Grimm@amd.com \
    --cc=boris.ostrovsky@oracle.com \
    --cc=brijesh.singh@amd.com \
    --cc=jmattson@google.com \
    --cc=joro@8bytes.org \
    --cc=kvm@vger.kernel.org \
    --cc=liam.merwick@oracle.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=pbonzini@redhat.com \
    --cc=seanjc@google.com \
    --cc=thomas.lendacky@amd.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.