From: Sean Christopherson <seanjc@google.com>
To: Sean Christopherson <seanjc@google.com>,
Paolo Bonzini <pbonzini@redhat.com>,
Kiryl Shutsemau <kas@kernel.org>
Cc: kvm@vger.kernel.org, x86@kernel.org, linux-coco@lists.linux.dev,
linux-kernel@vger.kernel.org,
Yashu Zhang <zhangjiaji1@huawei.com>,
Rick Edgecombe <rick.p.edgecombe@intel.com>,
Binbin Wu <binbin.wu@linux.intel.com>,
Xiaoyao Li <xiaoyao.li@intel.com>,
Tom Lendacky <thomas.lendacky@amd.com>,
Michael Roth <michael.roth@amd.com>
Subject: [PATCH 05/14] KVM: x86: Open code read vs. write userspace MMIO exits in emulator_read_write()
Date: Tue, 24 Feb 2026 17:20:40 -0800 [thread overview]
Message-ID: <20260225012049.920665-6-seanjc@google.com> (raw)
In-Reply-To: <20260225012049.920665-1-seanjc@google.com>
Open code the differences in read vs. write userspace MMIO exits instead
of burying three lines of code behind indirect callbacks, as splitting the
logic makes it extremely hard to track that KVM's handling of reads vs.
write is _significantly_ different. Add a comment to explain why the
semantics are different, and how on earth an MMIO write ends up triggering
an exit to userspace.
No functional change intended.
Signed-off-by: Sean Christopherson <seanjc@google.com>
---
arch/x86/kvm/x86.c | 33 +++++++++++++--------------------
1 file changed, 13 insertions(+), 20 deletions(-)
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 7cbd6f7d8578..5fde5bb010e7 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -8116,8 +8116,6 @@ struct read_write_emulator_ops {
void *val, int bytes);
int (*read_write_mmio)(struct kvm_vcpu *vcpu, gpa_t gpa,
int bytes, void *val);
- int (*read_write_exit_mmio)(struct kvm_vcpu *vcpu, gpa_t gpa,
- void *val, int bytes);
bool write;
};
@@ -8139,31 +8137,14 @@ static int write_mmio(struct kvm_vcpu *vcpu, gpa_t gpa, int bytes, void *val)
return vcpu_mmio_write(vcpu, gpa, bytes, val);
}
-static int read_exit_mmio(struct kvm_vcpu *vcpu, gpa_t gpa,
- void *val, int bytes)
-{
- return X86EMUL_IO_NEEDED;
-}
-
-static int write_exit_mmio(struct kvm_vcpu *vcpu, gpa_t gpa,
- void *val, int bytes)
-{
- struct kvm_mmio_fragment *frag = &vcpu->mmio_fragments[0];
-
- memcpy(vcpu->run->mmio.data, frag->data, min(8u, frag->len));
- return X86EMUL_CONTINUE;
-}
-
static const struct read_write_emulator_ops read_emultor = {
.read_write_emulate = read_emulate,
.read_write_mmio = vcpu_mmio_read,
- .read_write_exit_mmio = read_exit_mmio,
};
static const struct read_write_emulator_ops write_emultor = {
.read_write_emulate = write_emulate,
.read_write_mmio = write_mmio,
- .read_write_exit_mmio = write_exit_mmio,
.write = true,
};
@@ -8296,7 +8277,19 @@ static int emulator_read_write(struct x86_emulate_ctxt *ctxt,
vcpu->run->exit_reason = KVM_EXIT_MMIO;
vcpu->run->mmio.phys_addr = frag->gpa;
- return ops->read_write_exit_mmio(vcpu, frag->gpa, val, bytes);
+ /*
+ * For MMIO reads, stop emulating and immediately exit to userspace, as
+ * KVM needs the value to correctly emulate the instruction. For MMIO
+ * writes, continue emulating as the write to MMIO is a side effect for
+ * all intents and purposes. KVM will still exit to userspace, but
+ * after completing emulation (see the check on vcpu->mmio_needed in
+ * x86_emulate_instruction()).
+ */
+ if (!ops->write)
+ return X86EMUL_IO_NEEDED;
+
+ memcpy(vcpu->run->mmio.data, frag->data, min(8u, frag->len));
+ return X86EMUL_CONTINUE;
}
static int emulator_read_emulated(struct x86_emulate_ctxt *ctxt,
--
2.53.0.414.gf7e9f6c205-goog
next prev parent reply other threads:[~2026-02-25 1:21 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-02-25 1:20 [PATCH 00/14] KVM: x86: Emulator MMIO fix and cleanups Sean Christopherson
2026-02-25 1:20 ` [PATCH 01/14] KVM: x86: Use scratch field in MMIO fragment to hold small write values Sean Christopherson
2026-02-25 1:20 ` [PATCH 02/14] KVM: x86: Open code handling of completed MMIO reads in emulator_read_write() Sean Christopherson
2026-02-25 1:20 ` [PATCH 03/14] KVM: x86: Trace unsatisfied MMIO reads on a per-page basis Sean Christopherson
2026-02-25 1:20 ` [PATCH 04/14] KVM: x86: Use local MMIO fragment variable to clean up emulator_read_write() Sean Christopherson
2026-02-25 1:20 ` Sean Christopherson [this message]
2026-02-25 1:20 ` [PATCH 06/14] KVM: x86: Move MMIO write tracing into vcpu_mmio_write() Sean Christopherson
2026-02-25 1:20 ` [PATCH 07/14] KVM: x86: Harden SEV-ES MMIO against on-stack use-after-free Sean Christopherson
2026-02-25 1:20 ` [PATCH 08/14] KVM: x86: Dedup kvm_sev_es_mmio_{read,write}() Sean Christopherson
2026-02-25 1:20 ` [PATCH 09/14] KVM: x86: Consolidate SEV-ES MMIO emulation into a single public API Sean Christopherson
2026-02-25 1:20 ` [PATCH 10/14] KVM: x86: Bury emulator read/write ops in emulator_{read,write}_emulated() Sean Christopherson
2026-02-25 1:20 ` [PATCH 11/14] KVM: x86: Fold emulator_write_phys() into write_emulate() Sean Christopherson
2026-02-25 1:20 ` [PATCH 12/14] KVM: x86: Rename .read_write_emulate() to .read_write_guest() Sean Christopherson
2026-02-25 1:20 ` [PATCH 13/14] KVM: x86: Don't panic the kernel if completing userspace I/O / MMIO goes sideways Sean Christopherson
2026-02-25 1:20 ` [PATCH 14/14] KVM: x86: Add helpers to prepare kvm_run for userspace MMIO exit Sean Christopherson
2026-02-25 17:32 ` Edgecombe, Rick P
2026-02-25 19:22 ` Sean Christopherson
2026-03-03 2:24 ` Sean Christopherson
2026-03-03 19:21 ` Edgecombe, Rick P
2026-03-03 19:44 ` Sean Christopherson
2026-03-03 19:51 ` Edgecombe, Rick P
2026-02-25 17:32 ` [PATCH 00/14] KVM: x86: Emulator MMIO fix and cleanups Edgecombe, Rick P
2026-02-25 20:19 ` Tom Lendacky
2026-02-27 20:19 ` Tom Lendacky
2026-03-05 17:07 ` 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=20260225012049.920665-6-seanjc@google.com \
--to=seanjc@google.com \
--cc=binbin.wu@linux.intel.com \
--cc=kas@kernel.org \
--cc=kvm@vger.kernel.org \
--cc=linux-coco@lists.linux.dev \
--cc=linux-kernel@vger.kernel.org \
--cc=michael.roth@amd.com \
--cc=pbonzini@redhat.com \
--cc=rick.p.edgecombe@intel.com \
--cc=thomas.lendacky@amd.com \
--cc=x86@kernel.org \
--cc=xiaoyao.li@intel.com \
--cc=zhangjiaji1@huawei.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