This is an automated email from the ASF dual-hosted git repository.
acassis pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git
The following commit(s) were added to refs/heads/master by this push:
new 42d684b02fd arch/risc-v: qemu: don't rewind interrupt stack sp on
nested trap
42d684b02fd is described below
commit 42d684b02fd7a6bd395a2b018228c1e430d92ea2
Author: liang.huang <[email protected]>
AuthorDate: Sat Jul 18 11:38:40 2026 +0800
arch/risc-v: qemu: don't rewind interrupt stack sp on nested trap
qemu-rv's S-mode/non-SMP setintstack unconditionally reloaded sp to
the top of the per-cpu interrupt stack. A trap taken while already
running on that stack rewound sp back to the same address, so the
nested trap's frame overwrote the still-live outer trap's frame.
Port the bounds check already used by the canonical setintstack in
riscv_macros.S: only move sp when it is outside the interrupt stack
range.
Other vendor chip.h files have the same unconditional-reload pattern
and are left for a follow-up.
Signed-off-by: liang.huang <[email protected]>
---
arch/risc-v/src/qemu-rv/chip.h | 81 +++++++++++++++++++++++++++---------------
1 file changed, 52 insertions(+), 29 deletions(-)
diff --git a/arch/risc-v/src/qemu-rv/chip.h b/arch/risc-v/src/qemu-rv/chip.h
index 8c92d861644..91cb8f93a3c 100644
--- a/arch/risc-v/src/qemu-rv/chip.h
+++ b/arch/risc-v/src/qemu-rv/chip.h
@@ -47,6 +47,45 @@
#ifdef __ASSEMBLY__
+#if CONFIG_ARCH_INTERRUPTSTACK > 15
+
+/****************************************************************************
+ * Name: setintstack_bounds
+ *
+ * Description:
+ * Set sp to high if sp is outside [low, high], the bounds of the
+ * interrupt stack for the current CPU.
+ *
+ ****************************************************************************/
+
+.macro setintstack_bounds high, low
+
+ /* Check if sp is below the low address of the interrupt stack
+ * (outside the interrupt stack).
+ */
+
+ blt sp, \low, 1f
+
+ /* Check if sp is above the high address of the interrupt stack
+ * (outside the interrupt stack)
+ */
+
+ bgt sp, \high, 1f
+
+ /* If sp is within the interrupt stack boundaries, no action is required */
+
+ j 2f
+
+1:
+ /* Set sp to the high address of the interrupt stack (start of the
+ * interrupt stack)
+ */
+
+ mv sp, \high
+
+2:
+.endm
+
/****************************************************************************
* Name: setintstack
*
@@ -56,7 +95,7 @@
*
****************************************************************************/
-#if defined(CONFIG_SMP) && CONFIG_ARCH_INTERRUPTSTACK > 15
+#if defined(CONFIG_SMP)
.macro setintstack tmp0, tmp1
up_cpu_index \tmp0
li \tmp1, STACKFRAME_ALIGN_DOWN(CONFIG_ARCH_INTERRUPTSTACK)
@@ -76,40 +115,24 @@
sub \tmp1, \tmp0, \tmp1
- /* Check if sp is below the low address of the interrupt stack
- * (outside the interrupt stack).
- */
-
- blt sp, \tmp1, 1f
-
- /* Check if sp is above the high address of the interrupt stack
- * (outside the interrupt stack)
- */
-
- bgt sp, \tmp0, 1f
-
- /* If sp is within the interrupt stack boundaries, no action is required */
+ setintstack_bounds \tmp0, \tmp1
+.endm
+#elif defined(CONFIG_ARCH_USE_S_MODE)
+.macro setintstack tmp0, tmp1
+ csrr \tmp0, CSR_SCRATCH
+ REGLOAD \tmp0, RISCV_PERCPU_IRQSTACK(\tmp0)
- j 2f
+ /* tmp0 = high address (top) of the interrupt stack for this hart */
-1:
- /* Set sp to the high address of the interrupt stack (start of the
- * interrupt stack)
- */
+ li \tmp1, STACKFRAME_ALIGN_DOWN(CONFIG_ARCH_INTERRUPTSTACK)
+ sub \tmp1, \tmp0, \tmp1
- mv sp, \tmp0
+ /* tmp1 = low address of the interrupt stack */
-2:
+ setintstack_bounds \tmp0, \tmp1
.endm
-#endif /* CONFIG_SMP && CONFIG_ARCH_INTERRUPTSTACK > 15 */
+#endif /* defined(CONFIG_SMP) */
-#if CONFIG_ARCH_INTERRUPTSTACK > 15
-#if !defined(CONFIG_SMP) && defined(CONFIG_ARCH_USE_S_MODE)
-.macro setintstack tmp0, tmp1
- csrr \tmp0, CSR_SCRATCH
- REGLOAD sp, RISCV_PERCPU_IRQSTACK(\tmp0)
-.endm
-#endif /* !defined(CONFIG_SMP) && defined(CONFIG_ARCH_USE_S_MODE) */
#endif /* CONFIG_ARCH_INTERRUPTSTACK > 15 */
#endif /* __ASSEMBLY__ */