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
>