Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e71a4e1b authored by Ard Biesheuvel's avatar Ard Biesheuvel Committed by Will Deacon
Browse files

arm64: ftrace: add support for far branches to dynamic ftrace



Currently, dynamic ftrace support in the arm64 kernel assumes that all
core kernel code is within range of ordinary branch instructions that
occur in module code, which is usually the case, but is no longer
guaranteed now that we have support for module PLTs and address space
randomization.

Since on arm64, all patching of branch instructions involves function
calls to the same entry point [ftrace_caller()], we can emit the modules
with a trampoline that has unlimited range, and patch both the trampoline
itself and the branch instruction to redirect the call via the trampoline.

Signed-off-by: default avatarArd Biesheuvel <ard.biesheuvel@linaro.org>
[will: minor clarification to smp_wmb() comment]
Signed-off-by: default avatarWill Deacon <will.deacon@arm.com>
parent f8af0b36
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -982,7 +982,7 @@ config RANDOMIZE_BASE

config RANDOMIZE_MODULE_REGION_FULL
	bool "Randomize the module region independently from the core kernel"
	depends on RANDOMIZE_BASE && !DYNAMIC_FTRACE
	depends on RANDOMIZE_BASE
	default y
	help
	  Randomizes the location of the module region without considering the
+3 −0
Original line number Diff line number Diff line
@@ -70,6 +70,9 @@ endif

ifeq ($(CONFIG_ARM64_MODULE_PLTS),y)
KBUILD_LDFLAGS_MODULE	+= -T $(srctree)/arch/arm64/kernel/module.lds
ifeq ($(CONFIG_DYNAMIC_FTRACE),y)
KBUILD_LDFLAGS_MODULE	+= $(objtree)/arch/arm64/kernel/ftrace-mod.o
endif
endif

# Default value
+3 −0
Original line number Diff line number Diff line
@@ -30,6 +30,9 @@ struct mod_plt_sec {
struct mod_arch_specific {
	struct mod_plt_sec	core;
	struct mod_plt_sec	init;

	/* for CONFIG_DYNAMIC_FTRACE */
	void			*ftrace_trampoline;
};
#endif

+3 −0
Original line number Diff line number Diff line
@@ -62,3 +62,6 @@ extra-y += $(head-y) vmlinux.lds
ifeq ($(CONFIG_DEBUG_EFI),y)
AFLAGS_head.o += -DVMLINUX_PATH="\"$(realpath $(objtree)/vmlinux)\""
endif

# will be included by each individual module but not by the core kernel itself
extra-$(CONFIG_DYNAMIC_FTRACE) += ftrace-mod.o
+18 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2017 Linaro Ltd <ard.biesheuvel@linaro.org>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */

#include <linux/linkage.h>
#include <asm/assembler.h>

	.section	".text.ftrace_trampoline", "ax"
	.align		3
0:	.quad		0
__ftrace_trampoline:
	ldr		x16, 0b
	br		x16
ENDPROC(__ftrace_trampoline)
Loading