diff --git a/arch/riscv/core/pmp.c b/arch/riscv/core/pmp.c index ca5e5a49d5a74..d91b43e884051 100644 --- a/arch/riscv/core/pmp.c +++ b/arch/riscv/core/pmp.c @@ -335,11 +335,13 @@ static void write_pmp_entries(unsigned int start, unsigned int end, ARRAY_SIZE(thread->arch.u_mode_pmpaddr_regs) /* - * This is used to seed thread PMP copies with global m-mode cfg entries - * sharing the same cfg register. Locked entries aren't modifiable but + * Stores the initial values of the pmpcfg CSRs, covering all global + * m-mode PMP entries. This array is sized to hold all pmpcfg registers + * necessary for CONFIG_PMP_SLOTS. It is used to seed the per-thread + * PMP configuration copies. Locked entries aren't modifiable but * we could have non-locked entries here too. */ -static unsigned long global_pmp_cfg[1]; +static unsigned long global_pmp_cfg[CONFIG_PMP_SLOTS / PMPCFG_STRIDE]; static unsigned long global_pmp_last_addr; /* End of global PMP entry range */ @@ -432,12 +434,12 @@ void z_riscv_pmp_init(void) /* Make sure secondary CPUs produced the same values */ if (global_pmp_end_index != 0) { __ASSERT(global_pmp_end_index == index, ""); - __ASSERT(global_pmp_cfg[0] == pmp_cfg[0], ""); + __ASSERT(memcmp(pmp_cfg, global_pmp_cfg, sizeof(global_pmp_cfg)) == 0, ""); __ASSERT(global_pmp_last_addr == pmp_addr[index - 1], ""); } #endif - global_pmp_cfg[0] = pmp_cfg[0]; + memcpy(global_pmp_cfg, pmp_cfg, sizeof(pmp_cfg)); global_pmp_last_addr = pmp_addr[index - 1]; global_pmp_end_index = index; @@ -457,9 +459,9 @@ static inline unsigned int z_riscv_pmp_thread_init(unsigned long *pmp_addr, ARG_UNUSED(index_limit); /* - * Retrieve pmpcfg0 partial content from global entries. + * Retrieve the pmpcfg register with partial content from global entries. */ - pmp_cfg[0] = global_pmp_cfg[0]; + memcpy(pmp_cfg, global_pmp_cfg, sizeof(global_pmp_cfg)); /* * Retrieve the pmpaddr value matching the last global PMP slot. @@ -520,7 +522,7 @@ void z_riscv_pmp_stackguard_enable(struct k_thread *thread) /* Write our m-mode MPP entries */ write_pmp_entries(global_pmp_end_index, thread->arch.m_mode_pmp_end_index, - false /* no need to clear to the end */, + true, PMP_M_MODE(thread)); if (PMP_DEBUG_DUMP) { diff --git a/include/zephyr/arch/riscv/thread.h b/include/zephyr/arch/riscv/thread.h index 08f14b61cebf7..c6ca4d7ae4162 100644 --- a/include/zephyr/arch/riscv/thread.h +++ b/include/zephyr/arch/riscv/thread.h @@ -81,8 +81,8 @@ struct _thread_arch { #endif #ifdef CONFIG_PMP_STACK_GUARD unsigned int m_mode_pmp_end_index; - unsigned long m_mode_pmpaddr_regs[PMP_M_MODE_SLOTS]; - unsigned long m_mode_pmpcfg_regs[PMP_M_MODE_SLOTS / sizeof(unsigned long)]; + unsigned long m_mode_pmpaddr_regs[CONFIG_PMP_SLOTS]; + unsigned long m_mode_pmpcfg_regs[CONFIG_PMP_SLOTS / sizeof(unsigned long)]; #endif };