[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH v2 2/7] arm/mpu: Provide access to the MPU region from the C code
Hi Ayan, > On 8 Apr 2025, at 15:02, Ayan Kumar Halder <ayankuma@xxxxxxx> wrote: > > Hi Luca, > >> >> +static void prepare_selector(uint8_t sel) >> +{ >> + /* >> + * {read,write}_protection_region works using the direct access to the >> 0..15 >> + * regions, so in order to save the isb() overhead, change the >> PRSELR_EL2 >> + * only when needed, so when the upper 4 bits of the selector will >> change. >> + */ >> + sel &= 0xF0U; >> + if ( READ_SYSREG(PRSELR_EL2) != sel ) >> + { >> + WRITE_SYSREG(sel, PRSELR_EL2); >> + isb(); >> + } > > This needs to be arm64 specific. Refer ARM DDI 0600A.d ID120821 > > G1.3.19 PRBAR<n>_EL2, /* I guess this is what you are following */ > > Provides access to the base address for the MPU region determined by the > value of 'n' and > PRSELR_EL2.REGION as PRSELR_EL2.REGION<7:4>:n. > > > Whereas for arm32 . Refer ARM DDI 0568A.c ID110520 > > E2.2.3 HPRBAR<n>, > > Provides access to the base addresses for the first 32 defined EL2 MPU > regions. > > /* Here we do not need to use HPRSELR for region selection */ > > > If you want to make the code similar between arm32 and arm64, then I can > suggest you can use these registers. > > G1.3.17 PRBAR_EL2 > > Provides access to the base addresses for the EL2 MPU region. > PRSELR_EL2.REGION determines > which MPU region is selected. > > E2.2.2 HPRBAR > > Provides indirect access to the base address of the EL2 MPU region currently > defined by > HPRSELR. > > Let me know if it makes sense. > > - Ayan Ok I didin’t get that before, what do you think if I modify the code as in this diff (not tested): diff --git a/xen/arch/arm/mpu/mm.c b/xen/arch/arm/mpu/mm.c index fe05c8097155..1bc6d7a77296 100644 --- a/xen/arch/arm/mpu/mm.c +++ b/xen/arch/arm/mpu/mm.c @@ -58,19 +58,21 @@ static void __init __maybe_unused build_assertions(void) BUILD_BUG_ON(PAGE_SIZE != SZ_4K); } -static void prepare_selector(uint8_t sel) +static void prepare_selector(uint8_t *sel) { + uint8_t cur_sel = *sel; /* * {read,write}_protection_region works using the direct access to the 0..15 * regions, so in order to save the isb() overhead, change the PRSELR_EL2 * only when needed, so when the upper 4 bits of the selector will change. */ - sel &= 0xF0U; - if ( READ_SYSREG(PRSELR_EL2) != sel ) + cur_sel &= 0xF0U; + if ( READ_SYSREG(PRSELR_EL2) != cur_sel ) { - WRITE_SYSREG(sel, PRSELR_EL2); + WRITE_SYSREG(cur_sel, PRSELR_EL2); isb(); } + *sel = *sel & 0xFU; } /* @@ -102,7 +104,7 @@ void read_protection_region(pr_t *pr_read, uint8_t sel) */ prepare_selector(sel); - switch ( sel & 0xFU ) + switch ( sel ) { GENERATE_READ_PR_REG_CASE(0, pr_read); GENERATE_READ_PR_REG_CASE(1, pr_read); @@ -140,7 +142,7 @@ void write_protection_region(const pr_t *pr_write, uint8_t sel) */ prepare_selector(sel); - switch ( sel & 0xFU ) + switch ( sel ) { GENERATE_WRITE_PR_REG_CASE(0, pr_write); GENERATE_WRITE_PR_REG_CASE(1, pr_write); And later you will use some #ifdef CONFIG_ARM_32 inside prepare_selector() to check that the code is passing up to the max supported region or panic. And in {read,write}_protection_region() you could add some #ifdef CONFIG_ARM_32 to add the case generators for regions from 16 to 23 since R52 can address them directly. What do you think? Cheers, Luca
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |