From 5fc5beabe2e9dd9e815f2bf13c9708ceabd858dc Mon Sep 17 00:00:00 2001 From: Jim Shu Date: Sun, 9 Jan 2022 22:01:02 +0800 Subject: [PATCH] arch: riscv: pmp: fix IRQ handling of PMP stack guard This commit add 2 minor fixes of IRQ handling: 1. Save caller registers before calling z_riscv_configure_stack_guard() in RISC-V assembly. 2. reschedule and no_reschdule code paths use different interrupt return path after supporting of CONFIG_PMP_STACK_GUARD. back-to-back interrupt checking is in the reschedule code path so that it should jump to interrupt return path of reschedule. Signed-off-by: Jim Shu --- arch/riscv/core/isr.S | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/arch/riscv/core/isr.S b/arch/riscv/core/isr.S index 6df73ad04c6..1ff01443157 100644 --- a/arch/riscv/core/isr.S +++ b/arch/riscv/core/isr.S @@ -831,7 +831,7 @@ reschedule: la t0, _kernel RV_OP_LOADREG t2, _kernel_offset_to_current(t0) RV_OP_LOADREG t3, _kernel_offset_to_ready_q_cache(t0) - beq t2, t3, no_reschedule + beq t2, t3, no_reschedule_resched #if CONFIG_INSTRUMENT_THREAD_SWITCHING call z_thread_mark_switched_out @@ -925,8 +925,16 @@ skip_load_fp_callee_saved: #ifdef CONFIG_PMP_STACK_GUARD mv a0, t1 /* kernel current */ + + /* Save t0/t1 caller registers for function call */ + addi sp, sp, -16 + RV_OP_STOREREG t0, 0(sp) + RV_OP_STOREREG t1, 8(sp) jal ra, z_riscv_configure_stack_guard -#endif // CONFIG_PMP_STACK_GUARD + RV_OP_LOADREG t0, 0(sp) + RV_OP_LOADREG t1, 8(sp) + addi sp, sp, 16 +#endif /* CONFIG_PMP_STACK_GUARD */ #ifdef CONFIG_USERSPACE /* t0 still reference to _kernel */ @@ -957,6 +965,15 @@ kernel_swap: call z_thread_mark_switched_in #endif + /* + * no_reschedule_resched is an another interrupt return path. + * + * When CONFIG_PMP_STACK_GUARD=y, reschedule & no_reschedule + * code paths use different sp and only no_reschedule code path + * needs to switch sp before interrupt return. Thus, we use + * another interrupt return path for reschedule path. + */ +no_reschedule_resched: #ifdef CONFIG_RISCV_SOC_CONTEXT_SAVE /* Restore context at SOC level */ addi a0, sp, __z_arch_esf_t_soc_context_OFFSET