[PATCH v1 1/2] riscv: stacktrace: Remove bogus -0x4 offset in non-FP walk_stackframe

Paul Walmsley pjw at kernel.org
Thu Jun 4 16:41:10 PDT 2026


On Wed, 3 Jun 2026, Rui Qi wrote:

> In the non-frame-pointer version of walk_stackframe, each value read
> from the stack is treated as a potential return address and has 0x4
> subtracted before being used as the program counter. This was intended
> to convert the return address (the instruction after a call) back to
> the call site, but it is incorrect:
> 
> 1. RISC-V has variable-length instructions due to the RVC (compressed
>    instruction) extension. A call instruction can be either 4 bytes
>    (regular) or 2 bytes (compressed, e.g. c.jal). Subtracting a fixed
>    0x4 assumes all call instructions are 4 bytes, which is wrong for
>    compressed instructions.
> 
> 2. Stack traces conventionally report return addresses, not call sites.
>    Other architectures (ARM64, x86, ARM) do not subtract instruction
>    size from return addresses in their stack unwinding code.
> 
> 3. The frame-pointer version of walk_stackframe already dropped the
>    -0x4 offset. Commit b785ec129bd9 ("riscv/ftrace: Add
>    HAVE_FUNCTION_GRAPH_RET_ADDR_PTR support") replaced "pc =
>    frame->ra - 0x4" with ftrace_graph_ret_addr(), and the commit
>    message explicitly noted that "the original calculation, pc =
>    frame->ra - 4, is buggy when the instruction at the return address
>    happened to be a compressed inst." The non-FP version was simply
>    overlooked.
> 
> Remove the bogus -0x4 offset to match the FP version and the
> conventions used by other architectures.

Thanks for the very clear commit message and for the fix.  Queued for 
v7.1-rc.


- Paul



More information about the linux-riscv mailing list