By the virtio spec [*] the vring is aligned, so the 'idx' and 'flag'
fields are also 16-bit aligned. Therefore we can use the load/store
*aligned* API to set the value.
[*] https://docs.oasis-open.org/virtio/virtio/v1.1/csprd01/virtio-v1.1-csprd01.html#x1-430008
Reported-by: Bibo Mao <maobibo@loongson.cn>
Inspired-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
---
hw/virtio/virtio.c | 13 +++++++------
1 file changed, 7 insertions(+), 6 deletions(-)
diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
index e02544b2df7..ebee9c4e643 100644
--- a/hw/virtio/virtio.c
+++ b/hw/virtio/virtio.c
@@ -296,7 +296,7 @@ static inline uint16_t vring_avail_flags(VirtQueue *vq)
return 0;
}
- return virtio_lduw_phys_cached(vq->vdev, &caches->avail, pa);
+ return virtio_lduw_phys_cached_aligned(vq->vdev, &caches->avail, pa);
}
/* Called within rcu_read_lock(). */
@@ -309,7 +309,8 @@ static inline uint16_t vring_avail_idx(VirtQueue *vq)
return 0;
}
- vq->shadow_avail_idx = virtio_lduw_phys_cached(vq->vdev, &caches->avail, pa);
+ vq->shadow_avail_idx = virtio_lduw_phys_cached_aligned(vq->vdev,
+ &caches->avail, pa);
return vq->shadow_avail_idx;
}
@@ -359,7 +360,7 @@ static uint16_t vring_used_idx(VirtQueue *vq)
return 0;
}
- return virtio_lduw_phys_cached(vq->vdev, &caches->used, pa);
+ return virtio_lduw_phys_cached_aligned(vq->vdev, &caches->used, pa);
}
/* Called within rcu_read_lock(). */
@@ -369,7 +370,7 @@ static inline void vring_used_idx_set(VirtQueue *vq, uint16_t val)
hwaddr pa = offsetof(VRingUsed, idx);
if (caches) {
- virtio_stw_phys_cached(vq->vdev, &caches->used, pa, val);
+ virtio_stw_phys_cached_aligned(vq->vdev, &caches->used, pa, val);
address_space_cache_invalidate(&caches->used, pa, sizeof(val));
}
@@ -388,8 +389,8 @@ static inline void vring_used_flags_set_bit(VirtQueue *vq, int mask)
return;
}
- flags = virtio_lduw_phys_cached(vq->vdev, &caches->used, pa);
- virtio_stw_phys_cached(vdev, &caches->used, pa, flags | mask);
+ flags = virtio_lduw_phys_cached_aligned(vq->vdev, &caches->used, pa);
+ virtio_stw_phys_cached_aligned(vdev, &caches->used, pa, flags | mask);
address_space_cache_invalidate(&caches->used, pa, sizeof(flags));
}
--
2.26.3