summaryrefslogtreecommitdiffstats
path: root/arch/arm64/kernel/ftrace.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm64/kernel/ftrace.c')
-rw-r--r--arch/arm64/kernel/ftrace.c14
1 files changed, 8 insertions, 6 deletions
diff --git a/arch/arm64/kernel/ftrace.c b/arch/arm64/kernel/ftrace.c
index c13b1fca0e5b..50986e388d2b 100644
--- a/arch/arm64/kernel/ftrace.c
+++ b/arch/arm64/kernel/ftrace.c
@@ -76,7 +76,7 @@ int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
if (offset < -SZ_128M || offset >= SZ_128M) {
#ifdef CONFIG_ARM64_MODULE_PLTS
- unsigned long *trampoline;
+ struct plt_entry trampoline;
struct module *mod;
/*
@@ -104,22 +104,24 @@ int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
* is added in the future, but for now, the pr_err() below
* deals with a theoretical issue only.
*/
- trampoline = (unsigned long *)mod->arch.ftrace_trampoline;
- if (trampoline[0] != addr) {
- if (trampoline[0] != 0) {
+ trampoline = get_plt_entry(addr);
+ if (!plt_entries_equal(mod->arch.ftrace_trampoline,
+ &trampoline)) {
+ if (!plt_entries_equal(mod->arch.ftrace_trampoline,
+ &(struct plt_entry){})) {
pr_err("ftrace: far branches to multiple entry points unsupported inside a single module\n");
return -EINVAL;
}
/* point the trampoline to our ftrace entry point */
module_disable_ro(mod);
- trampoline[0] = addr;
+ *mod->arch.ftrace_trampoline = trampoline;
module_enable_ro(mod, true);
/* update trampoline before patching in the branch */
smp_wmb();
}
- addr = (unsigned long)&trampoline[1];
+ addr = (unsigned long)(void *)mod->arch.ftrace_trampoline;
#else /* CONFIG_ARM64_MODULE_PLTS */
return -EINVAL;
#endif /* CONFIG_ARM64_MODULE_PLTS */