From: "Doru Blânzeanu" <dblanzeanu@linux.microsoft.com>
To: qemu-devel@nongnu.org
Cc: Wei Liu <wei.liu@kernel.org>,
Magnus Kulke <magnuskulke@linux.microsoft.com>
Subject: [PATCH 1/1] target/i386/mshv: fix read/write memory across the page boundary
Date: Thu, 9 Apr 2026 20:53:34 +0300 [thread overview]
Message-ID: <20260409175334.181249-2-dblanzeanu@linux.microsoft.com> (raw)
In-Reply-To: <20260409175334.181249-1-dblanzeanu@linux.microsoft.com>
Previously, read_memory and write_memory performed a single GVA-to-GPA
translation for the entire buffer. If the buffer spanned a page
boundary, the translated GPA was only valid for the first page, causing
incorrect reads/writes for the remainder.
Fix both functions to loop over pages, translating and accessing each
page-aligned chunk separately.
Signed-off-by: Doru Blânzeanu <dblanzeanu@linux.microsoft.com>
---
target/i386/mshv/mshv-cpu.c | 71 +++++++++++++++++++++++++++----------
1 file changed, 52 insertions(+), 19 deletions(-)
diff --git a/target/i386/mshv/mshv-cpu.c b/target/i386/mshv/mshv-cpu.c
index 2bc978deb2..afdb6b6e29 100644
--- a/target/i386/mshv/mshv-cpu.c
+++ b/target/i386/mshv/mshv-cpu.c
@@ -1316,21 +1316,38 @@ static int read_memory(const CPUState *cpu, uint64_t initial_gva,
{
int ret;
uint64_t gpa, flags;
-
- if (gva == initial_gva) {
- gpa = initial_gpa;
- } else {
- flags = HV_TRANSLATE_GVA_VALIDATE_READ;
- ret = translate_gva(cpu, gva, &gpa, flags);
- if (ret < 0) {
- return -1;
+ uint64_t cur_gva = gva;
+ size_t page_left, chunk;
+ uint8_t *cur_data = data;
+
+ /*
+ * If the read spans multiple pages,
+ * we need to translate and read each page separately
+ */
+ while (len > 0) {
+ page_left = HV_HYP_PAGE_SIZE - (cur_gva & (HV_HYP_PAGE_SIZE - 1));
+ chunk = MIN(len, page_left);
+
+ if (cur_gva == initial_gva) {
+ gpa = initial_gpa;
+ } else {
+ flags = HV_TRANSLATE_GVA_VALIDATE_READ;
+ ret = translate_gva(cpu, cur_gva, &gpa, flags);
+ if (ret < 0) {
+ return -1;
+ }
}
- ret = mshv_guest_mem_read(gpa, data, len, false, false);
+ ret = mshv_guest_mem_read(gpa, cur_data, chunk,
+ false, false);
if (ret < 0) {
error_report("failed to read guest mem");
return -1;
}
+
+ cur_gva += chunk;
+ cur_data += chunk;
+ len -= chunk;
}
return 0;
@@ -1341,18 +1358,34 @@ static int write_memory(const CPUState *cpu, uint64_t gva, const uint8_t *data,
{
int ret;
uint64_t gpa, flags;
+ uint64_t cur_gva = gva;
+ size_t page_left, chunk;
+ const uint8_t *cur_data = data;
+
+ /*
+ * If the write spans multiple pages,
+ * we need to translate and write each page separately
+ */
+ while (len > 0) {
+ page_left = HV_HYP_PAGE_SIZE - (cur_gva & (HV_HYP_PAGE_SIZE - 1));
+ chunk = MIN(len, page_left);
+
+ flags = HV_TRANSLATE_GVA_VALIDATE_WRITE;
+ ret = translate_gva(cpu, cur_gva, &gpa, flags);
+ if (ret < 0) {
+ error_report("failed to translate gva to gpa");
+ return -1;
+ }
- flags = HV_TRANSLATE_GVA_VALIDATE_WRITE;
- ret = translate_gva(cpu, gva, &gpa, flags);
- if (ret < 0) {
- error_report("failed to translate gva to gpa");
- return -1;
- }
+ ret = mshv_guest_mem_write(gpa, cur_data, chunk, false);
+ if (ret != MEMTX_OK) {
+ error_report("failed to write to mmio");
+ return -1;
+ }
- ret = mshv_guest_mem_write(gpa, data, len, false);
- if (ret != MEMTX_OK) {
- error_report("failed to write to mmio");
- return -1;
+ cur_gva += chunk;
+ cur_data += chunk;
+ len -= chunk;
}
return 0;
--
2.53.0
next prev parent reply other threads:[~2026-04-09 17:54 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-04-09 17:53 [PATCH 0/1] target/i386/mshv: fix read and write memory across the page boundary Doru Blânzeanu
2026-04-09 17:53 ` Doru Blânzeanu [this message]
2026-04-09 23:38 ` [PATCH 1/1] target/i386/mshv: fix read/write " Mohamed Mediouni
2026-04-10 14:52 ` Magnus Kulke
2026-04-13 11:57 ` Magnus Kulke
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=20260409175334.181249-2-dblanzeanu@linux.microsoft.com \
--to=dblanzeanu@linux.microsoft.com \
--cc=magnuskulke@linux.microsoft.com \
--cc=qemu-devel@nongnu.org \
--cc=wei.liu@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 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.