Commit b4a1dec1 authored by Sumanth Korikkar's avatar Sumanth Korikkar Committed by Vasily Gorbik
Browse files

s390/ftrace: Fix return address recovery of traced function



When fgraph is enabled the traced function return address is replaced with
trampoline return_to_handler(). The original return address of the traced
function is saved in per task return stack along with a stack pointer for
reliable stack unwinding via function_graph_enter_regs().

During stack unwinding e.g. for livepatching, ftrace_graph_ret_addr()
identifies the original return address of the traced function with the
saved stack pointer.

With a recent change, the stack pointers passed to ftrace_graph_ret_addr()
and function_graph_enter_regs() do not match anymore, and therefore the
original return address is not found.

Pass the correct stack pointer to function_graph_enter_regs() to fix this.

Fixes: 7495e179 ("s390/tracing: Enable HAVE_FTRACE_GRAPH_FUNC")
Reviewed-by: default avatarHeiko Carstens <hca@linux.ibm.com>
Signed-off-by: default avatarSumanth Korikkar <sumanthk@linux.ibm.com>
Signed-off-by: default avatarVasily Gorbik <gor@linux.ibm.com>
parent a22ee38d
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -266,12 +266,13 @@ void ftrace_graph_func(unsigned long ip, unsigned long parent_ip,
		       struct ftrace_ops *op, struct ftrace_regs *fregs)
{
	unsigned long *parent = &arch_ftrace_regs(fregs)->regs.gprs[14];
	unsigned long sp = arch_ftrace_regs(fregs)->regs.gprs[15];

	if (unlikely(ftrace_graph_is_dead()))
		return;
	if (unlikely(atomic_read(&current->tracing_graph_pause)))
		return;
	if (!function_graph_enter_regs(*parent, ip, 0, parent, fregs))
	if (!function_graph_enter_regs(*parent, ip, 0, (unsigned long *)sp, fregs))
		*parent = (unsigned long)&return_to_handler;
}