nds32/ftrace: Support static function tracer
authorZong Li <zong@andestech.com>
Wed, 15 Aug 2018 02:45:59 +0000 (10:45 +0800)
committerGreentime Hu <greentime@andestech.com>
Tue, 4 Sep 2018 06:45:17 +0000 (14:45 +0800)
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>
arch/nds32/Kconfig
arch/nds32/Makefile
arch/nds32/include/asm/ftrace.h [new file with mode: 0644]
arch/nds32/kernel/Makefile
arch/nds32/kernel/ftrace.c [new file with mode: 0644]

index 1d4248fa55e995fdc7cba95f9209372ed6533b52..853497fe42666c87714ba1b2fbd93becea2322c2 100644 (file)
@@ -40,6 +40,7 @@ config NDS32
        select NO_IOPORT_MAP
        select RTC_LIB
        select THREAD_INFO_IN_TASK
+       select HAVE_FUNCTION_TRACER
        help
          Andes(nds32) Linux support.
 
index 63f4f173e5f4b97afa7078a3d8600fbfb50c13a6..3509fac104919ff8d9727d4cdfe2185d10473746 100644 (file)
@@ -5,6 +5,10 @@ KBUILD_DEFCONFIG := defconfig
 
 comma = ,
 
+ifdef CONFIG_FUNCTION_TRACER
+arch-y += -malways-save-lp -mno-relax
+endif
+
 KBUILD_CFLAGS  += $(call cc-option, -mno-sched-prolog-epilog)
 KBUILD_CFLAGS  += -mcmodel=large
 
diff --git a/arch/nds32/include/asm/ftrace.h b/arch/nds32/include/asm/ftrace.h
new file mode 100644 (file)
index 0000000..bac7657
--- /dev/null
@@ -0,0 +1,20 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#ifndef __ASM_NDS32_FTRACE_H
+#define __ASM_NDS32_FTRACE_H
+
+#ifdef CONFIG_FUNCTION_TRACER
+
+#define HAVE_FUNCTION_GRAPH_FP_TEST
+
+#define MCOUNT_ADDR ((unsigned long)(_mcount))
+/* mcount call is composed of three instructions:
+ * sethi + ori + jral
+ */
+#define MCOUNT_INSN_SIZE 12
+
+extern void _mcount(unsigned long parent_ip);
+
+#endif /* CONFIG_FUNCTION_TRACER */
+
+#endif /* __ASM_NDS32_FTRACE_H */
index 42792743e8b953290b7cec0b4722684c72744df3..27cded39fa66266171a427afc988ad9db35fe75e 100644 (file)
@@ -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 (file)
index 0000000..563f64c
--- /dev/null
@@ -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);