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 <peter.lin@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
Link: https://lore.kernel.org/r/20251008084444.3525615-5-peter.lin@sifive.com
Signed-off-by: Anup Patel <anup@brainfault.org>
This commit is contained in:
Yu-Chien Peter Lin
2025-10-08 16:44:40 +08:00
committed by Anup Patel
parent 90c3b94094
commit 34657b377f

View File

@ -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;