diff options
-rw-r--r-- | arch/nds32/Kconfig | 1 | ||||
-rw-r--r-- | arch/nds32/Makefile | 4 | ||||
-rw-r--r-- | arch/nds32/include/asm/ftrace.h | 20 | ||||
-rw-r--r-- | arch/nds32/kernel/Makefile | 6 | ||||
-rw-r--r-- | arch/nds32/kernel/ftrace.c | 28 |
5 files changed, 59 insertions, 0 deletions
diff --git a/arch/nds32/Kconfig b/arch/nds32/Kconfig index 1d4248fa55e9..853497fe4266 100644 --- a/arch/nds32/Kconfig +++ b/arch/nds32/Kconfig | |||
@@ -40,6 +40,7 @@ config NDS32 | |||
40 | select NO_IOPORT_MAP | 40 | select NO_IOPORT_MAP |
41 | select RTC_LIB | 41 | select RTC_LIB |
42 | select THREAD_INFO_IN_TASK | 42 | select THREAD_INFO_IN_TASK |
43 | select HAVE_FUNCTION_TRACER | ||
43 | help | 44 | help |
44 | Andes(nds32) Linux support. | 45 | Andes(nds32) Linux support. |
45 | 46 | ||
diff --git a/arch/nds32/Makefile b/arch/nds32/Makefile index 63f4f173e5f4..3509fac10491 100644 --- a/arch/nds32/Makefile +++ b/arch/nds32/Makefile | |||
@@ -5,6 +5,10 @@ KBUILD_DEFCONFIG := defconfig | |||
5 | 5 | ||
6 | comma = , | 6 | comma = , |
7 | 7 | ||
8 | ifdef CONFIG_FUNCTION_TRACER | ||
9 | arch-y += -malways-save-lp -mno-relax | ||
10 | endif | ||
11 | |||
8 | KBUILD_CFLAGS += $(call cc-option, -mno-sched-prolog-epilog) | 12 | KBUILD_CFLAGS += $(call cc-option, -mno-sched-prolog-epilog) |
9 | KBUILD_CFLAGS += -mcmodel=large | 13 | KBUILD_CFLAGS += -mcmodel=large |
10 | 14 | ||
diff --git a/arch/nds32/include/asm/ftrace.h b/arch/nds32/include/asm/ftrace.h new file mode 100644 index 000000000000..bac7657f576a --- /dev/null +++ b/arch/nds32/include/asm/ftrace.h | |||
@@ -0,0 +1,20 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0 */ | ||
2 | |||
3 | #ifndef __ASM_NDS32_FTRACE_H | ||
4 | #define __ASM_NDS32_FTRACE_H | ||
5 | |||
6 | #ifdef CONFIG_FUNCTION_TRACER | ||
7 | |||
8 | #define HAVE_FUNCTION_GRAPH_FP_TEST | ||
9 | |||
10 | #define MCOUNT_ADDR ((unsigned long)(_mcount)) | ||
11 | /* mcount call is composed of three instructions: | ||
12 | * sethi + ori + jral | ||
13 | */ | ||
14 | #define MCOUNT_INSN_SIZE 12 | ||
15 | |||
16 | extern void _mcount(unsigned long parent_ip); | ||
17 | |||
18 | #endif /* CONFIG_FUNCTION_TRACER */ | ||
19 | |||
20 | #endif /* __ASM_NDS32_FTRACE_H */ | ||
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 | |||
21 | 21 | ||
22 | 22 | ||
23 | obj-y += vdso/ | 23 | obj-y += vdso/ |
24 | |||
25 | obj-$(CONFIG_FUNCTION_TRACER) += ftrace.o | ||
26 | |||
27 | ifdef CONFIG_FUNCTION_TRACER | ||
28 | CFLAGS_REMOVE_ftrace.o = $(CC_FLAGS_FTRACE) | ||
29 | 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 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | |||
3 | #include <linux/ftrace.h> | ||
4 | #include <linux/uaccess.h> | ||
5 | #include <asm/cacheflush.h> | ||
6 | |||
7 | extern void (*ftrace_trace_function)(unsigned long, unsigned long, | ||
8 | struct ftrace_ops*, struct pt_regs*); | ||
9 | |||
10 | noinline void __naked ftrace_stub(unsigned long ip, unsigned long parent_ip, | ||
11 | struct ftrace_ops *op, struct pt_regs *regs) | ||
12 | { | ||
13 | __asm__ (""); /* avoid to optimize as pure function */ | ||
14 | } | ||
15 | |||
16 | noinline void _mcount(unsigned long parent_ip) | ||
17 | { | ||
18 | /* save all state by the compiler prologue */ | ||
19 | |||
20 | unsigned long ip = (unsigned long)__builtin_return_address(0); | ||
21 | |||
22 | if (ftrace_trace_function != ftrace_stub) | ||
23 | ftrace_trace_function(ip - MCOUNT_INSN_SIZE, parent_ip, | ||
24 | NULL, NULL); | ||
25 | |||
26 | /* restore all state by the compiler epilogue */ | ||
27 | } | ||
28 | EXPORT_SYMBOL(_mcount); | ||