[PATCH 7/8] lib: sbi_domain: ensure consistent firmware PMP entries

Yu-Chien Peter Lin
2025-08-14T15:37:25Z

Currently, during a domain context switch, all PMP entries — including
those granting RW/RX permissions to firmware data and code are cleared
which will lead to access faults.

To configure firmware PMP entries deterministically across switches,
sort regions so that firmware regions come before others.

Signed-off-by: Yu-Chien Peter Lin <peter.lin@sifive.com>
---
include/sbi/sbi_domain.h | 3 +++
lib/sbi/sbi_domain.c | 14 ++++++++++++++
2 files changed, 17 insertions(+)

diff --git a/include/sbi/sbi_domain.h b/include/sbi/sbi_domain.h
index d71354c7..31237401 100644
--- a/include/sbi/sbi_domain.h
+++ b/include/sbi/sbi_domain.h
@@ -121,6 +121,9 @@ struct sbi_domain_memregion {
((__flags & SBI_DOMAIN_MEMREGION_SU_ACCESS_MASK) && \
!(__flags & SBI_DOMAIN_MEMREGION_M_ACCESS_MASK))

+#define SBI_DOMAIN_MEMREGION_IS_FIRMWARE(__flags) \
+ ((__flags & SBI_DOMAIN_MEMREGION_FW) ? true : false) \
+
/** Bit to control if permissions are enforced on all modes */
#define SBI_DOMAIN_MEMREGION_ENF_PERMISSIONS (1UL << 6)

diff --git a/lib/sbi/sbi_domain.c b/lib/sbi/sbi_domain.c
index ccfcc7f0..9e284f49 100644
--- a/lib/sbi/sbi_domain.c
+++ b/lib/sbi/sbi_domain.c
@@ -295,6 +295,20 @@ static bool is_region_compatible(const struct sbi_domain_memregion *regA,
static bool is_region_before(const struct sbi_domain_memregion *regA,
const struct sbi_domain_memregion *regB)
{
+ /*
+ * Firmware regions are placed before non‑firmware
+ * regions. This ensures firmware code/data remain
+ * accessible when SmePMP is enabled. Optional for
+ * regular PMP, but safe to follow consistently.
+ */
+ if (SBI_DOMAIN_MEMREGION_IS_FIRMWARE(regA->flags) &&
+ !SBI_DOMAIN_MEMREGION_IS_FIRMWARE(regB->flags))
+ return true;
+ if (!SBI_DOMAIN_MEMREGION_IS_FIRMWARE(regA->flags) &&
+ SBI_DOMAIN_MEMREGION_IS_FIRMWARE(regB->flags))
+ return false;
+
+
if (regA->order < regB->order)
return true;