Skip to content

Commit 8fd7348

Browse files
committed
RISCV: PMP: Use correct pmpcfg index for multi-register configurations
The PMP initialization and thread context switching logic was incorrectly assuming that the configuration for all global PMP entries was located within the first PMP configuration register, pmpcfg0 (represented by pmp_cfg[0]). Each pmpcfg register holds the configuration for four PMP entries. As the number of PMP entries increases and exceeds four, the configuration data spills over into higher-indexed pmpcfg registers (e.g., pmpcfg1). It is essential to store and restore the proper pmpcfg register content to maintain the state of the system protection boundaries. This patch fixes the indexing by calculating the correct pmpcfg array index using integer division (index / 4) in two places: 1) z_riscv_pmp_init: Correctly saves the final global PMP entry's configuration from pmp_cfg[index / 4]. 2) z_riscv_pmp_thread_init: Correctly restores the saved configuration to the appropriate pmp_cfg register index (global_pmp_end_index / 4) during thread setup. The patch also updates the write_pmp_entries call in z_riscv_pmp_stackguard_enable to use the correct, generalized function signature. Signed-off-by: Firas Sammoura <[email protected]>
1 parent dddd738 commit 8fd7348

File tree

1 file changed

+4
-5
lines changed

1 file changed

+4
-5
lines changed

arch/riscv/core/pmp.c

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -432,12 +432,12 @@ void z_riscv_pmp_init(void)
432432
/* Make sure secondary CPUs produced the same values */
433433
if (global_pmp_end_index != 0) {
434434
__ASSERT(global_pmp_end_index == index, "");
435-
__ASSERT(global_pmp_cfg[0] == pmp_cfg[0], "");
435+
__ASSERT(global_pmp_cfg[0] == pmp_cfg[index / PMPCFG_STRIDE], "");
436436
__ASSERT(global_pmp_last_addr == pmp_addr[index - 1], "");
437437
}
438438
#endif
439439

440-
global_pmp_cfg[0] = pmp_cfg[0];
440+
global_pmp_cfg[0] = pmp_cfg[index / PMPCFG_STRIDE];
441441
global_pmp_last_addr = pmp_addr[index - 1];
442442
global_pmp_end_index = index;
443443

@@ -459,7 +459,7 @@ static inline unsigned int z_riscv_pmp_thread_init(unsigned long *pmp_addr,
459459
/*
460460
* Retrieve pmpcfg0 partial content from global entries.
461461
*/
462-
pmp_cfg[0] = global_pmp_cfg[0];
462+
pmp_cfg[global_pmp_end_index / PMPCFG_STRIDE] = global_pmp_cfg[0];
463463

464464
/*
465465
* Retrieve the pmpaddr value matching the last global PMP slot.
@@ -519,8 +519,7 @@ void z_riscv_pmp_stackguard_enable(struct k_thread *thread)
519519
csr_clear(mstatus, MSTATUS_MPRV | MSTATUS_MPP);
520520

521521
/* Write our m-mode MPP entries */
522-
write_pmp_entries(global_pmp_end_index, thread->arch.m_mode_pmp_end_index,
523-
false /* no need to clear to the end */,
522+
write_pmp_entries(global_pmp_end_index, thread->arch.m_mode_pmp_end_index, true,
524523
PMP_M_MODE(thread));
525524

526525
if (PMP_DEBUG_DUMP) {

0 commit comments

Comments
 (0)