From 7c75dbae2be880c62e84e642b243d35113ae3b77 Mon Sep 17 00:00:00 2001 From: "liang.huang" Date: Sat, 18 Jul 2026 08:12:10 +0800 Subject: [PATCH] arch/risc-v: preserve ra in up_idle() for fp-chain backtrace up_idle() is a leaf function; with frame pointers enabled the compiler skips spilling ra, corrupting the fp chain. Clobber "ra" in the WFI inline asm so backtrace can walk past the idle frame correctly. Assisted-by: Claude Code:claude-sonnet-5 Signed-off-by: liang.huang --- arch/risc-v/src/common/riscv_idle.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/arch/risc-v/src/common/riscv_idle.c b/arch/risc-v/src/common/riscv_idle.c index d6f0d02dcbf..6953a38bdca 100644 --- a/arch/risc-v/src/common/riscv_idle.c +++ b/arch/risc-v/src/common/riscv_idle.c @@ -71,7 +71,18 @@ void up_idle(void) * sleep in a reduced power mode until an interrupt occurs to save power */ - asm("WFI"); + /* up_idle() never calls another function, so with frame pointers + * enabled the compiler has no need to spill ra and skips it, leaving + * its slot in the fp-chain holding whatever was on the stack before. + * Clobbering "ra" forces it to be spilled/reloaded around WFI so the + * fp-chain backtrace sched_backtrace() relies on can find it. + */ + +#if defined(CONFIG_FRAME_POINTER) && defined(CONFIG_SCHED_BACKTRACE) + asm volatile ("WFI" : : : "ra"); +#else + asm volatile ("WFI"); +#endif #endif }