From: Michael Ellerman <mpe@kernel.org>
To: Rui Qi <qirui.001@bytedance.com>,
palmer@dabbelt.com, pjw@kernel.org, aou@eecs.berkeley.edu,
alex@ghiti.fr, conor@kernel.org
Cc: linux-riscv@lists.infradead.org, linux-kernel@vger.kernel.org,
samuel.holland@sifive.com, namcao@linutronix.de
Subject: Re: [PATCH] riscv: Fix 32-bit call_on_irq_stack() frame pointer ABI
Date: Thu, 25 Jun 2026 18:05:44 +1000 [thread overview]
Message-ID: <2e47388a-8883-4b44-b440-a00b8e622733@kernel.org> (raw)
In-Reply-To: <20260624113148.3723541-1-qirui.001@bytedance.com>
On 24/6/26 9:31 pm, Rui Qi wrote:
> From: Samuel Holland <samuel.holland@sifive.com>
>
> call_on_irq_stack() uses struct member offsets to set up its link in the
> frame record list. On riscv32, struct stackframe is the wrong size to
> maintain stack pointer alignment, so STACKFRAME_SIZE_ON_STACK includes
> padding. However, the ABI requires the frame record to be placed
> immediately below the address stored in s0, so the padding must come
> before the struct members.
>
> Fix the layout by making STACKFRAME_FP and STACKFRAME_RA the negative
> offsets from s0, instead of the positive offsets from sp.
The fact that all uses of the defines need to add back STACKFRAME_SIZE_ON_STACK
makes me think the defines don't have the most useful values.
If the values were offset + padding then the uses could be left unchanged.
> diff --git a/arch/riscv/kernel/asm-offsets.c b/arch/riscv/kernel/asm-offsets.c
> index af827448a609..a75f0cfea1e9 100644
> --- a/arch/riscv/kernel/asm-offsets.c
> +++ b/arch/riscv/kernel/asm-offsets.c
> @@ -501,8 +501,8 @@ void asm_offsets(void)
> OFFSET(SBI_HART_BOOT_STACK_PTR_OFFSET, sbi_hart_boot_data, stack_ptr);
>
> DEFINE(STACKFRAME_SIZE_ON_STACK, ALIGN(sizeof(struct stackframe), STACK_ALIGN));
> - OFFSET(STACKFRAME_FP, stackframe, fp);
> - OFFSET(STACKFRAME_RA, stackframe, ra);
> + DEFINE(STACKFRAME_FP, offsetof(struct stackframe, fp) - sizeof(struct stackframe));
> + DEFINE(STACKFRAME_RA, offsetof(struct stackframe, ra) - sizeof(struct stackframe));
ie. if they were defined as:
DEFINE(STACKFRAME_FP, ALIGN(sizeof(struct stackframe), STACK_ALIGN) -
sizeof(struct stackframe) + offsetof(struct stackframe, fp));
DEFINE(STACKFRAME_RA, ALIGN(sizeof(struct stackframe), STACK_ALIGN) -
sizeof(struct stackframe) + offsetof(struct stackframe, ra));
STACKFRAME_SIZE_ON_STACK - sizeof(stackframe) computes the size of the padding,
and then plus the offset gets you the right location.
That would allow the call sites to still use STACKFRAME_RA(sp).
I would probably also rename them to ON_STACK_RA or something, to make it clear
they are not offsets into struct stackframe any more, but maybe that's bike shedding :)
cheers
> #ifdef CONFIG_FUNCTION_TRACER
> DEFINE(FTRACE_OPS_FUNC, offsetof(struct ftrace_ops, func));
> #ifdef CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS
> diff --git a/arch/riscv/kernel/entry.S b/arch/riscv/kernel/entry.S
> index c6988983cdf7..08df724e13b9 100644
> --- a/arch/riscv/kernel/entry.S
> +++ b/arch/riscv/kernel/entry.S
> @@ -386,8 +386,8 @@ SYM_CODE_END(ret_from_fork_user_asm)
> SYM_FUNC_START(call_on_irq_stack)
> /* Create a frame record to save ra and s0 (fp) */
> addi sp, sp, -STACKFRAME_SIZE_ON_STACK
> - REG_S ra, STACKFRAME_RA(sp)
> - REG_S s0, STACKFRAME_FP(sp)
> + REG_S ra, (STACKFRAME_SIZE_ON_STACK + STACKFRAME_RA)(sp)
> + REG_S s0, (STACKFRAME_SIZE_ON_STACK + STACKFRAME_FP)(sp)
> addi s0, sp, STACKFRAME_SIZE_ON_STACK
>
> /* Switch to the per-CPU shadow call stack */
> @@ -405,8 +405,8 @@ SYM_FUNC_START(call_on_irq_stack)
>
> /* Switch back to the thread stack and restore ra and s0 */
> addi sp, s0, -STACKFRAME_SIZE_ON_STACK
> - REG_L ra, STACKFRAME_RA(sp)
> - REG_L s0, STACKFRAME_FP(sp)
> + REG_L ra, (STACKFRAME_SIZE_ON_STACK + STACKFRAME_RA)(sp)
> + REG_L s0, (STACKFRAME_SIZE_ON_STACK + STACKFRAME_FP)(sp)
> addi sp, sp, STACKFRAME_SIZE_ON_STACK
>
> ret
next prev parent reply other threads:[~2026-06-25 8:05 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-06-24 11:31 Rui Qi
2026-06-24 12:38 ` Nam Cao
2026-06-25 8:05 ` Michael Ellerman [this message]
2026-06-25 8:49 ` Nam Cao
2026-06-25 19:50 ` Paul Walmsley
2026-06-25 20:52 ` Samuel Holland
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=2e47388a-8883-4b44-b440-a00b8e622733@kernel.org \
--to=mpe@kernel.org \
--cc=alex@ghiti.fr \
--cc=aou@eecs.berkeley.edu \
--cc=conor@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-riscv@lists.infradead.org \
--cc=namcao@linutronix.de \
--cc=palmer@dabbelt.com \
--cc=pjw@kernel.org \
--cc=qirui.001@bytedance.com \
--cc=samuel.holland@sifive.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
Powered by JetHome