Loading arch/blackfin/Kconfig +1 −0 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ config RWSEM_XCHGADD_ALGORITHM config BLACKFIN def_bool y select HAVE_FUNCTION_GRAPH_TRACER select HAVE_FUNCTION_TRACER select HAVE_IDE select HAVE_KERNEL_GZIP Loading arch/blackfin/kernel/Makefile +3 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,9 @@ else endif obj-$(CONFIG_FUNCTION_TRACER) += ftrace-entry.o obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o CFLAGS_REMOVE_ftrace.o = -pg obj-$(CONFIG_IPIPE) += ipipe.o obj-$(CONFIG_IPIPE_TRACE_MCOUNT) += mcount.o obj-$(CONFIG_BFIN_GPTIMERS) += gptimers.o Loading arch/blackfin/kernel/ftrace-entry.S +68 −0 Original line number Diff line number Diff line Loading @@ -35,6 +35,28 @@ ENTRY(__mcount) cc = r2 == r3; if ! cc jump .Ldo_trace; #ifdef CONFIG_FUNCTION_GRAPH_TRACER /* if the ftrace_graph_return function pointer is not set to * the ftrace_stub entry, call prepare_ftrace_return(). */ p0.l = _ftrace_graph_return; p0.h = _ftrace_graph_return; r3 = [p0]; cc = r2 == r3; if ! cc jump _ftrace_graph_caller; /* similarly, if the ftrace_graph_entry function pointer is not * set to the ftrace_graph_entry_stub entry, ... */ p0.l = _ftrace_graph_entry; p0.h = _ftrace_graph_entry; r2.l = _ftrace_graph_entry_stub; r2.h = _ftrace_graph_entry_stub; r3 = [p0]; cc = r2 == r3; if ! cc jump _ftrace_graph_caller; #endif r2 = [sp++]; rts; Loading @@ -61,6 +83,7 @@ ENTRY(__mcount) call (p0); /* restore state and get out of dodge */ .Lfinish_trace: rets = [sp++]; r1 = [sp++]; r0 = [sp++]; Loading @@ -70,3 +93,48 @@ ENTRY(__mcount) _ftrace_stub: rts; ENDPROC(__mcount) #ifdef CONFIG_FUNCTION_GRAPH_TRACER /* The prepare_ftrace_return() function is similar to the trace function * except it takes a pointer to the location of the frompc. This is so * the prepare_ftrace_return() can hijack it temporarily for probing * purposes. */ ENTRY(_ftrace_graph_caller) /* save first/second function arg and the return register */ [--sp] = r0; [--sp] = r1; [--sp] = rets; r0 = fp; r1 = rets; r0 += 4; r1 += -MCOUNT_INSN_SIZE; call _prepare_ftrace_return; jump .Lfinish_trace; ENDPROC(_ftrace_graph_caller) /* Undo the rewrite caused by ftrace_graph_caller(). The common function * ftrace_return_to_handler() will return the original rets so we can * restore it and be on our way. */ ENTRY(_return_to_handler) /* make sure original return values are saved */ [--sp] = p0; [--sp] = r0; [--sp] = r1; /* get original return address */ call _ftrace_return_to_handler; rets = r0; /* anomaly 05000371 - make sure we have at least three instructions * between rets setting and the return */ r1 = [sp++]; r0 = [sp++]; p0 = [sp++]; rts; ENDPROC(_return_to_handler) #endif arch/blackfin/kernel/ftrace.c 0 → 100644 +42 −0 Original line number Diff line number Diff line /* * ftrace graph code * * Copyright (C) 2009 Analog Devices Inc. * Licensed under the GPL-2 or later. */ #include <linux/ftrace.h> #include <linux/kernel.h> #include <linux/sched.h> #include <asm/atomic.h> #ifdef CONFIG_FUNCTION_GRAPH_TRACER /* * Hook the return address and push it in the stack of return addrs * in current thread info. */ void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr) { struct ftrace_graph_ent trace; unsigned long return_hooker = (unsigned long)&return_to_handler; if (unlikely(atomic_read(¤t->tracing_graph_pause))) return; if (ftrace_push_return_trace(*parent, self_addr, &trace.depth) == -EBUSY) return; trace.func = self_addr; /* Only trace if the calling function expects to */ if (!ftrace_graph_entry(&trace)) { current->curr_ret_stack--; return; } /* all is well in the world ! hijack RETS ... */ *parent = return_hooker; } #endif arch/blackfin/kernel/vmlinux.lds.S +1 −0 Original line number Diff line number Diff line Loading @@ -54,6 +54,7 @@ SECTIONS SCHED_TEXT #endif LOCK_TEXT IRQENTRY_TEXT KPROBES_TEXT *(.text.*) *(.fixup) Loading Loading
arch/blackfin/Kconfig +1 −0 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ config RWSEM_XCHGADD_ALGORITHM config BLACKFIN def_bool y select HAVE_FUNCTION_GRAPH_TRACER select HAVE_FUNCTION_TRACER select HAVE_IDE select HAVE_KERNEL_GZIP Loading
arch/blackfin/kernel/Makefile +3 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,9 @@ else endif obj-$(CONFIG_FUNCTION_TRACER) += ftrace-entry.o obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o CFLAGS_REMOVE_ftrace.o = -pg obj-$(CONFIG_IPIPE) += ipipe.o obj-$(CONFIG_IPIPE_TRACE_MCOUNT) += mcount.o obj-$(CONFIG_BFIN_GPTIMERS) += gptimers.o Loading
arch/blackfin/kernel/ftrace-entry.S +68 −0 Original line number Diff line number Diff line Loading @@ -35,6 +35,28 @@ ENTRY(__mcount) cc = r2 == r3; if ! cc jump .Ldo_trace; #ifdef CONFIG_FUNCTION_GRAPH_TRACER /* if the ftrace_graph_return function pointer is not set to * the ftrace_stub entry, call prepare_ftrace_return(). */ p0.l = _ftrace_graph_return; p0.h = _ftrace_graph_return; r3 = [p0]; cc = r2 == r3; if ! cc jump _ftrace_graph_caller; /* similarly, if the ftrace_graph_entry function pointer is not * set to the ftrace_graph_entry_stub entry, ... */ p0.l = _ftrace_graph_entry; p0.h = _ftrace_graph_entry; r2.l = _ftrace_graph_entry_stub; r2.h = _ftrace_graph_entry_stub; r3 = [p0]; cc = r2 == r3; if ! cc jump _ftrace_graph_caller; #endif r2 = [sp++]; rts; Loading @@ -61,6 +83,7 @@ ENTRY(__mcount) call (p0); /* restore state and get out of dodge */ .Lfinish_trace: rets = [sp++]; r1 = [sp++]; r0 = [sp++]; Loading @@ -70,3 +93,48 @@ ENTRY(__mcount) _ftrace_stub: rts; ENDPROC(__mcount) #ifdef CONFIG_FUNCTION_GRAPH_TRACER /* The prepare_ftrace_return() function is similar to the trace function * except it takes a pointer to the location of the frompc. This is so * the prepare_ftrace_return() can hijack it temporarily for probing * purposes. */ ENTRY(_ftrace_graph_caller) /* save first/second function arg and the return register */ [--sp] = r0; [--sp] = r1; [--sp] = rets; r0 = fp; r1 = rets; r0 += 4; r1 += -MCOUNT_INSN_SIZE; call _prepare_ftrace_return; jump .Lfinish_trace; ENDPROC(_ftrace_graph_caller) /* Undo the rewrite caused by ftrace_graph_caller(). The common function * ftrace_return_to_handler() will return the original rets so we can * restore it and be on our way. */ ENTRY(_return_to_handler) /* make sure original return values are saved */ [--sp] = p0; [--sp] = r0; [--sp] = r1; /* get original return address */ call _ftrace_return_to_handler; rets = r0; /* anomaly 05000371 - make sure we have at least three instructions * between rets setting and the return */ r1 = [sp++]; r0 = [sp++]; p0 = [sp++]; rts; ENDPROC(_return_to_handler) #endif
arch/blackfin/kernel/ftrace.c 0 → 100644 +42 −0 Original line number Diff line number Diff line /* * ftrace graph code * * Copyright (C) 2009 Analog Devices Inc. * Licensed under the GPL-2 or later. */ #include <linux/ftrace.h> #include <linux/kernel.h> #include <linux/sched.h> #include <asm/atomic.h> #ifdef CONFIG_FUNCTION_GRAPH_TRACER /* * Hook the return address and push it in the stack of return addrs * in current thread info. */ void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr) { struct ftrace_graph_ent trace; unsigned long return_hooker = (unsigned long)&return_to_handler; if (unlikely(atomic_read(¤t->tracing_graph_pause))) return; if (ftrace_push_return_trace(*parent, self_addr, &trace.depth) == -EBUSY) return; trace.func = self_addr; /* Only trace if the calling function expects to */ if (!ftrace_graph_entry(&trace)) { current->curr_ret_stack--; return; } /* all is well in the world ! hijack RETS ... */ *parent = return_hooker; } #endif
arch/blackfin/kernel/vmlinux.lds.S +1 −0 Original line number Diff line number Diff line Loading @@ -54,6 +54,7 @@ SECTIONS SCHED_TEXT #endif LOCK_TEXT IRQENTRY_TEXT KPROBES_TEXT *(.text.*) *(.fixup) Loading