aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorSumanth Korikkar <sumanthk@linux.ibm.com>2025-02-24 12:27:04 +0100
committerVasily Gorbik <gor@linux.ibm.com>2025-03-04 17:15:19 +0100
commitb4a1dec11793936ffe1a9fb811724532ff3b1174 (patch)
tree78f7238337f87c591aac5a6bbe6dab2610e9fb0b
parentselftests/vDSO: Fix GNU hash table entry size for s390x (diff)
downloadwireguard-linux-b4a1dec11793936ffe1a9fb811724532ff3b1174.tar.xz
wireguard-linux-b4a1dec11793936ffe1a9fb811724532ff3b1174.zip
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: 7495e179b478 ("s390/tracing: Enable HAVE_FTRACE_GRAPH_FUNC") Reviewed-by: Heiko Carstens <hca@linux.ibm.com> Signed-off-by: Sumanth Korikkar <sumanthk@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
-rw-r--r--arch/s390/kernel/ftrace.c3
1 files changed, 2 insertions, 1 deletions
diff --git a/arch/s390/kernel/ftrace.c b/arch/s390/kernel/ftrace.c
index 63ba6306632e..e540b022ceb2 100644
--- a/arch/s390/kernel/ftrace.c
+++ b/arch/s390/kernel/ftrace.c
@@ -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;
}