mirror of
https://gitlab.com/qemu-project/opensbi.git
synced 2025-11-10 05:37:55 +08:00
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 <peter.lin@sifive.com> Reviewed-by: Anup Patel <anup@brainfault.org> Link: https://lore.kernel.org/r/20251008084444.3525615-2-peter.lin@sifive.com Signed-off-by: Anup Patel <anup@brainfault.org>
This commit is contained in:
committed by
Anup Patel
parent
37b72cb575
commit
32c1d38dcf
@ -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
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user