[PATCH 2/6] arm64: insn: make `aarch64_insn_gen_d{m,s}b()` alternative-safe

Ada Couprie Diaz ada.coupriediaz at arm.com
Mon Sep 28 06:30:30 PDT 2026


Move `aarch64_insn_gen_d{m,s}b()` and `__get_barrier_crm_val()`
to `insn.h` and mark them `__always_inline`.
Replace the error print by a build-time check now that the compiler can
verify all call sites.

This is possible thanks to all enum types being covered in the previous
commit, and the only current caller being BPF with static arguments.

As all functions are now inlined and do not call any instrumentable
function, they are now safe to call in alternative callbacks.

Signed-off-by: Ada Couprie Diaz <ada.coupriediaz at arm.com>
---
 arch/arm64/include/asm/insn.h | 56 +++++++++++++++++++++++++++++++++--
 arch/arm64/lib/insn.c         | 52 --------------------------------
 2 files changed, 54 insertions(+), 54 deletions(-)

diff --git a/arch/arm64/include/asm/insn.h b/arch/arm64/include/asm/insn.h
index 8ec9d86cc575c..40f13d28a5fd7 100644
--- a/arch/arm64/include/asm/insn.h
+++ b/arch/arm64/include/asm/insn.h
@@ -7,6 +7,7 @@
  */
 #ifndef	__ASM_INSN_H
 #define	__ASM_INSN_H
+#include <linux/bits.h>
 #include <linux/build_bug.h>
 #include <linux/types.h>
 
@@ -699,8 +700,59 @@ u32 aarch64_insn_gen_cas(enum aarch64_insn_register result,
 			 enum aarch64_insn_register value,
 			 enum aarch64_insn_size_type size,
 			 enum aarch64_insn_mem_order_type order);
-u32 aarch64_insn_gen_dmb(enum aarch64_insn_mb_type type);
-u32 aarch64_insn_gen_dsb(enum aarch64_insn_mb_type type);
+
+static __always_inline u32 __get_barrier_crm_val(enum aarch64_insn_mb_type type)
+{
+	switch (type) {
+	case AARCH64_INSN_MB_SY:
+		return 0xf;
+	case AARCH64_INSN_MB_ST:
+		return 0xe;
+	case AARCH64_INSN_MB_LD:
+		return 0xd;
+	case AARCH64_INSN_MB_ISH:
+		return 0xb;
+	case AARCH64_INSN_MB_NSH:
+		return 0x7;
+	case AARCH64_INSN_MB_OSH:
+		return 0x3;
+	default:
+		BUILD_BUG_ON_MSG(1, "unknown barrier type");
+		return AARCH64_BREAK_FAULT;
+	}
+}
+
+static __always_inline u32 aarch64_insn_gen_dmb(enum aarch64_insn_mb_type type)
+{
+	u32 opt;
+	u32 insn;
+
+	opt = __get_barrier_crm_val(type);
+	if (opt == AARCH64_BREAK_FAULT)
+		return AARCH64_BREAK_FAULT;
+
+	insn = aarch64_insn_get_dmb_value();
+	insn &= ~GENMASK(11, 8);
+	insn |= (opt << 8);
+
+	return insn;
+}
+
+static __always_inline u32 aarch64_insn_gen_dsb(enum aarch64_insn_mb_type type)
+{
+	u32 opt, insn;
+
+	opt = __get_barrier_crm_val(type);
+	if (opt == AARCH64_BREAK_FAULT)
+		return AARCH64_BREAK_FAULT;
+
+	insn = aarch64_insn_get_dsb_base_value();
+	insn &= ~GENMASK(11, 8);
+	insn |= (opt << 8);
+
+	return insn;
+}
+
 u32 aarch64_insn_gen_mrs(enum aarch64_insn_register result,
 			 enum aarch64_insn_system_register sysreg);
 
diff --git a/arch/arm64/lib/insn.c b/arch/arm64/lib/insn.c
index c70820d65805f..5c37f3a4c402b 100644
--- a/arch/arm64/lib/insn.c
+++ b/arch/arm64/lib/insn.c
@@ -1561,58 +1561,6 @@ u32 aarch64_insn_gen_extr(enum aarch64_insn_variant variant,
 	return aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RM, insn, Rm);
 }
 
-static u32 __get_barrier_crm_val(enum aarch64_insn_mb_type type)
-{
-	switch (type) {
-	case AARCH64_INSN_MB_SY:
-		return 0xf;
-	case AARCH64_INSN_MB_ST:
-		return 0xe;
-	case AARCH64_INSN_MB_LD:
-		return 0xd;
-	case AARCH64_INSN_MB_ISH:
-		return 0xb;
-	case AARCH64_INSN_MB_NSH:
-		return 0x7;
-	case AARCH64_INSN_MB_OSH:
-		return 0x3;
-	default:
-		pr_err("%s: unknown barrier type %d\n", __func__, type);
-		return AARCH64_BREAK_FAULT;
-	}
-}
-
-u32 aarch64_insn_gen_dmb(enum aarch64_insn_mb_type type)
-{
-	u32 opt;
-	u32 insn;
-
-	opt = __get_barrier_crm_val(type);
-	if (opt == AARCH64_BREAK_FAULT)
-		return AARCH64_BREAK_FAULT;
-
-	insn = aarch64_insn_get_dmb_value();
-	insn &= ~GENMASK(11, 8);
-	insn |= (opt << 8);
-
-	return insn;
-}
-
-u32 aarch64_insn_gen_dsb(enum aarch64_insn_mb_type type)
-{
-	u32 opt, insn;
-
-	opt = __get_barrier_crm_val(type);
-	if (opt == AARCH64_BREAK_FAULT)
-		return AARCH64_BREAK_FAULT;
-
-	insn = aarch64_insn_get_dsb_base_value();
-	insn &= ~GENMASK(11, 8);
-	insn |= (opt << 8);
-
-	return insn;
-}
-
 u32 aarch64_insn_gen_mrs(enum aarch64_insn_register result,
 			 enum aarch64_insn_system_register sysreg)
 {
-- 
2.43.0




More information about the linux-arm-kernel mailing list