diff mbox series

[13/15] softmmu/memory: Disallow short writes

Message ID 20210619172626.875885-14-richard.henderson@linaro.org
State New
Headers show
Series accel/tcg: Fix for #360 and other i/o alignment issues | expand

Commit Message

Richard Henderson June 19, 2021, 5:26 p.m. UTC
Writes smaller than impl.min_access_size would require a
read-modify-write cycle, which could have side effects.

The present behaviour seems to be to extend the current write
to min_access_size.  While we could continue that, so far all
of the instances I have seen have been either device model
errors or the fuzzer intentionally doing bad things.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

---
 softmmu/memory.c | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

-- 
2.25.1
diff mbox series

Patch

diff --git a/softmmu/memory.c b/softmmu/memory.c
index 7373d89600..2fe237327d 100644
--- a/softmmu/memory.c
+++ b/softmmu/memory.c
@@ -548,6 +548,26 @@  static MemTxResult access_with_adjusted_size(hwaddr addr,
     }
 
     /* FIXME: support unaligned access? */
+    /*
+     * Check for a small access.
+     */
+    if (unlikely(size < access_size_min)) {
+        /*
+         * Logically, we cannot support short writes without a read-modify
+         * cycle, and many mmio registers have side-effects on read.
+         * In practice, this appears to be either (1) model error,
+         * or (2) guest error via the fuzzer.
+         */
+        if (write) {
+            qemu_log_mask(LOG_GUEST_ERROR, "%s: Invalid short write: %s "
+                          "hwaddr: 0x%" HWADDR_PRIx " size: %u "
+                          "min: %u max: %u\n", __func__,
+                          memory_region_name(mr), addr, size,
+                          access_size_min, access_size_max);
+            return MEMTX_ERROR;
+        }
+    }
+
     access_size = MAX(MIN(size, access_size_max), access_size_min);
     access_mask = MAKE_64BIT_MASK(0, access_size * 8);
     if (memory_region_big_endian(mr)) {