diff --git a/include/sbi/sbi_domain.h b/include/sbi/sbi_domain.h index 9193feb0..1196d609 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 8b03db12..da0f0557 100644 --- a/lib/sbi/sbi_domain.c +++ b/lib/sbi/sbi_domain.c @@ -292,6 +292,19 @@ 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) { + /* + * Enforce firmware region ordering for memory access + * under SmePMP. + * Place firmware regions first to ensure consistent + * PMP entries during domain context switches. + */ + 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;