[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH v2 2/3] arm/mpu: Provide and populate MPU C data structures
On 06/06/2025 18:48, Ayan Kumar Halder wrote: > Modify Arm32 assembly boot code to reset any unused MPU region, initialise > 'max_mpu_regions' with the number of supported MPU regions and set/clear the > bitmap 'xen_mpumap_mask' used to track the enabled regions. > > Use the macro definition for "dcache_line_size" from linux. > > Signed-off-by: Ayan Kumar Halder <ayan.kumar.halder@xxxxxxx> > --- > Changes from v1 :- > > 1. Introduce cache.S to hold arm32 cache initialization instructions. > > 2. Use dcache_line_size macro definition from linux. > > 3. Use mov_w instead of ldr. > > 4. Use a single stm instruction for 'store_pair' macro definition. > > xen/arch/arm/arm32/Makefile | 1 + > xen/arch/arm/arm32/asm-offsets.c | 6 ++++ > xen/arch/arm/arm32/cache.S | 41 ++++++++++++++++++++++++ > xen/arch/arm/arm32/mpu/head.S | 25 +++++++++++++++ > xen/arch/arm/include/asm/mpu/regions.inc | 2 +- > 5 files changed, 74 insertions(+), 1 deletion(-) > create mode 100644 xen/arch/arm/arm32/cache.S > > diff --git a/xen/arch/arm/arm32/Makefile b/xen/arch/arm/arm32/Makefile > index 537969d753..531168f58a 100644 > --- a/xen/arch/arm/arm32/Makefile > +++ b/xen/arch/arm/arm32/Makefile > @@ -2,6 +2,7 @@ obj-y += lib/ > obj-$(CONFIG_MMU) += mmu/ > obj-$(CONFIG_MPU) += mpu/ > > +obj-y += cache.o > obj-$(CONFIG_EARLY_PRINTK) += debug.o > obj-y += domctl.o > obj-y += domain.o > diff --git a/xen/arch/arm/arm32/asm-offsets.c > b/xen/arch/arm/arm32/asm-offsets.c > index 8bbb0f938e..c203ce269d 100644 > --- a/xen/arch/arm/arm32/asm-offsets.c > +++ b/xen/arch/arm/arm32/asm-offsets.c > @@ -75,6 +75,12 @@ void __dummy__(void) > > OFFSET(INITINFO_stack, struct init_info, stack); > BLANK(); > + > +#ifdef CONFIG_MPU > + DEFINE(XEN_MPUMAP_MASK_sizeof, sizeof(xen_mpumap_mask)); > + DEFINE(XEN_MPUMAP_sizeof, sizeof(xen_mpumap)); > + BLANK(); > +#endif > } > > /* > diff --git a/xen/arch/arm/arm32/cache.S b/xen/arch/arm/arm32/cache.S > new file mode 100644 > index 0000000000..00ea390ce4 > --- /dev/null > +++ b/xen/arch/arm/arm32/cache.S > @@ -0,0 +1,41 @@ > +/* SPDX-License-Identifier: GPL-2.0-only */ > +/* Cache maintenance */ > + > +#include <asm/arm32/sysregs.h> > + > +/* dcache_line_size - get the minimum D-cache line size from the CTR > register */ > + .macro dcache_line_size, reg, tmp > + mrc p15, 0, \tmp, c0, c0, 1 /* read ctr */ Why open coding macro CTR? Especially if below you use DCIMVAC. > + lsr \tmp, \tmp, #16 > + and \tmp, \tmp, #0xf /* cache line size encoding */ > + mov \reg, #4 /* bytes per word */ > + mov \reg, \reg, lsl \tmp /* actual cache line size */ > + .endm > + > +/* > + * __invalidate_dcache_area(addr, size) > + * > + * Ensure that the data held in the cache for the buffer is invalidated. > + * > + * - addr - start address of the buffer > + * - size - size of the buffer > + */ I do think that for new functions in assembly we should write what registers are clobbered. Arm64 cache.S originated from Linux, hence it lacks this information. > +FUNC(__invalidate_dcache_area) > + dcache_line_size r2, r3 > + add r1, r0, r1 > + sub r3, r2, #1 > + bic r0, r0, r3 > +1: mcr CP32(r0, DCIMVAC) /* invalidate D line / unified line */ > + add r0, r0, r2 > + cmp r0, r1 > + blo 1b > + dsb sy > + ret > +END(__invalidate_dcache_area) > + > +/* > + * Local variables: > + * mode: ASM > + * indent-tabs-mode: nil > + * End: > + */ > diff --git a/xen/arch/arm/arm32/mpu/head.S b/xen/arch/arm/arm32/mpu/head.S > index b2c5245e51..435b140d09 100644 > --- a/xen/arch/arm/arm32/mpu/head.S > +++ b/xen/arch/arm/arm32/mpu/head.S > @@ -49,6 +49,10 @@ FUNC(enable_boot_cpu_mm) > mrc CP32(r5, MPUIR_EL2) > and r5, r5, #NUM_MPU_REGIONS_MASK > > + mov_w r0, max_mpu_regions > + str r5, [r0] > + mcr CP32(r0, DCIMVAC) /* Invalidate cache for max_mpu_regions addr */ > + > /* x0: region sel */ > mov r0, #0 > /* Xen text section. */ > @@ -83,6 +87,27 @@ FUNC(enable_boot_cpu_mm) > prepare_xen_region r0, r1, r2, r3, r4, r5, > attr_prbar=REGION_DEVICE_PRBAR, attr_prlar=REGION_DEVICE_PRLAR > #endif > > +zero_mpu: > + /* Reset remaining MPU regions */ > + cmp r0, r5 > + beq out_zero_mpu > + mov r1, #0 > + mov r2, #1 > + prepare_xen_region r0, r1, r2, r3, r4, r5, > attr_prlar=REGION_DISABLED_PRLAR > + b zero_mpu > + > +out_zero_mpu: > + /* Invalidate data cache for MPU data structures */ > + mov r4, lr > + mov_w r0, xen_mpumap_mask > + mov r1, #XEN_MPUMAP_MASK_sizeof > + bl __invalidate_dcache_area > + > + ldr r0, =xen_mpumap > + mov r1, #XEN_MPUMAP_sizeof > + bl __invalidate_dcache_area > + mov lr, r4 > + > b enable_mpu > END(enable_boot_cpu_mm) > > diff --git a/xen/arch/arm/include/asm/mpu/regions.inc > b/xen/arch/arm/include/asm/mpu/regions.inc > index 6b8c233e6c..631b0b2b86 100644 > --- a/xen/arch/arm/include/asm/mpu/regions.inc > +++ b/xen/arch/arm/include/asm/mpu/regions.inc > @@ -24,7 +24,7 @@ > #define XEN_MPUMAP_ENTRY_SHIFT 0x3 /* 8 byte structure */ > > .macro store_pair reg1, reg2, dst > - .word 0xe7f000f0 /* unimplemented */ > + stm \dst, {\reg1, \reg2} /* reg2 should be a higher register than reg1 > */ Didn't we agree not to use STM (I suggested it but then Julien pointed out that it's use in macro might not be the best)? ~Michal
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |