public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Ivan Orlov <iorlov@amazon.com>
To: <hpa@zytor.com>, <bp@alien8.de>, <dave.hansen@linux.intel.com>,
	<mingo@redhat.com>, <pbonzini@redhat.com>, <seanjc@google.com>,
	<shuah@kernel.org>, <tglx@linutronix.de>
Cc: Ivan Orlov <iorlov@amazon.com>, <jalliste@amazon.com>,
	<nh-open-source@amazon.com>, <kvm@vger.kernel.org>,
	<linux-kernel@vger.kernel.org>, <linux-kselftest@vger.kernel.org>,
	<x86@kernel.org>
Subject: [PATCH 2/4] KVM: x86: Inject UD when fetching from MMIO
Date: Mon, 23 Sep 2024 14:18:08 +0000	[thread overview]
Message-ID: <20240923141810.76331-3-iorlov@amazon.com> (raw)
In-Reply-To: <20240923141810.76331-1-iorlov@amazon.com>

Currently, we simply return a KVM internal error with suberror =
KVM_INTERNAL_ERROR_EMULATION if the guest tries to fetch instruction
from MMIO range as we simply can't decode it.

I believe it is not the best thing to do, considering that

  1) we don't give enough information to VMM about the issue we faced
  2) the issue is triggered by the guest itself, so it is not the KVM
     "internal" error.

Inject the #UD into the guest instead and resume it's execution without
giving an error to VMM, as it would be if we can't find a valid
instruction at MMIO address.

Signed-off-by: Ivan Orlov <iorlov@amazon.com>
---
 arch/x86/kvm/emulate.c     | 3 +++
 arch/x86/kvm/kvm_emulate.h | 1 +
 arch/x86/kvm/x86.c         | 7 ++++++-
 3 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index e72aed25d721..d610c47fa1f4 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -4742,10 +4742,13 @@ int x86_decode_insn(struct x86_emulate_ctxt *ctxt, void *insn, int insn_len, int
 	ctxt->fetch.end = ctxt->fetch.data + insn_len;
 	ctxt->opcode_len = 1;
 	ctxt->intercept = x86_intercept_none;
+	ctxt->is_mmio_fetch = false;
 	if (insn_len > 0)
 		memcpy(ctxt->fetch.data, insn, insn_len);
 	else {
 		rc = __do_insn_fetch_bytes(ctxt, 1);
+		if (rc == X86EMUL_IO_NEEDED)
+			ctxt->is_mmio_fetch = true;
 		if (rc != X86EMUL_CONTINUE)
 			goto done;
 	}
diff --git a/arch/x86/kvm/kvm_emulate.h b/arch/x86/kvm/kvm_emulate.h
index 55a18e2f2dcd..46c0d1111ec1 100644
--- a/arch/x86/kvm/kvm_emulate.h
+++ b/arch/x86/kvm/kvm_emulate.h
@@ -362,6 +362,7 @@ struct x86_emulate_ctxt {
 	u8 seg_override;
 	u64 d;
 	unsigned long _eip;
+	bool is_mmio_fetch;
 
 	/* Here begins the usercopy section. */
 	struct operand src;
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index c983c8e434b8..4fb57280ec7b 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -8857,7 +8857,12 @@ static int handle_emulation_failure(struct kvm_vcpu *vcpu, int emulation_type)
 
 	kvm_queue_exception(vcpu, UD_VECTOR);
 
-	if (!is_guest_mode(vcpu) && kvm_x86_call(get_cpl)(vcpu) == 0) {
+	/*
+	 * Don't return an internal error if the emulation error is caused by a fetch from MMIO
+	 * address. Injecting a #UD should be enough.
+	 */
+	if (!is_guest_mode(vcpu) && kvm_x86_call(get_cpl)(vcpu) == 0 &&
+	    !vcpu->arch.emulate_ctxt->is_mmio_fetch) {
 		prepare_emulation_ctxt_failure_exit(vcpu);
 		return 0;
 	}
-- 
2.43.0


  parent reply	other threads:[~2024-09-23 14:18 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-09-23 14:18 [PATCH 0/4] Process some MMIO-related errors without KVM exit Ivan Orlov
2024-09-23 14:18 ` [PATCH 1/4] KVM: vmx, svm, mmu: Fix MMIO during event delivery handling Ivan Orlov
2024-09-23 14:18 ` Ivan Orlov [this message]
2024-09-23 14:18 ` [PATCH 3/4] selftests: KVM: Change expected exit code in test_zero_memory_regions Ivan Orlov
2024-09-23 14:18 ` [PATCH 4/4] selftests: KVM: Add new test for faulty mmio usage Ivan Orlov
2024-09-23 17:04 ` [PATCH 0/4] Process some MMIO-related errors without KVM exit Sean Christopherson
2024-09-23 19:38   ` Allister, Jack
2024-09-23 21:46     ` Sean Christopherson
2024-09-24  9:54       ` Ivan Orlov
2024-09-26  0:06         ` Sean Christopherson
2024-09-27 12:13           ` Ivan Orlov
2024-09-24  7:38     ` Sean Christopherson

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=20240923141810.76331-3-iorlov@amazon.com \
    --to=iorlov@amazon.com \
    --cc=bp@alien8.de \
    --cc=dave.hansen@linux.intel.com \
    --cc=hpa@zytor.com \
    --cc=jalliste@amazon.com \
    --cc=kvm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-kselftest@vger.kernel.org \
    --cc=mingo@redhat.com \
    --cc=nh-open-source@amazon.com \
    --cc=pbonzini@redhat.com \
    --cc=seanjc@google.com \
    --cc=shuah@kernel.org \
    --cc=tglx@linutronix.de \
    --cc=x86@kernel.org \
    /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