On Wed, 22 Oct 2025 14:32:19 +0200 Jiri Olsa <[email protected]> wrote:
> thanks for the report.. so above is from arm? > > yes the x86_64 starts with: > unwind_start(&state, current, NULL, (void *)regs->sp); > > I seems to get reasonable stack traces on x86 with the change below, > which just initializes fields in regs that are used later on and sets > the stack so the ftrace_graph_ret_addr code is triggered during unwind > > but I'm not familiar with this code, Masami, Josh, any idea? Oh! This is an issue with a stack trace happening from a callback of the exit handler? OK, that makes much more sense. As I don't think the code handles that properly. > > thanks, > jirka > > > --- > diff --git a/arch/x86/kernel/ftrace_64.S b/arch/x86/kernel/ftrace_64.S > index 367da3638167..2d2bb8c37b56 100644 > --- a/arch/x86/kernel/ftrace_64.S > +++ b/arch/x86/kernel/ftrace_64.S > @@ -353,6 +353,8 @@ STACK_FRAME_NON_STANDARD_FP(__fentry__) > SYM_CODE_START(return_to_handler) > UNWIND_HINT_UNDEFINED I believe the above UNWIND_HINT_UNDEFINED means that if ORC were to hit this, it should just give up. This is because tracing the exit of the function really doesn't fit in the normal execution paradigm. The entry is easy. It's the same as if the callback was called by the function being traced. The exit is more difficult because the function being traced has already did its return. Now the callback is in this limbo area of being called between a return and the caller. > ANNOTATE_NOENDBR > + push $return_to_handler > + UNWIND_HINT_FUNC OK, so what happened here is that you put in the return_to_handle into the stack and told ORC that this is a normal function, and that when it triggers to do a lookup from the handler itself. I wonder if we could just add a new UNWIND_HINT that tells ORC to do that? > > /* Save ftrace_regs for function exit context */ > subq $(FRAME_SIZE), %rsp > @@ -360,6 +362,9 @@ SYM_CODE_START(return_to_handler) > movq %rax, RAX(%rsp) > movq %rdx, RDX(%rsp) > movq %rbp, RBP(%rsp) > + movq %rsp, RSP(%rsp) > + movq $0, EFLAGS(%rsp) > + movq $__KERNEL_CS, CS(%rsp) Is this simulating some kind of interrupt? > movq %rsp, %rdi > > call ftrace_return_to_handler Now it gets tricky in the ftrace_return_to_handler as the first thing it does is to pop the shadow stack, which makes the return_to_handler lookup different, as its no longer on the stack that the unwinder will use. The return address will live in the "ret" variable of that function, which the unwinder will not have access to. Yeah, this will not be easy to solve. -- Steve > @@ -368,7 +373,8 @@ SYM_CODE_START(return_to_handler) > movq RDX(%rsp), %rdx > movq RAX(%rsp), %rax > > - addq $(FRAME_SIZE), %rsp > + addq $(FRAME_SIZE) + 8, %rsp > + > /* > * Jump back to the old return address. This cannot be JMP_NOSPEC rdi > * since IBT would demand that contain ENDBR, which simply isn't so for
