summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorYu-Chien Peter Lin <[email protected]>2025-10-08 16:44:40 +0800
committerAnup Patel <[email protected]>2025-11-02 16:21:07 +0530
commit34657b377f35ab4d0602390e885d1db91e82acf6 (patch)
treea0824c3f585c43c7ddbe518366826b690dc291e1 /lib
parent90c3b94094d052e8109862a8b05d2885b1c3d879 (diff)
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 <[email protected]> Reviewed-by: Anup Patel <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Anup Patel <[email protected]>
Diffstat (limited to 'lib')
-rw-r--r--lib/sbi/sbi_hart.c21
1 files 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;