1 /* SPDX-License-Identifier: GPL-2.0 */
2 #ifndef _TOOLS_LINUX_ASM_AARCH64_BARRIER_H
3 #define _TOOLS_LINUX_ASM_AARCH64_BARRIER_H
6 * From tools/perf/perf-sys.h, last modified in:
7 * f428ebd184c82a7914b2aa7e9f868918aaf7ea78 perf tools: Fix AAAAARGH64 memory barriers
9 * XXX: arch/arm64/include/asm/barrier.h in the kernel sources use dsb, is this
10 * a case like for arm32 where we do things differently in userspace?
13 #define mb() asm volatile("dmb ish" ::: "memory")
14 #define wmb() asm volatile("dmb ishst" ::: "memory")
15 #define rmb() asm volatile("dmb ishld" ::: "memory")
17 #define smp_store_release(p, v) \
19 union { typeof(*p) __val; char __c[1]; } __u = \
20 { .__val = (__force typeof(*p)) (v) }; \
22 switch (sizeof(*p)) { \
24 asm volatile ("stlrb %w1, %0" \
26 : "r" (*(__u8 *)__u.__c) \
30 asm volatile ("stlrh %w1, %0" \
32 : "r" (*(__u16 *)__u.__c) \
36 asm volatile ("stlr %w1, %0" \
38 : "r" (*(__u32 *)__u.__c) \
42 asm volatile ("stlr %1, %0" \
44 : "r" (*(__u64 *)__u.__c) \
48 /* Only to shut up gcc ... */ \
54 #define smp_load_acquire(p) \
56 union { typeof(*p) __val; char __c[1]; } __u; \
58 switch (sizeof(*p)) { \
60 asm volatile ("ldarb %w0, %1" \
61 : "=r" (*(__u8 *)__u.__c) \
62 : "Q" (*p) : "memory"); \
65 asm volatile ("ldarh %w0, %1" \
66 : "=r" (*(__u16 *)__u.__c) \
67 : "Q" (*p) : "memory"); \
70 asm volatile ("ldar %w0, %1" \
71 : "=r" (*(__u32 *)__u.__c) \
72 : "Q" (*p) : "memory"); \
75 asm volatile ("ldar %0, %1" \
76 : "=r" (*(__u64 *)__u.__c) \
77 : "Q" (*p) : "memory"); \
80 /* Only to shut up gcc ... */ \
87 #endif /* _TOOLS_LINUX_ASM_AARCH64_BARRIER_H */