Thanks to previous refactoring, we can see more easily it is strictly
equivalent to always call virtio_vdev_is_big_endian.
static inline bool virtio_vdev_is_big_endian(VirtIODevice *vdev)
{
if (virtio_vdev_is_legacy(vdev)) {
assert(vdev->device_endian != VIRTIO_DEVICE_ENDIAN_UNKNOWN);
return vdev->device_endian == VIRTIO_DEVICE_ENDIAN_BIG;
}
/* Devices conforming to VIRTIO 1.0 or later are always LE. */
return false;
}
The key is to understand that vdev->device_endian is initialized as
expected. It always contains cpu endianness, and not
device endianness, ignoring if device is legacy or not.
By default, it's initialized to vdev->device_endian =
virtio_default_endian(), which matches target default endianness.
Then, on virtio_reset, it will be initialized with current_cpu
endianness (if there is one current_cpu).
void virtio_reset() {
...
if (current_cpu) {
/* Guest initiated reset */
vdev->device_endian = virtio_current_cpu_endian();
} else {
/* System reset */
vdev->device_endian = virtio_default_endian();
}
Now, we can see how existing virtio_access_is_big_endian is equivalent
to virtio_vdev_is_big_endian. Let's break the existing function in its 3
variants, and compare that to virtio_vdev_is_big_endian.
static inline bool virtio_access_is_big_endian(VirtIODevice *vdev)
- #if defined(LEGACY_VIRTIO_IS_BIENDIAN)
return virtio_vdev_is_big_endian(vdev);
This is the exact replacement we did, so equivalent.
- #elif TARGET_BIG_ENDIAN
if (virtio_vdev_is_modern(vdev)) {
return false;
}
return true;
we know target_is_big_endian(), so
vdev->device_endian == VIRTIO_DEVICE_ENDIAN_BIG.
if (virtio_vdev_is_legacy(vdev)) {
return VIRTIO_DEVICE_ENDIAN_BIG == VIRTIO_DEVICE_ENDIAN_BIG;
}
return false;
It's written in opposite style compared to existing code (if legacy vs
if modern), but it's strictly equivalent.
- #else
return false;
we know !target_is_big_endian(), so
vdev->device_endian == VIRTIO_DEVICE_ENDIAN_LITTLE.
if virtio_vdev_is_legacy(vdev) {
return VIRTIO_DEVICE_ENDIAN_LITTLE == VIRTIO_DEVICE_ENDIAN_BIG;
}
return false;
So it always return false, as expected.
Signed-off-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
---
include/hw/virtio/virtio-access.h | 42 +++++++++----------------------
hw/virtio/virtio.c | 4 +--
2 files changed, 14 insertions(+), 32 deletions(-)
diff --git a/include/hw/virtio/virtio-access.h b/include/hw/virtio/virtio-access.h
index 0c5514178e4..506be642c9f 100644
--- a/include/hw/virtio/virtio-access.h
+++ b/include/hw/virtio/virtio-access.h
@@ -21,27 +21,9 @@
#include "hw/virtio/virtio.h"
#include "hw/virtio/virtio-bus.h"
-#if defined(TARGET_PPC64) || defined(TARGET_ARM)
-#define LEGACY_VIRTIO_IS_BIENDIAN 1
-#endif
-
-static inline bool virtio_access_is_big_endian(VirtIODevice *vdev)
-{
-#if defined(LEGACY_VIRTIO_IS_BIENDIAN)
- return virtio_vdev_is_big_endian(vdev);
-#elif TARGET_BIG_ENDIAN
- if (virtio_vdev_is_modern(vdev)) {
- return false;
- }
- return true;
-#else
- return false;
-#endif
-}
-
static inline void virtio_stw_p(VirtIODevice *vdev, void *ptr, uint16_t v)
{
- if (virtio_access_is_big_endian(vdev)) {
+ if (virtio_vdev_is_big_endian(vdev)) {
stw_be_p(ptr, v);
} else {
stw_le_p(ptr, v);
@@ -50,7 +32,7 @@ static inline void virtio_stw_p(VirtIODevice *vdev, void *ptr, uint16_t v)
static inline void virtio_stl_p(VirtIODevice *vdev, void *ptr, uint32_t v)
{
- if (virtio_access_is_big_endian(vdev)) {
+ if (virtio_vdev_is_big_endian(vdev)) {
stl_be_p(ptr, v);
} else {
stl_le_p(ptr, v);
@@ -59,7 +41,7 @@ static inline void virtio_stl_p(VirtIODevice *vdev, void *ptr, uint32_t v)
static inline void virtio_stq_p(VirtIODevice *vdev, void *ptr, uint64_t v)
{
- if (virtio_access_is_big_endian(vdev)) {
+ if (virtio_vdev_is_big_endian(vdev)) {
stq_be_p(ptr, v);
} else {
stq_le_p(ptr, v);
@@ -68,7 +50,7 @@ static inline void virtio_stq_p(VirtIODevice *vdev, void *ptr, uint64_t v)
static inline int virtio_lduw_p(VirtIODevice *vdev, const void *ptr)
{
- if (virtio_access_is_big_endian(vdev)) {
+ if (virtio_vdev_is_big_endian(vdev)) {
return lduw_be_p(ptr);
} else {
return lduw_le_p(ptr);
@@ -77,7 +59,7 @@ static inline int virtio_lduw_p(VirtIODevice *vdev, const void *ptr)
static inline int virtio_ldl_p(VirtIODevice *vdev, const void *ptr)
{
- if (virtio_access_is_big_endian(vdev)) {
+ if (virtio_vdev_is_big_endian(vdev)) {
return ldl_be_p(ptr);
} else {
return ldl_le_p(ptr);
@@ -86,7 +68,7 @@ static inline int virtio_ldl_p(VirtIODevice *vdev, const void *ptr)
static inline uint64_t virtio_ldq_p(VirtIODevice *vdev, const void *ptr)
{
- if (virtio_access_is_big_endian(vdev)) {
+ if (virtio_vdev_is_big_endian(vdev)) {
return ldq_be_p(ptr);
} else {
return ldq_le_p(ptr);
@@ -96,9 +78,9 @@ static inline uint64_t virtio_ldq_p(VirtIODevice *vdev, const void *ptr)
static inline uint16_t virtio_tswap16(VirtIODevice *vdev, uint16_t s)
{
#if HOST_BIG_ENDIAN
- return virtio_access_is_big_endian(vdev) ? s : bswap16(s);
+ return virtio_vdev_is_big_endian(vdev) ? s : bswap16(s);
#else
- return virtio_access_is_big_endian(vdev) ? bswap16(s) : s;
+ return virtio_vdev_is_big_endian(vdev) ? bswap16(s) : s;
#endif
}
@@ -110,9 +92,9 @@ static inline void virtio_tswap16s(VirtIODevice *vdev, uint16_t *s)
static inline uint32_t virtio_tswap32(VirtIODevice *vdev, uint32_t s)
{
#if HOST_BIG_ENDIAN
- return virtio_access_is_big_endian(vdev) ? s : bswap32(s);
+ return virtio_vdev_is_big_endian(vdev) ? s : bswap32(s);
#else
- return virtio_access_is_big_endian(vdev) ? bswap32(s) : s;
+ return virtio_vdev_is_big_endian(vdev) ? bswap32(s) : s;
#endif
}
@@ -124,9 +106,9 @@ static inline void virtio_tswap32s(VirtIODevice *vdev, uint32_t *s)
static inline uint64_t virtio_tswap64(VirtIODevice *vdev, uint64_t s)
{
#if HOST_BIG_ENDIAN
- return virtio_access_is_big_endian(vdev) ? s : bswap64(s);
+ return virtio_vdev_is_big_endian(vdev) ? s : bswap64(s);
#else
- return virtio_access_is_big_endian(vdev) ? bswap64(s) : s;
+ return virtio_vdev_is_big_endian(vdev) ? bswap64(s) : s;
#endif
}
diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
index b0987e66d5b..2ae238001dc 100644
--- a/hw/virtio/virtio.c
+++ b/hw/virtio/virtio.c
@@ -222,7 +222,7 @@ static inline uint16_t virtio_lduw_phys_cached(VirtIODevice *vdev,
MemoryRegionCache *cache,
hwaddr pa)
{
- if (virtio_access_is_big_endian(vdev)) {
+ if (virtio_vdev_is_big_endian(vdev)) {
return lduw_be_phys_cached(cache, pa);
}
return lduw_le_phys_cached(cache, pa);
@@ -232,7 +232,7 @@ static inline void virtio_stw_phys_cached(VirtIODevice *vdev,
MemoryRegionCache *cache,
hwaddr pa, uint16_t value)
{
- if (virtio_access_is_big_endian(vdev)) {
+ if (virtio_vdev_is_big_endian(vdev)) {
stw_be_phys_cached(cache, pa, value);
} else {
stw_le_phys_cached(cache, pa, value);
--
2.47.3
On 13/2/26 00:46, Pierrick Bouvier wrote: > Thanks to previous refactoring, we can see more easily it is strictly > equivalent to always call virtio_vdev_is_big_endian. > Signed-off-by: Pierrick Bouvier <pierrick.bouvier@linaro.org> > --- > include/hw/virtio/virtio-access.h | 42 +++++++++---------------------- > hw/virtio/virtio.c | 4 +-- > 2 files changed, 14 insertions(+), 32 deletions(-) Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
© 2016 - 2026 Red Hat, Inc.