[PATCH 1/2] arm64: Remove .inst workarounds after binutils bump

Marc Zyngier maz at kernel.org
Sat Jun 7 03:40:40 PDT 2025


Binutils version up to (and including) 2.25 have a pathological
behaviour when it comes to mixing .inst directive and arithmetic
involving labels. The assembler complains about non-constant
expressions and compilation stops pretty quickly.

Now that our base binutils version is 2.30, we can drop the hackish
workarounds we had in both the alternative and sysreg code.

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/Kconfig                          |  3 ---
 arch/arm64/Makefile                         |  4 ---
 arch/arm64/include/asm/alternative-macros.h | 28 ++++++++-------------
 arch/arm64/include/asm/sysreg.h             | 21 ----------------
 tools/arch/arm64/include/asm/sysreg.h       | 21 ----------------
 5 files changed, 11 insertions(+), 66 deletions(-)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 55fc331af3371..95697700f1992 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -404,9 +404,6 @@ config ARCH_SUPPORTS_UPROBES
 config ARCH_PROC_KCORE_TEXT
 	def_bool y
 
-config BROKEN_GAS_INST
-	def_bool !$(as-instr,1:\n.inst 0\n.rept . - 1b\n\nnop\n.endr\n)
-
 config BUILTIN_RETURN_ADDRESS_STRIPS_PAC
 	bool
 	# Clang's __builtin_return_address() strips the PAC since 12.0.0
diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile
index 73a10f65ce8bc..212bf394ea43f 100644
--- a/arch/arm64/Makefile
+++ b/arch/arm64/Makefile
@@ -29,10 +29,6 @@ cc_has_k_constraint := $(call try-run,echo				\
 		return 0;						\
 	}' | $(CC) -S -x c -o "$$TMP" -,,-DCONFIG_CC_HAS_K_CONSTRAINT=1)
 
-ifeq ($(CONFIG_BROKEN_GAS_INST),y)
-$(warning Detected assembler with broken .inst; disassembly will be unreliable)
-endif
-
 # The GCC option -ffreestanding is required in order to compile code containing
 # ARM/NEON intrinsics in a non C99-compliant environment (such as the kernel)
 CC_FLAGS_FPU	:= -ffreestanding
diff --git a/arch/arm64/include/asm/alternative-macros.h b/arch/arm64/include/asm/alternative-macros.h
index c8c77f9e36d60..61c2cbe618b9f 100644
--- a/arch/arm64/include/asm/alternative-macros.h
+++ b/arch/arm64/include/asm/alternative-macros.h
@@ -40,17 +40,6 @@
 /*
  * alternative assembly primitive:
  *
- * If any of these .org directive fail, it means that insn1 and insn2
- * don't have the same length. This used to be written as
- *
- * .if ((664b-663b) != (662b-661b))
- * 	.error "Alternatives instruction length mismatch"
- * .endif
- *
- * but most assemblers die if insn1 or insn2 have a .inst. This should
- * be fixed in a binutils release posterior to 2.25.51.0.2 (anything
- * containing commit 4e4d08cf7399b606 or c1baaddf8861).
- *
  * Alternatives with callbacks do not generate replacement instructions.
  */
 #define __ALTERNATIVE_CFG(oldinstr, newinstr, cpucap, cfg_enabled)	\
@@ -65,8 +54,9 @@
 	"663:\n\t"							\
 	newinstr "\n"							\
 	"664:\n\t"							\
-	".org	. - (664b-663b) + (662b-661b)\n\t"			\
-	".org	. - (662b-661b) + (664b-663b)\n\t"			\
+	".if ((664b-663b) != (662b-661b))\n"				\
+	".error \"Alternatives instruction length mismatch\"\n"		\
+	".endif\n"							\
 	".previous\n"							\
 	".endif\n"
 
@@ -99,6 +89,12 @@
 	.byte \alt_len
 .endm
 
+.macro check_alternative_sizes
+	.if ((664b-663b) != (662b-661b))
+	.error "Alternatives instruction length mismatch"
+	.endif
+.endm
+
 .macro alternative_insn insn1, insn2, cap, enable = 1
 	.if \enable
 661:	\insn1
@@ -107,8 +103,7 @@
 	.popsection
 	.subsection 1
 663:	\insn2
-664:	.org	. - (664b-663b) + (662b-661b)
-	.org	. - (662b-661b) + (664b-663b)
+664:	check_alternative_sizes
 	.previous
 	.endif
 .endm
