Add infrastructure for SoCs to define additional PMP regions
that need protection beyond the standard ROM region. This uses
iterable sections to collect region definitions at link time.
The PMP_SOC_REGION_DEFINE macro allows SoCs to register memory
regions with specific permissions. These regions become global
PMP entries shared between M-mode and U-mode.
Signed-off-by: Sylvio Alves <sylvio.alves@espressif.com>
This commit implements a new unit test suite to validate the
integration of Device Tree memory attributes (`zephyr,memory-attr`)
with the RISC-V Physical Memory Protection (PMP) hardware.
The test suite includes:
1. **`test_pmp_devicetree_memattr_config`**: Verifies that the PMP
Control and Status Registers (CSRs) are programmed correctly based
on the memory regions defined with `zephyr,memory-attr` in the
Device Tree. It iterates through the active PMP entries and
asserts a match against the expected DT-defined regions.
2. **`test_riscv_mprv_mpp_config`**: Checks the initial state of the
Machine Privilege Register Virtualization (MPRV) bit and Machine
Previous Privilege (MPP) field in the `mstatus` CSR to ensure PMP
is configured for correct privilege level switching during boot.
3. **`test_dt_pmp_perm_conversion`**: Validates the
`DT_MEM_RISCV_TO_PMP_PERM` macro to ensure the conversion from
Device Tree memory attribute flags to RISC-V PMP permission bits
(R/W/X) is correct.
Signed-off-by: Firas Sammoura <fsammoura@google.com>
The Physical Memory Protection (PMP) initialization is updated to support
custom entries defined in the Device Tree (DT) using the `zephyr,memattr`
property, contingent on `CONFIG_MEM_ATTR` being enabled. A new function,
`set_pmp_mem_attr()`, iterates over DT-defined regions and programs PMP
entries in `z_riscv_pmp_init()`, allowing for early, flexible, and
hardware-specific R/W/X protection for critical memory areas. DT-based
entries are also installed in `z_riscv_pmp_kernelmode_prepare()` for
thread-specific configuration. The logic for the temporary PMP "catch-all"
entry is adjusted to account for new DT entries. Furthermore, the PMP
domain resync logic now masks user partition permissions against DT-defined
region permissions, preventing privilege escalation. `CONFIG_RISCV_PMP` is
updated to select `PMP_KERNEL_MODE_DYNAMIC` if `MEM_ATTR`. Finally, the
`pmp_cfg` array in `z_riscv_pmp_init()` is initialized to zero to prevent
writing uninitialized stack data to unused PMP entries.
Signed-off-by: Firas Sammoura <fsammoura@google.com>
Rename the `z_riscv_pmp_stackguard_*` functions to
`z_riscv_pmp_kernelmode_*`. This change better reflects that
these functions are used for general kernel mode PMP configuration,
not strictly limited to stack guard purposes.
Call sites in fatal.c, isr.S, and switch.S have been updated accordingly.
Signed-off-by: Firas Sammoura <fsammoura@google.com>
Replace `sizeof(unsigned long)` with `PMPCFG_STRIDE` (defined as
`__riscv_xlen / 8`) for dimensioning PMP configuration register arrays
(`pmpcfg_regs`).
The size of PMP configuration registers should be derived directly from
the target architecture's XLEN. Using `sizeof(unsigned long)` can cause
size mismatches, particularly with static analysis tools like SonarQube.
These tools might assume a host-specific size for `unsigned long`,
leading to spurious out-of-bounds access warnings when analyzing code
for different RISCV base architectures (e.g., RV32 vs. RV64).
This change ensures the array sizing is correctly and consistently tied
to the target's register width (XLEN).
Signed-off-by: Firas Sammoura <fsammoura@google.com>
When RISCV_ALWAYS_SWITCH_THROUGH_ECALL is enabled, do_swap() enables PMP
checking in is_kernel_syscall.
If the PMP stack guard is triggered and do_swap() is called from the
fault handler, a PMP error occurs because the stack usage violates the
previous PMP setting.
Remove the stack guard setting during a stack overflow handler to allow
enabling PMP checking safely in fault handler.
Signed-off-by: Jimmy Zheng <jimmyzhe@andestech.com>
The idea here is to compute the PMP register set on demand i.e. upon
scheduling in the affected threads, and only if changes occurred.
A simple sequence number is used to stay in sync with the latest update.
Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
Stackguard uses the PMP to prevents many types of stack overflow by
making any access to the bottom stack area raise a CPU exception. Each
thread has its set of precomputed PMP entries and those are written to
PMP registers at context switch time.
This is the code to set it up. It will be connected later.
Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
This is the core code to manage PMP entries with only the global entries
initialisation for now. It is not yet linked into the build.
Signed-off-by: Nicolas Pitre <npitre@baylibre.com>