From 34657b377f35ab4d0602390e885d1db91e82acf6 Mon Sep 17 00:00:00 2001 From: Yu-Chien Peter Lin Date: Wed, 8 Oct 2025 16:44:40 +0800 Subject: [PATCH] lib: sbi_hart: return error when insufficient PMP entries available Previously, when memory regions exceed available PMP entries, some regions were silently ignored. If the last entry that covers the full 64-bit address space is not added to a domain, the next stage S-mode software won't have permission to access and fetch instructions from its memory. So return early with error message to catch such situation. Signed-off-by: Yu-Chien Peter Lin Reviewed-by: Anup Patel Link: https://lore.kernel.org/r/20251008084444.3525615-5-peter.lin@sifive.com Signed-off-by: Anup Patel --- lib/sbi/sbi_hart.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/lib/sbi/sbi_hart.c b/lib/sbi/sbi_hart.c index 7edd2a05..42bcb517 100644 --- a/lib/sbi/sbi_hart.c +++ b/lib/sbi/sbi_hart.c @@ -324,6 +324,15 @@ static void sbi_hart_smepmp_set(struct sbi_scratch *scratch, } } +static bool is_valid_pmp_idx(unsigned int pmp_count, unsigned int pmp_idx) +{ + if (pmp_count > pmp_idx) + return true; + + sbi_printf("error: insufficient PMP entries\n"); + return false; +} + static int sbi_hart_smepmp_configure(struct sbi_scratch *scratch, unsigned int pmp_count, unsigned int pmp_log2gran, @@ -348,8 +357,8 @@ static int sbi_hart_smepmp_configure(struct sbi_scratch *scratch, /* Skip reserved entry */ if (pmp_idx == SBI_SMEPMP_RESV_ENTRY) pmp_idx++; - if (pmp_count <= pmp_idx) - break; + if (!is_valid_pmp_idx(pmp_count, pmp_idx)) + return SBI_EFAIL; /* Skip shared and SU-only regions */ if (!SBI_DOMAIN_MEMREGION_M_ONLY_ACCESS(reg->flags)) { @@ -372,8 +381,8 @@ static int sbi_hart_smepmp_configure(struct sbi_scratch *scratch, /* Skip reserved entry */ if (pmp_idx == SBI_SMEPMP_RESV_ENTRY) pmp_idx++; - if (pmp_count <= pmp_idx) - break; + if (!is_valid_pmp_idx(pmp_count, pmp_idx)) + return SBI_EFAIL; /* Skip M-only regions */ if (SBI_DOMAIN_MEMREGION_M_ONLY_ACCESS(reg->flags)) { @@ -407,8 +416,8 @@ static int sbi_hart_oldpmp_configure(struct sbi_scratch *scratch, unsigned long pmp_addr; sbi_domain_for_each_memregion(dom, reg) { - if (pmp_count <= pmp_idx) - break; + if (!is_valid_pmp_idx(pmp_count, pmp_idx)) + return SBI_EFAIL; pmp_flags = 0;