Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1ee76d7e authored by Mike Frysinger's avatar Mike Frysinger
Browse files

Blackfin: initial support for ftrace grapher

parent 1c873be7
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -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
+3 −0
Original line number Diff line number Diff line
@@ -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
+68 −0
Original line number Diff line number Diff line
@@ -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;

@@ -61,6 +83,7 @@ ENTRY(__mcount)
	call (p0);

	/* restore state and get out of dodge */
.Lfinish_trace:
	rets = [sp++];
	r1 = [sp++];
	r0 = [sp++];
@@ -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
+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(&current->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
+1 −0
Original line number Diff line number Diff line
@@ -54,6 +54,7 @@ SECTIONS
		SCHED_TEXT
#endif
		LOCK_TEXT
		IRQENTRY_TEXT
		KPROBES_TEXT
		*(.text.*)
		*(.fixup)