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__  */

Reply via email to