[PATCH 07/12] arm64/bti: Advertise BTI in assembly objects

Josh Poimboeuf <[email protected]>
Newsgroups org.kernel.vger.linux-toolchains,org.infradead.lists.linux-arm-kernel,org.kernel.vger.linux-kernel,org.kernel.vger.live-patching
Message-ID <5340f3df281bebc81aad3cd9a7471d95061b4b9d.1786768375.git.jpoimboe@kernel.org>
On a kernel whose text exceeds the +/-128MB direct branch range, the
linker inserts veneers.  With BTI enabled, the veneers' indirect branch
targets need a BTI landing pad, which not all functions have starting
with Clang 21 (and for all versions of GCC).

In such cases the linker can emit a second veneer close to the target
which has the landing pad along with a direct branch to the target.
However, that's currently not being done, so GCC and Clang 21+ are
broken with BTI on large kernels.

The linker only emits the BTI veneer if *all* input objects have
GNU_PROPERTY_AARCH64_FEATURE_1_BTI, which is not being done for
hand-written asm.

Force-include a property note with the BTI bit into every assembly
translation unit, which is accurate as SYM_FUNC_START*() already emits a
"bti c" landing pad for callable assembly functions.

Signed-off-by: Josh Poimboeuf <[email protected]>
---
 arch/arm64/Makefile               |  4 ++++
 arch/arm64/include/asm/bti-note.h | 32 +++++++++++++++++++++++++++++++
 2 files changed, 36 insertions(+)
 create mode 100644 arch/arm64/include/asm/bti-note.h

diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile
index 6b005c8fef706..4eee721c0b278 100644
--- a/arch/arm64/Makefile
+++ b/arch/arm64/Makefile
@@ -23,6 +23,10 @@ ifeq ($(CONFIG_ARM64_ERRATUM_843419),y)
 LDFLAGS_vmlinux	+= --fix-cortex-a53-843419
 endif
 
+ifeq ($(CONFIG_ARM64_BTI_KERNEL),y)
+KBUILD_AFLAGS	+= -include $(srctree)/arch/arm64/include/asm/bti-note.h
+endif
+
 cc_has_k_constraint := $(call try-run,echo				\
 	'int main(void) {						\
 		asm volatile("and w0, w0, %w0" :: "K" (4294967295));	\
diff --git a/arch/arm64/include/asm/bti-note.h b/arch/arm64/include/asm/bti-note.h
new file mode 100644
index 0000000000000..17ef5692987f7
--- /dev/null
+++ b/arch/arm64/include/asm/bti-note.h
@@ -0,0 +1,32 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Emit a GNU_PROPERTY_AARCH64_FEATURE_1_BTI note.  This is force-included in
+ * every assembly file so the linker emits BTI veneers for >128MB kernels.
+ *
+ * Clang has -mmark-bti-property, but there's no equivalent for GCC/GAS.
+ *
+ * Binutils 2.44+ and LLVM 22+ support a much more compact version:
+ *
+ *   .aeabi_subsection aeabi_feature_and_bits, optional, ULEB128
+ *   .aeabi_attribute Tag_Feature_BTI, 1
+ */
+#ifndef __ASM_BTI_NOTE_H
+#define __ASM_BTI_NOTE_H
+
+	.pushsection .note.gnu.property, "a"
+	.align	3
+	.long	2f - 1f
+	.long	6f - 3f
+	.long	5		/* NT_GNU_PROPERTY_TYPE_0 */
+1:	.string	"GNU"
+2:
+	.align	3
+3:	.long	0xc0000000	/* GNU_PROPERTY_AARCH64_FEATURE_1_AND */
+	.long	5f - 4f
+4:	.long	1		/* GNU_PROPERTY_AARCH64_FEATURE_1_BTI */
+5:
+	.align	3
+6:
+	.popsection
+
+#endif /* __ASM_BTI_NOTE_H */
-- 
2.55.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.