From 230c77a5e92a29bf21e98ee35e22b0537f61c55b Mon Sep 17 00:00:00 2001 From: Guo Ren Date: Sun, 9 Dec 2018 14:29:59 +0800 Subject: csky: basic ftrace supported When gcc with -pg, it'll add _mcount stub in every function. We need implement the _mcount in kernel and ftrace depends on stackstrace. To do: call-graph, dynamic ftrace Signed-off-by: Guo Ren --- arch/csky/kernel/ftrace.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 arch/csky/kernel/ftrace.c (limited to 'arch/csky/kernel/ftrace.c') diff --git a/arch/csky/kernel/ftrace.c b/arch/csky/kernel/ftrace.c new file mode 100644 index 000000000000..ad054f7190f9 --- /dev/null +++ b/arch/csky/kernel/ftrace.c @@ -0,0 +1,24 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd. + +#include +#include + +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 volatile ("\n"); +} + +noinline void csky_mcount(unsigned long from_pc, unsigned long self_pc) +{ + if (ftrace_trace_function != ftrace_stub) + ftrace_trace_function(self_pc, from_pc, NULL, NULL); +} + +/* _mcount is defined in abi's mcount.S */ +EXPORT_SYMBOL(_mcount); -- cgit From d7950be145c84ca5094c52bc1ad1e7f1893d0f19 Mon Sep 17 00:00:00 2001 From: Guo Ren Date: Sat, 15 Dec 2018 21:04:27 +0800 Subject: csky: ftrace call graph supported. With csky-gcc -pg -mbacktrace, ftrace call graph supported. Signed-off-by: Guo Ren --- arch/csky/kernel/ftrace.c | 48 ++++++++++++++++++++++++++++++++++++----------- 1 file changed, 37 insertions(+), 11 deletions(-) (limited to 'arch/csky/kernel/ftrace.c') diff --git a/arch/csky/kernel/ftrace.c b/arch/csky/kernel/ftrace.c index ad054f7190f9..274c431f1810 100644 --- a/arch/csky/kernel/ftrace.c +++ b/arch/csky/kernel/ftrace.c @@ -4,21 +4,47 @@ #include #include -extern void (*ftrace_trace_function)(unsigned long, unsigned long, - struct ftrace_ops*, struct pt_regs*); +#ifdef CONFIG_FUNCTION_GRAPH_TRACER +void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr, + unsigned long frame_pointer) +{ + unsigned long return_hooker = (unsigned long)&return_to_handler; + unsigned long old; + if (unlikely(atomic_read(¤t->tracing_graph_pause))) + return; -noinline void __naked ftrace_stub(unsigned long ip, unsigned long parent_ip, - struct ftrace_ops *op, struct pt_regs *regs) -{ - asm volatile ("\n"); -} + old = *parent; -noinline void csky_mcount(unsigned long from_pc, unsigned long self_pc) -{ - if (ftrace_trace_function != ftrace_stub) - ftrace_trace_function(self_pc, from_pc, NULL, NULL); + if (!function_graph_enter(old, self_addr, + *(unsigned long *)frame_pointer, parent)) { + /* + * For csky-gcc function has sub-call: + * subi sp, sp, 8 + * stw r8, (sp, 0) + * mov r8, sp + * st.w r15, (sp, 0x4) + * push r15 + * jl _mcount + * We only need set *parent for resume + * + * For csky-gcc function has no sub-call: + * subi sp, sp, 4 + * stw r8, (sp, 0) + * mov r8, sp + * push r15 + * jl _mcount + * We need set *parent and *(frame_pointer + 4) for resume, + * because lr is resumed twice. + */ + *parent = return_hooker; + frame_pointer += 4; + if (*(unsigned long *)frame_pointer == old) + *(unsigned long *)frame_pointer = return_hooker; + } } +#endif /* _mcount is defined in abi's mcount.S */ +extern void _mcount(void); EXPORT_SYMBOL(_mcount); -- cgit