From: Shuai Xue <xueshuai@linux.alibaba.com>
To: palmer@dabbelt.com, pjw@kernel.org, aou@eecs.berkeley.edu
Cc: alex@ghiti.fr, linux-riscv@lists.infradead.org, oleg@redhat.com,
rostedt@goodmis.org, mhiramat@kernel.org, mark.rutland@arm.com,
peterz@infradead.org, mingo@redhat.com, acme@kernel.org,
namhyung@kernel.org, alexander.shishkin@linux.intel.com,
jolsa@kernel.org, irogers@google.com, adrian.hunter@intel.com,
james.clark@linaro.org, jpoimboe@kernel.org, jikos@kernel.org,
mbenes@suse.cz, pmladek@suse.com, joe.lawrence@redhat.com,
shuah@kernel.org, mpdesouza@suse.com, martin@kaiser.cx,
kmehltretter@gmail.com, oliver.yang@linux.alibaba.com,
zhuo.song@linux.alibaba.com, xueshuai@linux.alibaba.com,
jkchen@linux.alibaba.com, linux-kernel@vger.kernel.org,
linux-trace-kernel@vger.kernel.org,
linux-perf-users@vger.kernel.org, live-patching@vger.kernel.org,
linux-kselftest@vger.kernel.org
Subject: [PATCH v7 03/10] riscv: ftrace: use the frame pointer as the function graph return-address cookie
Date: Tue, 10 Nov 2026 09:37:43 +0800 [thread overview]
Message-ID: <20261110013750.36800-4-xueshuai@linux.alibaba.com> (raw)
In-Reply-To: <20261110013750.36800-1-xueshuai@linux.alibaba.com>
The function graph tracer stamps every shadow-stack entry with a
cookie, ftrace_ret_stack::retp, which stack unwinders later pass to
ftrace_graph_ret_addr() to recover a return address that the tracer
replaced with return_to_handler. The match is an exact pointer
comparison, so the producer and the consumer must agree on what the
cookie is. On riscv they don't:
* The dynamic ftrace path stores &arch_ftrace_regs(fregs)->ra, a
slot inside the transient ftrace trampoline frame. The frame is
popped as soon as the callback returns, so the stored cookie is
an address that no consumer can ever reproduce. It has never
matched anything since ftrace_graph_func() was introduced in
v6.8.
* The frame-pointer walker in walk_stackframe() passes &frame->ra,
the ra slot of a live frame record. That key matches the static
mcount path, which passes the callee's ra-slot address, but not
the dynamic path.
Since distro kernels only ever use the dynamic path, the net effect
is that the shadow stack is never consulted during unwinding:
whenever the function graph tracer is running, dump_stack(), perf
callchains and __get_wchan() report return_to_handler instead of the
real caller.
Switch the cookie to the architectural frame pointer, i.e. the
caller's frame-pointer value. Every party can reproduce it from the
frame records themselves:
* ftrace.c stores (void *)frame_pointer on both entry paths. At
ftrace entry the frame pointer is still the caller's, which is
the value the callee later saves in its frame_record::fp.
* walk_stackframe() passes that value, frame->fp, to
ftrace_graph_ret_addr() instead of the ra-slot address. The
static mcount path has to switch too: its old cookie (the
callee's ra-slot address) is exactly what the old walker key
matched, so leaving it behind would regress the static path.
This is the convention arm64 already uses: (void *)frame_pointer
from ftrace.c, the saved fp from the unwinder.
function_get_true_parent_ip() keeps passing the entry stack pointer
as its key; that key is only reproducible on architectures whose
return address lives at the entry stack pointer (x86). On riscv,
as on arm64, it keeps falling back to the raw parent ip.
Fixes: 35e61e8827ee8 ("riscv: ftrace: Make function graph use ftrace directly")
Suggested-by: Martin Kaiser <martin@kaiser.cx>
Cc: stable@vger.kernel.org
Signed-off-by: Shuai Xue <xueshuai@linux.alibaba.com>
---
arch/riscv/kernel/ftrace.c | 6 ++++--
arch/riscv/kernel/stacktrace.c | 3 ++-
2 files changed, 6 insertions(+), 3 deletions(-)
diff --git a/arch/riscv/kernel/ftrace.c b/arch/riscv/kernel/ftrace.c
index be8b68514417..0facd824c911 100644
--- a/arch/riscv/kernel/ftrace.c
+++ b/arch/riscv/kernel/ftrace.c
@@ -245,7 +245,8 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr,
*/
old = *parent;
- if (!function_graph_enter(old, self_addr, frame_pointer, parent))
+ if (!function_graph_enter(old, self_addr, frame_pointer,
+ (void *)frame_pointer))
*parent = return_hooker;
}
@@ -267,7 +268,8 @@ void ftrace_graph_func(unsigned long ip, unsigned long parent_ip,
*/
old = *parent;
- if (!function_graph_enter_regs(old, ip, frame_pointer, parent, fregs))
+ if (!function_graph_enter_regs(old, ip, frame_pointer,
+ (void *)frame_pointer, fregs))
*parent = return_hooker;
}
#endif /* CONFIG_DYNAMIC_FTRACE */
diff --git a/arch/riscv/kernel/stacktrace.c b/arch/riscv/kernel/stacktrace.c
index 28c5744889ba..a5abb705d43b 100644
--- a/arch/riscv/kernel/stacktrace.c
+++ b/arch/riscv/kernel/stacktrace.c
@@ -96,8 +96,9 @@ static __always_inline void __walk_stackframe(struct task_struct *task,
} else {
fp = READ_ONCE_TASK_STACK(task, frame->fp);
pc = READ_ONCE_TASK_STACK(task, frame->ra);
+ /* the cookie is the caller's frame pointer */
pc = ftrace_graph_ret_addr(task, &graph_idx, pc,
- &frame->ra);
+ (void *)fp);
if (pc >= (unsigned long)handle_exception &&
pc < (unsigned long)&ret_from_exception_end) {
if (unlikely(!fn(arg, pc)))
--
2.39.3
next prev parent reply other threads:[~2026-11-10 1:38 UTC|newest]
Thread overview: 27+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-14 9:26 [PATCH v6 0/7] riscv: Add reliable stack unwinding for livepatch Shuai Xue
2026-09-14 9:26 ` [PATCH v6 1/7] riscv: stacktrace: Add frame record metadata Shuai Xue
2026-09-14 9:26 ` [PATCH v6 2/7] riscv: stacktrace: disable KASAN and KCOV instrumentation for stacktrace.o Shuai Xue
2026-09-14 9:26 ` [PATCH v6 3/7] riscv: ftrace: always preserve s0 in dynamic ftrace register frame Shuai Xue
2026-09-14 9:26 ` [PATCH v6 4/7] riscv: stacktrace: introduce stack-bound tracking helpers Shuai Xue
2026-09-14 9:26 ` [PATCH v6 5/7] riscv: stacktrace: switch to frame-pointer based unwinder Shuai Xue
2026-10-09 18:59 ` Karl Mehltretter
2026-10-10 3:38 ` Shuai Xue
2026-10-13 20:18 ` Martin Kaiser
2026-10-14 13:09 ` Shuai Xue
2026-09-14 9:26 ` [PATCH v6 6/7] riscv: Kconfig: enable HAVE_RELIABLE_STACKTRACE and HAVE_LIVEPATCH Shuai Xue
2026-09-14 9:26 ` [PATCH v6 7/7] selftests/livepatch: Add RISC-V syscall wrapper prefix Shuai Xue
2026-09-29 7:28 ` [PATCH v6 0/7] riscv: Add reliable stack unwinding for livepatch Martin Kaiser
2026-10-08 11:42 ` Shuai Xue
2026-10-12 8:44 ` Martin Kaiser
2026-11-10 1:37 ` [PATCH v7 00/10] " Shuai Xue
2026-11-10 1:37 ` [PATCH v7 01/10] riscv: stacktrace: do not report the walker's own frame from arch_stack_walk() Shuai Xue
2026-11-10 1:37 ` [PATCH v7 02/10] riscv: Add KUnit test for stack trace start frames Shuai Xue
2026-11-10 1:37 ` Shuai Xue [this message]
2026-11-10 1:37 ` [PATCH v7 04/10] riscv: stacktrace: Add frame record metadata Shuai Xue
2026-11-10 1:37 ` [PATCH v7 05/10] riscv: stacktrace: disable KASAN and KCOV instrumentation for stacktrace.o Shuai Xue
2026-11-10 1:37 ` [PATCH v7 06/10] riscv: ftrace: always preserve s0 in dynamic ftrace register frame Shuai Xue
2026-11-10 1:37 ` [PATCH v7 07/10] riscv: stacktrace: introduce stack-bound tracking helpers Shuai Xue
2026-11-10 1:37 ` [PATCH v7 08/10] riscv: stacktrace: switch to frame-pointer based unwinder Shuai Xue
2026-11-10 1:37 ` [PATCH v7 09/10] riscv: Kconfig: enable HAVE_RELIABLE_STACKTRACE and HAVE_LIVEPATCH Shuai Xue
2026-11-10 1:37 ` [PATCH v7 10/10] selftests/livepatch: Add RISC-V syscall wrapper prefix Shuai Xue
2026-11-10 6:35 ` [PATCH v7 00/10] riscv: Add reliable stack unwinding for livepatch Karl Mehltretter
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261110013750.36800-4-xueshuai@linux.alibaba.com \
--to=xueshuai@linux.alibaba.com \
--cc=acme@kernel.org \
--cc=adrian.hunter@intel.com \
--cc=alex@ghiti.fr \
--cc=alexander.shishkin@linux.intel.com \
--cc=aou@eecs.berkeley.edu \
--cc=irogers@google.com \
--cc=james.clark@linaro.org \
--cc=jikos@kernel.org \
--cc=jkchen@linux.alibaba.com \
--cc=joe.lawrence@redhat.com \
--cc=jolsa@kernel.org \
--cc=jpoimboe@kernel.org \
--cc=kmehltretter@gmail.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-kselftest@vger.kernel.org \
--cc=linux-perf-users@vger.kernel.org \
--cc=linux-riscv@lists.infradead.org \
--cc=linux-trace-kernel@vger.kernel.org \
--cc=live-patching@vger.kernel.org \
--cc=mark.rutland@arm.com \
--cc=martin@kaiser.cx \
--cc=mbenes@suse.cz \
--cc=mhiramat@kernel.org \
--cc=mingo@redhat.com \
--cc=mpdesouza@suse.com \
--cc=namhyung@kernel.org \
--cc=oleg@redhat.com \
--cc=oliver.yang@linux.alibaba.com \
--cc=palmer@dabbelt.com \
--cc=peterz@infradead.org \
--cc=pjw@kernel.org \
--cc=pmladek@suse.com \
--cc=rostedt@goodmis.org \
--cc=shuah@kernel.org \
--cc=zhuo.song@linux.alibaba.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®