On 11/3/26 13:19, Philippe Mathieu-Daudé wrote:
On 11/3/26 12:59, Djordje Todorovic wrote:
The subpage memory region wrapper dispatches MMIO accesses through
flatview_read/write, which re-enters memory_region_dispatch_read/write
on the underlying device MR. The inner dispatch uses size_memop() which
strips endianness bits (effectively MO_LE), causing adjust_endianness to
apply a byte-swap for DEVICE_NATIVE_ENDIAN devices on big-endian targets.
The outer dispatch's adjust_endianness then sees matching endianness
(MO_BE == devend_BE) and does nothing, leaving the data incorrectly swapped.

Fix by changing subpage_ops from DEVICE_NATIVE_ENDIAN to DEVICE_LITTLE_ENDIAN.
This matches the implicit LE semantics of size_memop() used in the inner
dispatch, so the outer adjust_endianness correctly compensates with a
second swap, yielding the correct net result.

For little-endian targets, DEVICE_NATIVE_ENDIAN already equals LE, so
this change has zero behavioral impact.
---
  system/physmem.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/system/physmem.c b/system/physmem.c
index 2fb0c25c93..5d917482eb 100644
--- a/system/physmem.c
+++ b/system/physmem.c
@@ -2929,7 +2929,7 @@ static const MemoryRegionOps subpage_ops = {
      .valid.min_access_size = 1,
      .valid.max_access_size = 8,
      .valid.accepts = subpage_accepts,
-    .endianness = DEVICE_NATIVE_ENDIAN,
+    .endianness = DEVICE_LITTLE_ENDIAN,

NAck, this likely break big-endian hosts.

(see also https://lore.kernel.org/qemu-devel/[email protected]/ and Paolo's response)

  };



Reply via email to