Skip to content

Commit 258305e

Browse files
committed
arch: riscv: Defer PMP lock and ensure stack guard in IRQ offload
This commit addresses two aspects of PMP stack guarding on RISC-V: 1. Defer Locking of Interrupt Stack Guard PMP Entry: The PMP entry for the interrupt stack guard, initially configured in `z_riscv_pmp_init()`, was previously locked immediately using the `PMP_L` flag. This immediate locking causes issues in complex boot scenarios, such as systems that jump from a Read-Only (RO) image to a Read-Write (RW) image. When switching images, the kernel must re-initialize PMP. If the interrupt stack address changes between the RO and RW stages, the already-locked PMP entry for the original address cannot be reconfigured. This change removes the premature `PMP_L` flag from the PMP entry setup in `z_riscv_pmp_init()`. The essential locking is now deferred to `z_riscv_pmp_stackguard_enable()`, which is executed only when the system is ready and the stack guard is enabled (`CONFIG_PMP_STACK_GUARD` && `CONFIG_MULTITHREADING`). 2. Enforce PMP Stack Guard during IRQ Offload: Since the PMP entry for the stack guard is no longer locked early in the boot process, we must ensure that the PMP settings are enforced in all critical execution contexts. The `do_irq_offload` path needs explicit `mstatus` configuration to activate the PMP protection for the interrupt stack. This change adds assembly instructions to `do_irq_offload` to properly configure `mstatus` before executing the offloaded routine: - Clear `mstatus.MPP` (Machine Previous Privilege). - Set `mstatus.MPRV` to 1. Setting `mstatus.MPRV` makes memory accesses within the offloaded IRQ routine behave as if they are occurring from M-mode, thus subjecting them to the PMP rules, including the stack guard entry. This is essential to ensure the stack guard is active during IRQ offloads, conditionally applied when `CONFIG_PMP_STACK_GUARD` and `CONFIG_MULTITHREADING` are enabled. Signed-off-by: Firas Sammoura <[email protected]>
1 parent d3e645e commit 258305e

File tree

2 files changed

+13
-1
lines changed

2 files changed

+13
-1
lines changed

arch/riscv/core/isr.S

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -486,6 +486,18 @@ do_fault:
486486

487487
#if defined(CONFIG_IRQ_OFFLOAD)
488488
do_irq_offload:
489+
490+
#if defined(CONFIG_PMP_STACK_GUARD) && defined(CONFIG_MULTITHREADING)
491+
/*
492+
* Re-activate Physical Memory Protection (PMP) for M-mode.
493+
* This ensures the stack guard remains active while running the offloaded IRQ.
494+
*/
495+
li t1, MSTATUS_MPP
496+
csrc mstatus, t1
497+
li t1, MSTATUS_MPRV
498+
csrs mstatus, t1
499+
#endif /* CONFIG_PMP_STACK_GUARD && CONFIG_MULTITHREADING */
500+
489501
/*
490502
* Retrieve provided routine and argument from the stack.
491503
* Routine pointer is in saved a0, argument in saved a1

arch/riscv/core/pmp.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -378,7 +378,7 @@ void z_riscv_pmp_init(void)
378378
* addresses inaccessible. This will never change so we do it here
379379
* and lock it too.
380380
*/
381-
set_pmp_entry(&index, PMP_NONE | PMP_L,
381+
set_pmp_entry(&index, PMP_NONE,
382382
(uintptr_t)z_interrupt_stacks[_current_cpu->id],
383383
Z_RISCV_STACK_GUARD_SIZE,
384384
pmp_addr, pmp_cfg, ARRAY_SIZE(pmp_addr));

0 commit comments

Comments
 (0)