Re: [PATCH v2] virtio: Add aligned ld/st accessors for vring

Peter Xu <[email protected]>
Newsgroups org.nongnu.qemu-riscv,org.nongnu.qemu-devel
Message-ID <[email protected]>
On Mon, Aug 24, 2026 at 12:19:15PM +0800, BillXiang wrote:
> Hi Richard, I've read your code in accel/tcg/ldst_atomicity.c.inc. Do 
> you think it would be better to make the load/store_atomic* public?

They do not fit by default, as we need to still process unaligned cases?

I wished we can use qemu_mem_move() directly that just got introduced.. but
it does slightly more than wanted.  Maybe something like this?  Below diff
dropped ldsw_he_p() alone the way as it's never used.

Thanks,

===8<===

diff --git a/include/qemu/bswap.h b/include/qemu/bswap.h
index 387d65c0b0..04a0f63612 100644
--- a/include/qemu/bswap.h
+++ b/include/qemu/bswap.h
@@ -1,6 +1,7 @@
 #ifndef BSWAP_H
 #define BSWAP_H
 
+#include "qemu/atomic.h"
 #include "qemu/target-info.h"
 #include "exec/memop.h"
 
@@ -238,62 +239,52 @@ static inline void stb_p(void *ptr, uint8_t v)
     *(uint8_t *)ptr = v;
 }
 
-/*
- * Any compiler worth its salt will turn these memcpy into native unaligned
- * operations.  Thus we don't need to play games with packed attributes, or
- * inline byte-by-byte stores.
- * Some compilation environments (eg some fortify-source implementations)
- * may intercept memcpy() in a way that defeats the compiler optimization,
- * though, so we use __builtin_memcpy() to give ourselves the best chance
- * of good performance.
- */
-
-static inline int lduw_he_p(const void *ptr)
-{
-    uint16_t r;
-    __builtin_memcpy(&r, ptr, sizeof(r));
-    return r;
-}
-
-static inline int ldsw_he_p(const void *ptr)
-{
-    int16_t r;
-    __builtin_memcpy(&r, ptr, sizeof(r));
-    return r;
-}
+#define  LD_HE_P(type, size)                                \
+    static inline type                                      \
+    glue(glue(ld, size), _he_p)(const void *ptr)            \
+    {                                                       \
+        type v;                                             \
+        if (unlikely((uintptr_t)ptr & (sizeof(v) - 1))) {   \
+            __builtin_memcpy(&v, ptr, sizeof(v));           \
+        } else {                                            \
+            v = qatomic_read((type *)ptr);                  \
+        }                                                   \
+        return v;                                           \
+    }
 
-static inline void stw_he_p(void *ptr, uint16_t v)
-{
-    __builtin_memcpy(ptr, &v, sizeof(v));
-}
+#define  ST_HE_P(type, size)                                \
+    static inline void                                      \
+    glue(glue(st, size), _he_p)(void *ptr, type v)          \
+    {                                                       \
+        if (unlikely((uintptr_t)ptr & (sizeof(v) - 1))) {   \
+            __builtin_memcpy(ptr, &v, sizeof(v));           \
+        } else {                                            \
+            qatomic_set((type *)ptr, v);                    \
+        }                                                   \
+    }
 
-static inline void st24_he_p(void *ptr, uint32_t v)
-{
-    __builtin_memcpy(ptr, &v, 3);
-}
+LD_HE_P(uint16_t, 16)
+LD_HE_P(uint32_t, 32)
+LD_HE_P(uint64_t, 64)
+ST_HE_P(uint16_t, 16)
+ST_HE_P(uint32_t, 32)
+ST_HE_P(uint64_t, 64)
 
-static inline int ldl_he_p(const void *ptr)
-{
-    int32_t r;
-    __builtin_memcpy(&r, ptr, sizeof(r));
-    return r;
-}
+#undef LD_HE_P
+#undef ST_HE_P
+#undef ADDR_ALIGNED
 
-static inline void stl_he_p(void *ptr, uint32_t v)
-{
-    __builtin_memcpy(ptr, &v, sizeof(v));
-}
+#define  lduw_he_p  ld16_he_p
+#define  ldl_he_p  ld32_he_p
+#define  ldq_he_p  ld64_he_p
 
-static inline uint64_t ldq_he_p(const void *ptr)
-{
-    uint64_t r;
-    __builtin_memcpy(&r, ptr, sizeof(r));
-    return r;
-}
+#define  stw_he_p  st16_he_p
+#define  stl_he_p  st32_he_p
+#define  stq_he_p  st64_he_p
 
-static inline void stq_he_p(void *ptr, uint64_t v)
+static inline void st24_he_p(void *ptr, uint32_t v)
 {
-    __builtin_memcpy(ptr, &v, sizeof(v));
+    __builtin_memcpy(ptr, &v, 3);
 }
 
 static inline int lduw_le_p(const void *ptr)
-- 
2.54.0

-- 
Peter Xu
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.