The early startup code in kernel/pi/ is built with -mbranch-protection=none and has its property note stripped, which prevents the linker from generating BTI veneers in >128MB kernels.
Unlike the assembly objects, which only lacked the note because SYM_FUNC_START*() already emits the landing pads, pi/ needs the real thing. Some of it runs with the MMU on, where the kernel text is mapped PTE_GP and BTI is enforced: __pi_scs_patch() is called when loading a module, and __pi_map_range() is called from create_idmap(). Add -mbranch-protection=bti. The added "bti c" landing pads execute as NOPs in the startup code wherever BTI isn't implemented or isn't enforced. Also stop stripping the objects' property notes, as the linker only marks the output BTI-compatible if *all* objects advertise it. Keeping the note as-is isn't enough either: --prefix-alloc-sections=.init renames it to .init.note.gnu.property, which GNU ld still parses but LLD ignores. Rename it back afterwards so both linkers see it. Signed-off-by: Josh Poimboeuf <[email protected]> --- arch/arm64/kernel/pi/Makefile | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/arch/arm64/kernel/pi/Makefile b/arch/arm64/kernel/pi/Makefile index be92d73c25b21..2101d96d754e5 100644 --- a/arch/arm64/kernel/pi/Makefile +++ b/arch/arm64/kernel/pi/Makefile @@ -4,7 +4,7 @@ KBUILD_CFLAGS := $(subst $(CC_FLAGS_FTRACE),,$(KBUILD_CFLAGS)) -fpie \ -Os -DDISABLE_BRANCH_PROFILING $(DISABLE_KSTACK_ERASE) \ $(DISABLE_LATENT_ENTROPY_PLUGIN) \ - $(call cc-option,-mbranch-protection=none) \ + $(call cc-option,-mbranch-protection=bti) \ -I$(srctree)/scripts/dtc/libfdt -fno-stack-protector \ -include $(srctree)/include/linux/hidden.h \ -D__DISABLE_EXPORTS -ffreestanding -D__NO_FORTIFY \ @@ -21,11 +21,14 @@ KBUILD_CFLAGS := $(filter-out $(CC_FLAGS_LTO), $(KBUILD_CFLAGS)) hostprogs := relacheck +# --prefix-alloc-sections=.init also renames .note.gnu.property, which LLD then +# ignores, dropping the BTI property. Rename it back. quiet_cmd_piobjcopy = $(quiet_cmd_objcopy) - cmd_piobjcopy = $(cmd_objcopy) && $(obj)/relacheck $(@) $(<) + cmd_piobjcopy = $(cmd_objcopy) && \ + $(OBJCOPY) --rename-section .init.note.gnu.property=.note.gnu.property $(@) && \ + $(obj)/relacheck $(@) $(<) -$(obj)/%.pi.o: OBJCOPYFLAGS := --prefix-symbols=__pi_ \ - --remove-section=.note.gnu.property +$(obj)/%.pi.o: OBJCOPYFLAGS := --prefix-symbols=__pi_ $(obj)/%.pi.o: $(obj)/%.o $(obj)/relacheck FORCE $(call if_changed,piobjcopy) -- 2.55.0