@@ -179,8 +174,7 @@
  */
 .macro alternative_endif
 664:
-	.org	. - (664b-663b) + (662b-661b)
-	.org	. - (662b-661b) + (664b-663b)
+	check_alternative_sizes
 	.if .Lasm_alt_mode==0
 	.previous
 	.endif
diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
index f1bb0d10c39a3..42084cdd3fce8 100644
--- a/arch/arm64/include/asm/sysreg.h
+++ b/arch/arm64/include/asm/sysreg.h
@@ -50,8 +50,6 @@
 #define sys_reg_CRm(id)	(((id) >> CRm_shift) & CRm_mask)
 #define sys_reg_Op2(id)	(((id) >> Op2_shift) & Op2_mask)
 
-#ifndef CONFIG_BROKEN_GAS_INST
-
 #ifdef __ASSEMBLY__
 // The space separator is omitted so that __emit_inst(x) can be parsed as
 // either an assembler directive or an assembler macro argument.
@@ -60,25 +58,6 @@
 #define __emit_inst(x)			".inst " __stringify((x)) "\n\t"
 #endif
 
-#else  /* CONFIG_BROKEN_GAS_INST */
-
-#ifndef CONFIG_CPU_BIG_ENDIAN
-#define __INSTR_BSWAP(x)		(x)
-#else  /* CONFIG_CPU_BIG_ENDIAN */
-#define __INSTR_BSWAP(x)		((((x) << 24) & 0xff000000)	| \
-					 (((x) <<  8) & 0x00ff0000)	| \
-					 (((x) >>  8) & 0x0000ff00)	| \
-					 (((x) >> 24) & 0x000000ff))
-#endif	/* CONFIG_CPU_BIG_ENDIAN */
-
-#ifdef __ASSEMBLY__
-#define __emit_inst(x)			.long __INSTR_BSWAP(x)
-#else  /* __ASSEMBLY__ */
-#define __emit_inst(x)			".long " __stringify(__INSTR_BSWAP(x)) "\n\t"
-#endif	/* __ASSEMBLY__ */
-
-#endif	/* CONFIG_BROKEN_GAS_INST */
-
 /*
  * Instructions for modifying PSTATE fields.
  * As per Arm ARM for v8-A, Section "C.5.1.3 op0 == 0b00, architectural hints,
diff --git a/tools/arch/arm64/include/asm/sysreg.h b/tools/arch/arm64/include/asm/sysreg.h
index 690b6ebd118f4..58aebe6e65da5 100644
--- a/tools/arch/arm64/include/asm/sysreg.h
+++ b/tools/arch/arm64/include/asm/sysreg.h
@@ -49,8 +49,6 @@
 #define sys_reg_CRm(id)	(((id) >> CRm_shift) & CRm_mask)
 #define sys_reg_Op2(id)	(((id) >> Op2_shift) & Op2_mask)
 
-#ifndef CONFIG_BROKEN_GAS_INST
-
 #ifdef __ASSEMBLY__
 // The space separator is omitted so that __emit_inst(x) can be parsed as
 // either an assembler directive or an assembler macro argument.
@@ -59,25 +57,6 @@
 #define __emit_inst(x)			".inst " __stringify((x)) "\n\t"
 #endif
 
-#else  /* CONFIG_BROKEN_GAS_INST */
-
-#ifndef CONFIG_CPU_BIG_ENDIAN
-#define __INSTR_BSWAP(x)		(x)
-#else  /* CONFIG_CPU_BIG_ENDIAN */
-#define __INSTR_BSWAP(x)		((((x) << 24) & 0xff000000)	| \
-					 (((x) <<  8) & 0x00ff0000)	| \
-					 (((x) >>  8) & 0x0000ff00)	| \
-					 (((x) >> 24) & 0x000000ff))
-#endif	/* CONFIG_CPU_BIG_ENDIAN */
-
-#ifdef __ASSEMBLY__
-#define __emit_inst(x)			.long __INSTR_BSWAP(x)
-#else  /* __ASSEMBLY__ */
-#define __emit_inst(x)			".long " __stringify(__INSTR_BSWAP(x)) "\n\t"
-#endif	/* __ASSEMBLY__ */
-
-#endif	/* CONFIG_BROKEN_GAS_INST */
-
 /*
  * Instructions for modifying PSTATE fields.
  * As per Arm ARM for v8-A, Section "C.5.1.3 op0 == 0b00, architectural hints,
-- 
2.39.2




More information about the linux-arm-kernel mailing list