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)
};