Implement the function setup_mpu that will logically track the MPU regions defined by hardware registers, start introducing data structures and functions to track the status from the C world.
The xen_mpumap_mask bitmap is used to track which MPU region are enabled at runtime. This function is called from setup_mm() which full implementation will be provided in a later stage. Signed-off-by: Luca Fancellu <luca.fance...@arm.com> --- xen/arch/arm/include/asm/arm64/mpu.h | 2 ++ xen/arch/arm/mpu/mm.c | 49 +++++++++++++++++++++++++++- 2 files changed, 50 insertions(+), 1 deletion(-) diff --git a/xen/arch/arm/include/asm/arm64/mpu.h b/xen/arch/arm/include/asm/arm64/mpu.h index 7cf8d355a1af..ff5a957bf085 100644 --- a/xen/arch/arm/include/asm/arm64/mpu.h +++ b/xen/arch/arm/include/asm/arm64/mpu.h @@ -6,6 +6,8 @@ #ifndef __ARM_ARM64_MPU_H__ #define __ARM_ARM64_MPU_H__ +#define PRENR_MASK GENMASK(31, 0) + /* * Excute never. * Stage 1 EL2 translation regime. diff --git a/xen/arch/arm/mpu/mm.c b/xen/arch/arm/mpu/mm.c index 2c5820a44f13..fe05c8097155 100644 --- a/xen/arch/arm/mpu/mm.c +++ b/xen/arch/arm/mpu/mm.c @@ -14,6 +14,17 @@ struct page_info *frame_table; +/* Maximum number of supported MPU memory regions by the EL2 MPU. */ +uint8_t __ro_after_init max_xen_mpumap; + +/* + * Bitmap xen_mpumap_mask is to record the usage of EL2 MPU memory regions. + * Bit 0 represents MPU memory region 0, bit 1 represents MPU memory + * region 1, ..., and so on. + * If a MPU memory region gets enabled, set the according bit to 1. + */ +DECLARE_BITMAP(xen_mpumap_mask, MAX_MPU_REGIONS); + /* EL2 Xen MPU memory region mapping table. */ pr_t xen_mpumap[MAX_MPU_REGIONS]; @@ -224,9 +235,45 @@ pr_t pr_of_xenaddr(paddr_t base, paddr_t limit, unsigned attr) return region; } +/* + * The code in this function needs to track the regions programmed in + * arm64/mpu/head.S + */ +static void __init setup_mpu(void) +{ + register_t prenr; + unsigned int i = 0; + + /* + * MPUIR_EL2.Region[0:7] identifies the number of regions supported by + * the EL2 MPU. + */ + max_xen_mpumap = (uint8_t)(READ_SYSREG(MPUIR_EL2) & NUM_MPU_REGIONS_MASK); + + /* PRENR_EL2 has the N bit set if the N region is enabled, N < 32 */ + prenr = (READ_SYSREG(PRENR_EL2) & PRENR_MASK); + + /* + * Set the bitfield for regions enabled in assembly boot-time. + * This code works under the assumption that the code in head.S has + * allocated and enabled regions below 32 (N < 32). + */ + while ( prenr > 0 ) + { + if (prenr & 0x1) + { + set_bit(i, xen_mpumap_mask); + read_protection_region(&xen_mpumap[i], i); + } + + prenr >>= 1; + i++; + } +} + void __init setup_mm(void) { - BUG_ON("unimplemented"); + setup_mpu(); } int modify_xen_mappings(unsigned long s, unsigned long e, unsigned int nf) -- 2.34.1