diff options
author | Zong Li <zong@andestech.com> | 2018-08-15 10:45:59 +0800 |
---|---|---|
committer | Greentime Hu <greentime@andestech.com> | 2018-09-04 14:45:17 +0800 |
commit | a18082575c664847d36c6ca030b09ce8d93aec2f (patch) | |
tree | 96070f10fadd478d6f644d639b899d9bb9311650 /arch/nds32/kernel | |
parent | 487913ab18c215b06611c4c91c7e905fc0960eb8 (diff) |
nds32/ftrace: Support static function tracer
This patch support the static function tracer. On nds32 ABI, we need to
always push return address to stack for __builtin_return_address can
work correctly, otherwise, it will get the wrong value of $lp at leaf
function.
Signed-off-by: Zong Li <zong@andestech.com>
Acked-by: Greentime Hu <greentime@andestech.com>
Signed-off-by: Greentime Hu <greentime@andestech.com>
Diffstat (limited to 'arch/nds32/kernel')
-rw-r--r-- | arch/nds32/kernel/Makefile | 6 | ||||
-rw-r--r-- | arch/nds32/kernel/ftrace.c | 28 |
2 files changed, 34 insertions, 0 deletions
diff --git a/arch/nds32/kernel/Makefile b/arch/nds32/kernel/Makefile index 42792743e8b9..27cded39fa66 100644 --- a/arch/nds32/kernel/Makefile +++ b/arch/nds32/kernel/Makefile @@ -21,3 +21,9 @@ extra-y := head.o vmlinux.lds obj-y += vdso/ + +obj-$(CONFIG_FUNCTION_TRACER) += ftrace.o + +ifdef CONFIG_FUNCTION_TRACER +CFLAGS_REMOVE_ftrace.o = $(CC_FLAGS_FTRACE) +endif diff --git a/arch/nds32/kernel/ftrace.c b/arch/nds32/kernel/ftrace.c new file mode 100644 index 000000000000..563f64c070b3 --- /dev/null +++ b/arch/nds32/kernel/ftrace.c @@ -0,0 +1,28 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include <linux/ftrace.h> +#include <linux/uaccess.h> +#include <asm/cacheflush.h> + +extern void (*ftrace_trace_function)(unsigned long, unsigned long, + struct ftrace_ops*, struct pt_regs*); + +noinline void __naked ftrace_stub(unsigned long ip, unsigned long parent_ip, + struct ftrace_ops *op, struct pt_regs *regs) +{ + __asm__ (""); /* avoid to optimize as pure function */ +} + +noinline void _mcount(unsigned long parent_ip) +{ + /* save all state by the compiler prologue */ + + unsigned long ip = (unsigned long)__builtin_return_address(0); + + if (ftrace_trace_function != ftrace_stub) + ftrace_trace_function(ip - MCOUNT_INSN_SIZE, parent_ip, + NULL, NULL); + + /* restore all state by the compiler epilogue */ +} +EXPORT_SYMBOL(_mcount); |