From 32c1d38dcf1a184b100bba2e26047939c32ec625 Mon Sep 17 00:00:00 2001 From: Yu-Chien Peter Lin Date: Wed, 8 Oct 2025 16:44:37 +0800 Subject: [PATCH] lib: sbi_hart: move sbi_hart_get_smepmp_flags() to sbi_domain Move sbi_hart_get_smepmp_flags() from sbi_hart.c to sbi_domain.c and rename it to sbi_domain_get_smepmp_flags() to better reflect its purpose of converting domain memory region flags to PMP configuration. Also removes unused parameters (scratch and dom). Signed-off-by: Yu-Chien Peter Lin Reviewed-by: Anup Patel Link: https://lore.kernel.org/r/20251008084444.3525615-2-peter.lin@sifive.com Signed-off-by: Anup Patel --- include/sbi/sbi_domain.h | 7 +++++ lib/sbi/sbi_domain.c | 58 ++++++++++++++++++++++++++++++++++ lib/sbi/sbi_hart.c | 67 ++-------------------------------------- 3 files changed, 67 insertions(+), 65 deletions(-) diff --git a/include/sbi/sbi_domain.h b/include/sbi/sbi_domain.h index e9cff0b1..a6ee553b 100644 --- a/include/sbi/sbi_domain.h +++ b/include/sbi/sbi_domain.h @@ -249,6 +249,13 @@ void sbi_domain_memregion_init(unsigned long addr, unsigned long flags, struct sbi_domain_memregion *reg); +/** + * Return the Smepmp pmpcfg LRWX encoding for the flags in @reg. + * + * @param reg pointer to memory region; its flags field encodes permissions. + */ +unsigned int sbi_domain_get_smepmp_flags(struct sbi_domain_memregion *reg); + /** * Check whether we can access specified address for given mode and * memory region flags under a domain diff --git a/lib/sbi/sbi_domain.c b/lib/sbi/sbi_domain.c index 461c7e53..1fa56b6a 100644 --- a/lib/sbi/sbi_domain.c +++ b/lib/sbi/sbi_domain.c @@ -122,6 +122,64 @@ void sbi_domain_memregion_init(unsigned long addr, } } +unsigned int sbi_domain_get_smepmp_flags(struct sbi_domain_memregion *reg) +{ + unsigned int pmp_flags = 0; + + if (SBI_DOMAIN_MEMREGION_IS_SHARED(reg->flags)) { + /* Read only for both M and SU modes */ + if (SBI_DOMAIN_MEMREGION_IS_SUR_MR(reg->flags)) + pmp_flags = (PMP_L | PMP_R | PMP_W | PMP_X); + + /* Execute for SU but Read/Execute for M mode */ + else if (SBI_DOMAIN_MEMREGION_IS_SUX_MRX(reg->flags)) + /* locked region */ + pmp_flags = (PMP_L | PMP_W | PMP_X); + + /* Execute only for both M and SU modes */ + else if (SBI_DOMAIN_MEMREGION_IS_SUX_MX(reg->flags)) + pmp_flags = (PMP_L | PMP_W); + + /* Read/Write for both M and SU modes */ + else if (SBI_DOMAIN_MEMREGION_IS_SURW_MRW(reg->flags)) + pmp_flags = (PMP_W | PMP_X); + + /* Read only for SU mode but Read/Write for M mode */ + else if (SBI_DOMAIN_MEMREGION_IS_SUR_MRW(reg->flags)) + pmp_flags = (PMP_W); + } else if (SBI_DOMAIN_MEMREGION_M_ONLY_ACCESS(reg->flags)) { + /* + * When smepmp is supported and used, M region cannot have RWX + * permissions on any region. + */ + if ((reg->flags & SBI_DOMAIN_MEMREGION_M_ACCESS_MASK) + == SBI_DOMAIN_MEMREGION_M_RWX) { + sbi_printf("%s: M-mode only regions cannot have" + "RWX permissions\n", __func__); + return 0; + } + + /* M-mode only access regions are always locked */ + pmp_flags |= PMP_L; + + if (reg->flags & SBI_DOMAIN_MEMREGION_M_READABLE) + pmp_flags |= PMP_R; + if (reg->flags & SBI_DOMAIN_MEMREGION_M_WRITABLE) + pmp_flags |= PMP_W; + if (reg->flags & SBI_DOMAIN_MEMREGION_M_EXECUTABLE) + pmp_flags |= PMP_X; + } else if (SBI_DOMAIN_MEMREGION_SU_ONLY_ACCESS(reg->flags)) { + if (reg->flags & SBI_DOMAIN_MEMREGION_SU_READABLE) + pmp_flags |= PMP_R; + if (reg->flags & SBI_DOMAIN_MEMREGION_SU_WRITABLE) + pmp_flags |= PMP_W; + if (reg->flags & SBI_DOMAIN_MEMREGION_SU_EXECUTABLE) + pmp_flags |= PMP_X; + } + + return pmp_flags; +} + bool sbi_domain_check_addr(const struct sbi_domain *dom, unsigned long addr, unsigned long mode, unsigned long access_flags) diff --git a/lib/sbi/sbi_hart.c b/lib/sbi/sbi_hart.c index de135818..81b9e479 100644 --- a/lib/sbi/sbi_hart.c +++ b/lib/sbi/sbi_hart.c @@ -301,69 +301,6 @@ unsigned int sbi_hart_mhpm_bits(struct sbi_scratch *scratch) return hfeatures->mhpm_bits; } -/* - * Returns Smepmp flags for a given domain and region based on permissions. - */ -static unsigned int sbi_hart_get_smepmp_flags(struct sbi_scratch *scratch, - struct sbi_domain *dom, - struct sbi_domain_memregion *reg) -{ - unsigned int pmp_flags = 0; - - if (SBI_DOMAIN_MEMREGION_IS_SHARED(reg->flags)) { - /* Read only for both M and SU modes */ - if (SBI_DOMAIN_MEMREGION_IS_SUR_MR(reg->flags)) - pmp_flags = (PMP_L | PMP_R | PMP_W | PMP_X); - - /* Execute for SU but Read/Execute for M mode */ - else if (SBI_DOMAIN_MEMREGION_IS_SUX_MRX(reg->flags)) - /* locked region */ - pmp_flags = (PMP_L | PMP_W | PMP_X); - - /* Execute only for both M and SU modes */ - else if (SBI_DOMAIN_MEMREGION_IS_SUX_MX(reg->flags)) - pmp_flags = (PMP_L | PMP_W); - - /* Read/Write for both M and SU modes */ - else if (SBI_DOMAIN_MEMREGION_IS_SURW_MRW(reg->flags)) - pmp_flags = (PMP_W | PMP_X); - - /* Read only for SU mode but Read/Write for M mode */ - else if (SBI_DOMAIN_MEMREGION_IS_SUR_MRW(reg->flags)) - pmp_flags = (PMP_W); - } else if (SBI_DOMAIN_MEMREGION_M_ONLY_ACCESS(reg->flags)) { - /* - * When smepmp is supported and used, M region cannot have RWX - * permissions on any region. - */ - if ((reg->flags & SBI_DOMAIN_MEMREGION_M_ACCESS_MASK) - == SBI_DOMAIN_MEMREGION_M_RWX) { - sbi_printf("%s: M-mode only regions cannot have" - "RWX permissions\n", __func__); - return 0; - } - - /* M-mode only access regions are always locked */ - pmp_flags |= PMP_L; - - if (reg->flags & SBI_DOMAIN_MEMREGION_M_READABLE) - pmp_flags |= PMP_R; - if (reg->flags & SBI_DOMAIN_MEMREGION_M_WRITABLE) - pmp_flags |= PMP_W; - if (reg->flags & SBI_DOMAIN_MEMREGION_M_EXECUTABLE) - pmp_flags |= PMP_X; - } else if (SBI_DOMAIN_MEMREGION_SU_ONLY_ACCESS(reg->flags)) { - if (reg->flags & SBI_DOMAIN_MEMREGION_SU_READABLE) - pmp_flags |= PMP_R; - if (reg->flags & SBI_DOMAIN_MEMREGION_SU_WRITABLE) - pmp_flags |= PMP_W; - if (reg->flags & SBI_DOMAIN_MEMREGION_SU_EXECUTABLE) - pmp_flags |= PMP_X; - } - - return pmp_flags; -} - static void sbi_hart_smepmp_set(struct sbi_scratch *scratch, struct sbi_domain *dom, struct sbi_domain_memregion *reg, @@ -420,7 +357,7 @@ static int sbi_hart_smepmp_configure(struct sbi_scratch *scratch, continue; } - pmp_flags = sbi_hart_get_smepmp_flags(scratch, dom, reg); + pmp_flags = sbi_domain_get_smepmp_flags(reg); if (!pmp_flags) return 0; @@ -446,7 +383,7 @@ static int sbi_hart_smepmp_configure(struct sbi_scratch *scratch, continue; } - pmp_flags = sbi_hart_get_smepmp_flags(scratch, dom, reg); + pmp_flags = sbi_domain_get_smepmp_flags(reg); if (!pmp_flags) return 0;