mirror of
https://github.com/apache/nuttx.git
synced 2026-08-01 20:28:58 +00:00
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 <liang.huang@houmo.ai>
This commit is contained in:
parent
2f73fe2267
commit
32cf92db24
1 changed files with 54 additions and 31 deletions
|
|
@ -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 */
|
||||
|
||||
j 2f
|
||||
|
||||
1:
|
||||
/* Set sp to the high address of the interrupt stack (start of the
|
||||
* interrupt stack)
|
||||
*/
|
||||
|
||||
mv sp, \tmp0
|
||||
|
||||
2:
|
||||
setintstack_bounds \tmp0, \tmp1
|
||||
.endm
|
||||
#endif /* CONFIG_SMP && CONFIG_ARCH_INTERRUPTSTACK > 15 */
|
||||
|
||||
#if CONFIG_ARCH_INTERRUPTSTACK > 15
|
||||
#if !defined(CONFIG_SMP) && defined(CONFIG_ARCH_USE_S_MODE)
|
||||
#elif defined(CONFIG_ARCH_USE_S_MODE)
|
||||
.macro setintstack tmp0, tmp1
|
||||
csrr \tmp0, CSR_SCRATCH
|
||||
REGLOAD sp, RISCV_PERCPU_IRQSTACK(\tmp0)
|
||||
REGLOAD \tmp0, RISCV_PERCPU_IRQSTACK(\tmp0)
|
||||
|
||||
/* tmp0 = high address (top) of the interrupt stack for this hart */
|
||||
|
||||
li \tmp1, STACKFRAME_ALIGN_DOWN(CONFIG_ARCH_INTERRUPTSTACK)
|
||||
sub \tmp1, \tmp0, \tmp1
|
||||
|
||||
/* tmp1 = low address of the interrupt stack */
|
||||
|
||||
setintstack_bounds \tmp0, \tmp1
|
||||
.endm
|
||||
#endif /* !defined(CONFIG_SMP) && defined(CONFIG_ARCH_USE_S_MODE) */
|
||||
#endif /* defined(CONFIG_SMP) */
|
||||
|
||||
#endif /* CONFIG_ARCH_INTERRUPTSTACK > 15 */
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue