On 2026-05-15 02:30 PM, Jason Gunthorpe wrote:
> The tools/include readl/writel MMIO accessors on arm64 use
> inner-shareable barriers (dmb ish) while the kernel uses
> outer-shareable (dmb osh).  Fix them to match.
> 
> Add __io_bw() and __io_ar() definitions matching the kernel's
> arch/arm64/include/asm/io.h, including the dummy control dependency
> in __io_ar() that orders MMIO reads against all subsequent
> instructions.
> 
> Assisted-by: Claude:claude-opus-4.6
> Signed-off-by: Jason Gunthorpe <[email protected]>
> ---
>  tools/arch/arm64/include/asm/barrier.h | 14 ++++++++++++++
>  1 file changed, 14 insertions(+)
> 
> diff --git a/tools/arch/arm64/include/asm/barrier.h 
> b/tools/arch/arm64/include/asm/barrier.h
> index abdc64fc3c70f0..3f7fcb2a27541e 100644
> --- a/tools/arch/arm64/include/asm/barrier.h
> +++ b/tools/arch/arm64/include/asm/barrier.h
> @@ -28,6 +28,20 @@
>  #define dma_rmb()    asm volatile("dmb oshld" ::: "memory")
>  #define dma_wmb()    asm volatile("dmb oshst" ::: "memory")
>  
> +/* Match arch/arm64/include/asm/io.h: use osh barriers for device MMIO */
> +#define __io_bw()    dma_wmb()
> +#define __io_ar(v)                                                   \
> +({                                                                   \
> +     unsigned long tmp;                                              \
> +                                                                     \
> +     dma_rmb();                                                      \
> +                                                                     \
> +     asm volatile("eor       %0, %1, %1\n"                           \
> +                  "cbnz      %0, ."                                  \
> +                  : "=r" (tmp) : "r" ((unsigned long)(v))            \
> +                  : "memory");                                       \
> +})
> +

Let's put these in tools/arch/arm64/include/asm/io.h so that the tools
headers are more aligned with the kernel headers, and so that the arm64
io.h overrides are done in the same way as the x86 overrides in
tools/arch/x86/include/asm/io.h.

Something like this (untested):

diff --git a/tools/arch/arm64/include/asm/io.h 
b/tools/arch/arm64/include/asm/io.h
new file mode 100644
index 000000000000..8a5de4fe2afd
--- /dev/null
+++ b/tools/arch/arm64/include/asm/io.h
@@ -0,0 +1,22 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _TOOLS_ASM_ARM64_IO_H
+#define _TOOLS_ASM_ARM64_IO_H
+
+#include <asm/barrier.h>
+
+#define __io_bw()      dma_wmb()
+#define __io_ar(v)                                                     \
+({                                                                     \
+       unsigned long tmp;                                              \
+                                                                       \
+       dma_rmb();                                                      \
+                                                                       \
+       asm volatile("eor       %0, %1, %1\n"                           \
+                    "cbnz      %0, ."                                  \
+                    : "=r" (tmp) : "r" ((unsigned long)(v))            \
+                    : "memory");                                       \
+})
+
+#include <asm-generic/io.h>
+
+#endif /* _TOOLS_ASM_ARM64_IO_H */
diff --git a/tools/include/asm/io.h b/tools/include/asm/io.h
index eed5066f25c4..1090a2c387f4 100644
--- a/tools/include/asm/io.h
+++ b/tools/include/asm/io.h
@@ -4,6 +4,8 @@

 #if defined(__i386__) || defined(__x86_64__)
 #include "../../arch/x86/include/asm/io.h"
+#elif defined(__aarch64__)
+#include "../../arch/arm64/include/asm/io.h"
 #else
 #include <asm-generic/io.h>
 #endif


>  #define smp_store_release(p, v)                                              
> \
>  do {                                                                 \
>       union { typeof(*p) __val; char __c[1]; } __u =                  \
> -- 
> 2.43.0
> 

Reply via email to