For targets compiled as little-endian but supporting runtime big-endian
mode (e.g. RISC-V with big-endian=true), virtio_access_is_big_endian()
unconditionally returned false. This caused legacy virtio config space
values to be stored in LE byte order even when the guest runs in BE mode,
leading to byte-swapped config reads (e.g. virtio-blk block size 512
read as 131072).
Use target_big_endian() in the #else branch to detect runtime endianness.
For LE targets that are truly LE, target_big_endian() returns false so
behavior is unchanged. For bi-endian targets running in BE mode, config
values are now correctly stored in BE byte order, matching what the
guest's le32_to_cpu() conversion expects.
---
include/hw/virtio/virtio-access.h | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/include/hw/virtio/virtio-access.h
b/include/hw/virtio/virtio-access.h
index b58fb6ed7e..a3f1b9f5fe 100644
--- a/include/hw/virtio/virtio-access.h
+++ b/include/hw/virtio/virtio-access.h
@@ -20,6 +20,7 @@
#include "system/memory_cached.h"
#include "hw/virtio/virtio.h"
#include "hw/virtio/virtio-bus.h"
+#include "qemu/target-info.h"
#if defined(TARGET_PPC64) || defined(TARGET_ARM)
#define LEGACY_VIRTIO_IS_BIENDIAN 1
@@ -36,7 +37,10 @@ static inline bool virtio_access_is_big_endian(VirtIODevice
*vdev)
}
return true;
#else
- return false;
+ if (virtio_vdev_has_feature(vdev, VIRTIO_F_VERSION_1)) {
+ return false;
+ }
+ return target_big_endian();
#endif
}
--
2.34.1