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 <maob...@loongson.cn>
Inspired-by: Stefan Hajnoczi <stefa...@redhat.com>
Signed-off-by: Philippe Mathieu-Daudé <phi...@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


Reply via email to