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,
|
unsigned long flags,
|
||||||
struct sbi_domain_memregion *reg);
|
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
|
* Check whether we can access specified address for given mode and
|
||||||
* memory region flags under a domain
|
* 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,
|
bool sbi_domain_check_addr(const struct sbi_domain *dom,
|
||||||
unsigned long addr, unsigned long mode,
|
unsigned long addr, unsigned long mode,
|
||||||
unsigned long access_flags)
|
unsigned long access_flags)
|
||||||
|
|||||||
@ -301,69 +301,6 @@ unsigned int sbi_hart_mhpm_bits(struct sbi_scratch *scratch)
|
|||||||
return hfeatures->mhpm_bits;
|
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,
|
static void sbi_hart_smepmp_set(struct sbi_scratch *scratch,
|
||||||
struct sbi_domain *dom,
|
struct sbi_domain *dom,
|
||||||
struct sbi_domain_memregion *reg,
|
struct sbi_domain_memregion *reg,
|
||||||
@ -420,7 +357,7 @@ static int sbi_hart_smepmp_configure(struct sbi_scratch *scratch,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
pmp_flags = sbi_hart_get_smepmp_flags(scratch, dom, reg);
|
pmp_flags = sbi_domain_get_smepmp_flags(reg);
|
||||||
if (!pmp_flags)
|
if (!pmp_flags)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@ -446,7 +383,7 @@ static int sbi_hart_smepmp_configure(struct sbi_scratch *scratch,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
pmp_flags = sbi_hart_get_smepmp_flags(scratch, dom, reg);
|
pmp_flags = sbi_domain_get_smepmp_flags(reg);
|
||||||
if (!pmp_flags)
|
if (!pmp_flags)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user