diff options
| author | Yu-Chien Peter Lin <[email protected]> | 2025-10-08 16:44:40 +0800 |
|---|---|---|
| committer | Anup Patel <[email protected]> | 2025-11-02 16:21:07 +0530 |
| commit | 34657b377f35ab4d0602390e885d1db91e82acf6 (patch) | |
| tree | a0824c3f585c43c7ddbe518366826b690dc291e1 /lib | |
| parent | 90c3b94094d052e8109862a8b05d2885b1c3d879 (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.c | 21 |
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; |
