From 9e14e03032c3e61658c0e8bf6026e33c777ca0a4 Mon Sep 17 00:00:00 2001 From: Yu-Chien Peter Lin Date: Tue, 24 Feb 2026 11:17:33 +0800 Subject: [PATCH] sifive_dev_platform: Set default MMIO region when SmePMP is enabled Set a default MMIO region with a single SmePMP entry, which allows us to save entries for M-mode only devices. The default entry has M-/S-mode shared permission, so system-level resource protection, such as RISC-V World extension and WorldGuard checker, will be introduced to protect M-mode only region access from lower privilege modes. Reviewed-by: Greentime Hu Reviewed-by: Zong Li Signed-off-by: Yu-Chien Peter Lin Link: https://lore.kernel.org/r/20260224031733.3817148-3-peter.lin@sifive.com Signed-off-by: Anup Patel --- platform/generic/sifive/sifive_dev_platform.c | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/platform/generic/sifive/sifive_dev_platform.c b/platform/generic/sifive/sifive_dev_platform.c index facc044f..579d4651 100644 --- a/platform/generic/sifive/sifive_dev_platform.c +++ b/platform/generic/sifive/sifive_dev_platform.c @@ -5,10 +5,60 @@ */ #include +#include +#include + +/* + * Instead of allocating individual PMP entries for each M-mode + * MMIO driver, configure SMEPMP regions to grant R/W permission + * to peripheral and system ports for all privilege modes. + * Finer-grained access control is enforced by wgChecker rules. + */ +static int sifive_smepmp_setup(void) +{ + struct sbi_scratch *scratch = sbi_scratch_thishart_ptr(); + int rc; + + if (!sbi_hart_has_extension(scratch, SBI_HART_EXT_SMEPMP)) + return 0; + + /* Peripheral port region: 0 to 2GiB */ + rc = sbi_domain_root_add_memrange(0x0, 0x80000000, 0x80000000, + SBI_DOMAIN_MEMREGION_MMIO | + SBI_DOMAIN_MEMREGION_SHARED_SURW_MRW); + if (rc) + return rc; + +#if __riscv_xlen > 32 + /* System port region: 512GiB to 1TiB */ + rc = sbi_domain_root_add_memrange(0x8000000000ULL, 0x8000000000ULL, 0x8000000000ULL, + SBI_DOMAIN_MEMREGION_MMIO | + SBI_DOMAIN_MEMREGION_SHARED_SURW_MRW); + if (rc) + return rc; +#endif + + return 0; +} + +static int sifive_early_init(bool cold_boot) +{ + int rc; + + if (cold_boot) { + rc = sifive_smepmp_setup(); + if (rc) + return rc; + } + + return generic_early_init(cold_boot); +} static int sifive_platform_init(const void *fdt, int nodeoff, const struct fdt_match *match) { + generic_platform_ops.early_init = sifive_early_init; + return 0; }