-
Notifications
You must be signed in to change notification settings - Fork 8.3k
arch/riscv: Defer locking of interrupt stack guard PMP entry #96189
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
arch/riscv: Defer locking of interrupt stack guard PMP entry #96189
Conversation
1d2b8fc to
a38482a
Compare
fkokosinski
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi, thanks for the PR!
The PMP entry for the interrupt stack guard is initially configured in z_riscv_pmp_init(). This entry was previously locked immediately using the PMP_L (Lock) flag.
Note that this means that this entry won’t be enforced within the M mode, as per specification:
In addition to locking the PMP entry, the L bit indicates whether the R/W/X permissions are
enforced on M-mode accesses. When the L bit is set, these permissions are enforced for all privilege modes. When the L bit is clear, any M-mode access matching the PMP entry will succeed; the R/W/X permissions apply only to S and U modes.
The essential locking of the interrupt stack guard will now be deferred and correctly applied within z_riscv_pmp_stackguard_enable()
Only when CONFIG_USERSPACE=y. What about other configurations?
https://github.com/zephyrproject-rtos/zephyr/blob/main/arch/riscv/core/isr.S#L361-L383
https://github.com/zephyrproject-rtos/zephyr/blob/main/arch/riscv/core/isr.S#L518-L587
npitre
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't understand what the problem is. Please could you elaborate some more?
Also the lock removal is not reflected in the preceding comment.
The statement about z_riscv_pmp_stackguard_enable() in the commit log is
wrong. This only takes care of the process stack not the IRQ stack (the later
never changes unlike the former).
0ea47b3 to
d807b5e
Compare
We have multi-stage firmware where we jump from RO firmware to RW firmware. The IRQ stack address is different for the 2 firmwares. With this entry being locked, the jumping between the firmware stages is blocked. If I make this entry unlocked, I can jump with no issues. I see that this entry is enabled with the other stackguard entries. I do not see why we cannot remove the locked permission and make it unlocked. It is going to be enforced. |
This specific PMP entry is conditionally defined and enforced. It is only active when both |
d807b5e to
be76d0f
Compare
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]>
be76d0f to
258305e
Compare
|
|
should be generalized in this PR: #99520 |



This commit addresses two aspects of PMP stack guarding on RISC-V:
The PMP entry for the interrupt stack guard, initially configured in
z_riscv_pmp_init(), was previously locked immediately using thePMP_Lflag. 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_Lflag from the PMP entry setup inz_riscv_pmp_init(). The essential locking is now deferred toz_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).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_offloadpath needs explicitmstatusconfiguration to activate the PMP protection for the interrupt stack.This change adds assembly instructions to
do_irq_offloadto properly configuremstatusbefore executing the offloaded routine:- Clear
mstatus.MPP(Machine Previous Privilege).- Set
mstatus.MPRVto 1.Setting
mstatus.MPRVmakes 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 whenCONFIG_PMP_STACK_GUARDandCONFIG_MULTITHREADINGare enabled.