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

Commit 46542888 authored by Steven Rostedt's avatar Steven Rostedt Committed by Benjamin Herrenschmidt
Browse files

powerpc64, tracing: add function graph tracer with dynamic tracing



This is the port of the function graph tracer to PowerPC with
dynamic tracing.

Geoff Lavand tested on PS3.

Tested-by: default avatarGeoff Levand <geoffrey.levand@am.sony.com>
Acked-by: default avatarBenjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: default avatarSteven Rostedt <srostedt@redhat.com>
Signed-off-by: default avatarBenjamin Herrenschmidt <benh@kernel.crashing.org>
parent 6794c782
Loading
Loading
Loading
Loading
+1 −1
Original line number Original line Diff line number Diff line
@@ -111,7 +111,7 @@ config PPC
	select HAVE_FTRACE_MCOUNT_RECORD
	select HAVE_FTRACE_MCOUNT_RECORD
	select HAVE_DYNAMIC_FTRACE
	select HAVE_DYNAMIC_FTRACE
	select HAVE_FUNCTION_TRACER
	select HAVE_FUNCTION_TRACER
	select HAVE_FUNCTION_GRAPH_TRACER if !DYNAMIC_FTRACE && PPC64
	select HAVE_FUNCTION_GRAPH_TRACER if PPC64
	select ARCH_WANT_OPTIONAL_GPIOLIB
	select ARCH_WANT_OPTIONAL_GPIOLIB
	select HAVE_IDE
	select HAVE_IDE
	select HAVE_IOREMAP_PROT
	select HAVE_IOREMAP_PROT
+7 −1
Original line number Original line Diff line number Diff line
@@ -908,6 +908,12 @@ _GLOBAL(ftrace_caller)
ftrace_call:
ftrace_call:
	bl	ftrace_stub
	bl	ftrace_stub
	nop
	nop
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
.globl ftrace_graph_call
ftrace_graph_call:
	b	ftrace_graph_stub
_GLOBAL(ftrace_graph_stub)
#endif
	ld	r0, 128(r1)
	ld	r0, 128(r1)
	mtlr	r0
	mtlr	r0
	addi	r1, r1, 112
	addi	r1, r1, 112
@@ -946,7 +952,7 @@ _GLOBAL(ftrace_stub)
#endif /* CONFIG_DYNAMIC_FTRACE */
#endif /* CONFIG_DYNAMIC_FTRACE */


#ifdef CONFIG_FUNCTION_GRAPH_TRACER
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
ftrace_graph_caller:
_GLOBAL(ftrace_graph_caller)
	/* load r4 with local address */
	/* load r4 with local address */
	ld	r4, 128(r1)
	ld	r4, 128(r1)
	subi	r4, r4, MCOUNT_INSN_SIZE
	subi	r4, r4, MCOUNT_INSN_SIZE
+41 −6
Original line number Original line Diff line number Diff line
@@ -43,7 +43,8 @@ static unsigned char *ftrace_nop_replace(void)
	return (char *)&ftrace_nop;
	return (char *)&ftrace_nop;
}
}


static unsigned char *ftrace_call_replace(unsigned long ip, unsigned long addr)
static unsigned char *
ftrace_call_replace(unsigned long ip, unsigned long addr, int link)
{
{
	static unsigned int op;
	static unsigned int op;


@@ -55,8 +56,9 @@ static unsigned char *ftrace_call_replace(unsigned long ip, unsigned long addr)
	 */
	 */
	addr = GET_ADDR(addr);
	addr = GET_ADDR(addr);


	/* Set to "bl addr" */
	/* if (link) set op to 'bl' else 'b' */
	op = 0x48000001 | (ftrace_calc_offset(ip, addr) & 0x03fffffc);
	op = 0x48000000 | (link ? 1 : 0);
	op |= (ftrace_calc_offset(ip, addr) & 0x03fffffc);


	/*
	/*
	 * No locking needed, this must be called via kstop_machine
	 * No locking needed, this must be called via kstop_machine
@@ -344,7 +346,7 @@ int ftrace_make_nop(struct module *mod,
	 */
	 */
	if (test_24bit_addr(ip, addr)) {
	if (test_24bit_addr(ip, addr)) {
		/* within range */
		/* within range */
		old = ftrace_call_replace(ip, addr);
		old = ftrace_call_replace(ip, addr, 1);
		new = ftrace_nop_replace();
		new = ftrace_nop_replace();
		return ftrace_modify_code(ip, old, new);
		return ftrace_modify_code(ip, old, new);
	}
	}
@@ -484,7 +486,7 @@ int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
	if (test_24bit_addr(ip, addr)) {
	if (test_24bit_addr(ip, addr)) {
		/* within range */
		/* within range */
		old = ftrace_nop_replace();
		old = ftrace_nop_replace();
		new = ftrace_call_replace(ip, addr);
		new = ftrace_call_replace(ip, addr, 1);
		return ftrace_modify_code(ip, old, new);
		return ftrace_modify_code(ip, old, new);
	}
	}


@@ -513,7 +515,7 @@ int ftrace_update_ftrace_func(ftrace_func_t func)
	int ret;
	int ret;


	memcpy(old, &ftrace_call, MCOUNT_INSN_SIZE);
	memcpy(old, &ftrace_call, MCOUNT_INSN_SIZE);
	new = ftrace_call_replace(ip, (unsigned long)func);
	new = ftrace_call_replace(ip, (unsigned long)func, 1);
	ret = ftrace_modify_code(ip, old, new);
	ret = ftrace_modify_code(ip, old, new);


	return ret;
	return ret;
@@ -532,6 +534,39 @@ int __init ftrace_dyn_arch_init(void *data)


#ifdef CONFIG_FUNCTION_GRAPH_TRACER
#ifdef CONFIG_FUNCTION_GRAPH_TRACER


#ifdef CONFIG_DYNAMIC_FTRACE
extern void ftrace_graph_call(void);
extern void ftrace_graph_stub(void);

int ftrace_enable_ftrace_graph_caller(void)
{
	unsigned long ip = (unsigned long)(&ftrace_graph_call);
	unsigned long addr = (unsigned long)(&ftrace_graph_caller);
	unsigned long stub = (unsigned long)(&ftrace_graph_stub);
	unsigned char old[MCOUNT_INSN_SIZE], *new;

	new = ftrace_call_replace(ip, stub, 0);
	memcpy(old, new, MCOUNT_INSN_SIZE);
	new = ftrace_call_replace(ip, addr, 0);

	return ftrace_modify_code(ip, old, new);
}

int ftrace_disable_ftrace_graph_caller(void)
{
	unsigned long ip = (unsigned long)(&ftrace_graph_call);
	unsigned long addr = (unsigned long)(&ftrace_graph_caller);
	unsigned long stub = (unsigned long)(&ftrace_graph_stub);
	unsigned char old[MCOUNT_INSN_SIZE], *new;

	new = ftrace_call_replace(ip, addr, 0);
	memcpy(old, new, MCOUNT_INSN_SIZE);
	new = ftrace_call_replace(ip, stub, 0);

	return ftrace_modify_code(ip, old, new);
}
#endif /* CONFIG_DYNAMIC_FTRACE */

/*
/*
 * Hook the return address and push it in the stack of return addrs
 * Hook the return address and push it in the stack of return addrs
 * in current thread info.
 * in current thread info.