Commit 1256e70a authored by Sven Schnelle's avatar Sven Schnelle Committed by Heiko Carstens
Browse files

s390/ftrace: enable HAVE_FUNCTION_GRAPH_RETVAL



Add support for tracing return values in the function graph tracer.
This requires return_to_handler() to record gpr2 and the frame pointer

Signed-off-by: default avatarSven Schnelle <svens@linux.ibm.com>
Reviewed-by: default avatarHeiko Carstens <hca@linux.ibm.com>
Signed-off-by: default avatarHeiko Carstens <hca@linux.ibm.com>
parent 3325b4d8
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -174,6 +174,7 @@ config S390
	select HAVE_FTRACE_MCOUNT_RECORD
	select HAVE_FUNCTION_ARG_ACCESS_API
	select HAVE_FUNCTION_ERROR_INJECTION
	select HAVE_FUNCTION_GRAPH_RETVAL
	select HAVE_FUNCTION_GRAPH_TRACER
	select HAVE_FUNCTION_TRACER
	select HAVE_GCC_PLUGINS
+17 −0
Original line number Diff line number Diff line
@@ -54,6 +54,23 @@ static __always_inline struct pt_regs *arch_ftrace_get_regs(struct ftrace_regs *
	return NULL;
}

#ifdef CONFIG_FUNCTION_GRAPH_TRACER
struct fgraph_ret_regs {
	unsigned long gpr2;
	unsigned long fp;
};

static __always_inline unsigned long fgraph_ret_regs_return_value(struct fgraph_ret_regs *ret_regs)
{
	return ret_regs->gpr2;
}

static __always_inline unsigned long fgraph_ret_regs_frame_pointer(struct fgraph_ret_regs *ret_regs)
{
	return ret_regs->fp;
}
#endif /* CONFIG_FUNCTION_GRAPH_TRACER */

static __always_inline unsigned long
ftrace_regs_get_instruction_pointer(const struct ftrace_regs *fregs)
{
+7 −0
Original line number Diff line number Diff line
@@ -12,6 +12,7 @@
#include <linux/sched.h>
#include <linux/purgatory.h>
#include <linux/pgtable.h>
#include <linux/ftrace.h>
#include <asm/idle.h>
#include <asm/gmap.h>
#include <asm/stacktrace.h>
@@ -177,5 +178,11 @@ int main(void)
	DEFINE(OLDMEM_SIZE, PARMAREA + offsetof(struct parmarea, oldmem_size));
	DEFINE(COMMAND_LINE, PARMAREA + offsetof(struct parmarea, command_line));
	DEFINE(MAX_COMMAND_LINE_SIZE, PARMAREA + offsetof(struct parmarea, max_command_line_size));
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
	/* function graph return value tracing */
	OFFSET(__FGRAPH_RET_GPR2, fgraph_ret_regs, gpr2);
	OFFSET(__FGRAPH_RET_FP, fgraph_ret_regs, fp);
	DEFINE(__FGRAPH_RET_SIZE, sizeof(struct fgraph_ret_regs));
#endif
	return 0;
}
+6 −2
Original line number Diff line number Diff line
@@ -128,10 +128,14 @@ SYM_CODE_END(ftrace_common)
SYM_FUNC_START(return_to_handler)
	stmg	%r2,%r5,32(%r15)
	lgr	%r1,%r15
	aghi	%r15,-STACK_FRAME_OVERHEAD
	aghi	%r15,-(STACK_FRAME_OVERHEAD+__FGRAPH_RET_SIZE)
	stg	%r1,__SF_BACKCHAIN(%r15)
	aghik	%r3,%r15,STACK_FRAME_OVERHEAD
	stg	%r1,__FGRAPH_RET_FP(%r3)
	stg	%r2,__FGRAPH_RET_GPR2(%r3)
	lgr	%r2,%r3
	brasl	%r14,ftrace_return_to_handler
	aghi	%r15,STACK_FRAME_OVERHEAD
	aghi	%r15,STACK_FRAME_OVERHEAD+__FGRAPH_RET_SIZE
	lgr	%r14,%r2
	lmg	%r2,%r5,32(%r15)
	BR_EX	%r14