[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH v5 2/3] xen/arm32: Create the same boot-time MPU regions as arm64
On 07/04/2025 20:44, Ayan Kumar Halder wrote: > We have created the same boot-time MPU protection regions as Armv8-R AArch64. > Also, we have defined *_PRBAR macros for arm32. The only difference from > arm64 is that XN is 1-bit for arm32. > The macros have been defined in mpu/cpregs.h. NIT: Describe your changes in imperative mood > > Also defined WRITE_SYSREG_ASM() to write to system registers in assembly. > > Signed-off-by: Ayan Kumar Halder <ayan.kumar.halder@xxxxxxx> > --- > Changes from > > v1 - > > 1. enable_mpu() now sets HMAIR{0,1} registers. This is similar to what is > being done in enable_mmu(). All the mm related configurations happen in this > function. > > 2. Fixed some typos. > > v2 - > 1. Include the common prepare_xen_region.inc in head.S. > > 2. Define LOAD_SYSREG()/STORE_SYSREG() for arm32. > > v3 - > 1. Rename STORE_SYSREG() as WRITE_SYSREG_ASM() > > 2. enable_boot_cpu_mm() is defined in head.S > > v4 - > 1. *_PRBAR is moved to arm32/sysregs.h. > > 2. MPU specific CP15 system registers are defined in mpu/cpregs.h. > > xen/arch/arm/arm32/Makefile | 1 + > xen/arch/arm/arm32/mpu/Makefile | 1 + > xen/arch/arm/arm32/mpu/head.S | 101 +++++++++++++++++++++++ > xen/arch/arm/include/asm/arm32/sysregs.h | 7 ++ > xen/arch/arm/include/asm/cpregs.h | 4 + > xen/arch/arm/include/asm/mpu/cpregs.h | 24 ++++++ > 6 files changed, 138 insertions(+) > create mode 100644 xen/arch/arm/arm32/mpu/Makefile > create mode 100644 xen/arch/arm/arm32/mpu/head.S > create mode 100644 xen/arch/arm/include/asm/mpu/cpregs.h > > diff --git a/xen/arch/arm/arm32/Makefile b/xen/arch/arm/arm32/Makefile > index 40a2b4803f..537969d753 100644 > --- a/xen/arch/arm/arm32/Makefile > +++ b/xen/arch/arm/arm32/Makefile > @@ -1,5 +1,6 @@ > obj-y += lib/ > obj-$(CONFIG_MMU) += mmu/ > +obj-$(CONFIG_MPU) += mpu/ > > obj-$(CONFIG_EARLY_PRINTK) += debug.o > obj-y += domctl.o > diff --git a/xen/arch/arm/arm32/mpu/Makefile b/xen/arch/arm/arm32/mpu/Makefile > new file mode 100644 > index 0000000000..3340058c08 > --- /dev/null > +++ b/xen/arch/arm/arm32/mpu/Makefile > @@ -0,0 +1 @@ > +obj-y += head.o > diff --git a/xen/arch/arm/arm32/mpu/head.S b/xen/arch/arm/arm32/mpu/head.S > new file mode 100644 > index 0000000000..84e9f1f8ec > --- /dev/null > +++ b/xen/arch/arm/arm32/mpu/head.S > @@ -0,0 +1,101 @@ > +/* SPDX-License-Identifier: GPL-2.0-only */ > +/* > + * Start-of-day code for an Armv8-R MPU system. That's exactly the same text as for Aarch64. At least write Armv8A-R-AArch32. > + */ > + > +#include <asm/arm32/macros.h> > +#include <asm/mpu/common.inc> > +#include <asm/page.h> > + > +/* > + * Set up the memory attribute type tables and enable EL2 MPU and data cache. > + * If the Background region is enabled, then the MPU uses the default memory > + * map as the Background region for generating the memory > + * attributes when MPU is disabled. > + * Since the default memory map of the Armv8-R AArch32 architecture is > + * IMPLEMENTATION DEFINED, we intend to turn off the Background region here. > + * > + * Clobbers r0 - r1 > + */ > +FUNC_LOCAL(enable_mpu) > + /* Set up memory attribute type tables */ > + mov_w r0, MAIR0VAL > + mov_w r1, MAIR1VAL > + mcr CP32(r0, HMAIR0) > + mcr CP32(r1, HMAIR1) Is there really a need to do these 2 writes one after another? Why can't we use only r0 and save one clobbered reg? mov_w r0, MAIR0VAL mcr CP32(r0, HMAIR0) mov_w r0, MAIR1VAL mcr CP32(r0, HMAIR1) > + > + mrc CP32(r0, HSCTLR) > + bic r0, r0, #SCTLR_ELx_BR /* Disable Background region */ > + orr r0, r0, #SCTLR_Axx_ELx_M /* Enable MPU */ > + orr r0, r0, #SCTLR_Axx_ELx_C /* Enable D-cache */ > + mcr CP32(r0, HSCTLR) > + isb > + > + ret > +END(enable_mpu) > + > +/* > + * Maps the various sections of Xen (described in xen.lds.S) as different MPU > + * regions. > + * > + * Clobbers r0 - r5 > + * > + */ > +FUNC(enable_boot_cpu_mm) > + /* Get the number of regions specified in MPUIR_EL2 */ > + mrc CP32(r5, MPUIR_EL2) > + and r5, r5, #NUM_MPU_REGIONS_MASK > + > + /* x0: region sel */ > + mov r0, #0 > + /* Xen text section. */ > + mov_w r1, _stext > + mov_w r2, _etext > + prepare_xen_region r0, r1, r2, r3, r4, r5, attr_prbar=REGION_TEXT_PRBAR > + > + /* Xen read-only data section. */ > + mov_w r1, _srodata > + mov_w r2, _erodata > + prepare_xen_region r0, r1, r2, r3, r4, r5, attr_prbar=REGION_RO_PRBAR > + > + /* Xen read-only after init and data section. (RW data) */ > + mov_w r1, __ro_after_init_start > + mov_w r2, __init_begin > + prepare_xen_region r0, r1, r2, r3, r4, r5 > + > + /* Xen code section. */ > + mov_w r1, __init_begin > + mov_w r2, __init_data_begin > + prepare_xen_region r0, r1, r2, r3, r4, r5, attr_prbar=REGION_TEXT_PRBAR > + > + /* Xen data and BSS section. */ > + mov_w r1, __init_data_begin > + mov_w r2, __bss_end > + prepare_xen_region r0, r1, r2, r3, r4, r5 > + > +#ifdef CONFIG_EARLY_PRINTK > + /* Xen early UART section. */ > + mov_w r1, CONFIG_EARLY_UART_BASE_ADDRESS > + mov_w r2, (CONFIG_EARLY_UART_BASE_ADDRESS + CONFIG_EARLY_UART_SIZE) > + prepare_xen_region r0, r1, r2, r3, r4, r5, > attr_prbar=REGION_DEVICE_PRBAR, attr_prlar=REGION_DEVICE_PRLAR > +#endif > + > + b enable_mpu > +END(enable_boot_cpu_mm) > + > +/* > + * We don't yet support secondary CPUs bring-up. Implement a dummy helper to > + * please the common code. > + */ > +FUNC(enable_secondary_cpu_mm) > + PRINT("- SMP not enabled yet -\r\n") > +1: wfe > + b 1b > +END(enable_secondary_cpu_mm) > + > +/* > + * Local variables: > + * mode: ASM > + * indent-tabs-mode: nil > + * End: > + */ > diff --git a/xen/arch/arm/include/asm/arm32/sysregs.h > b/xen/arch/arm/include/asm/arm32/sysregs.h > index 22871999af..a90d1610a1 100644 > --- a/xen/arch/arm/include/asm/arm32/sysregs.h > +++ b/xen/arch/arm/include/asm/arm32/sysregs.h > @@ -20,6 +20,13 @@ > * uses r0 as a placeholder register. */ > #define CMD_CP32(name...) "mcr " __stringify(CP32(r0, name)) ";" > > +#define REGION_TEXT_PRBAR 0x18 /* SH=11 AP=10 XN=0 */ > +#define REGION_RO_PRBAR 0x1D /* SH=11 AP=10 XN=1 */ > +#define REGION_DATA_PRBAR 0x19 /* SH=11 AP=00 XN=1 */ > +#define REGION_DEVICE_PRBAR 0x11 /* SH=10 AP=00 XN=1 */ > + > +#define WRITE_SYSREG_ASM(v, name) mcr CP32(v, name) Same comment as for previous patch. > + > #ifndef __ASSEMBLY__ > > /* C wrappers */ > diff --git a/xen/arch/arm/include/asm/cpregs.h > b/xen/arch/arm/include/asm/cpregs.h > index aec9e8f329..6019a2cbdd 100644 > --- a/xen/arch/arm/include/asm/cpregs.h > +++ b/xen/arch/arm/include/asm/cpregs.h > @@ -1,6 +1,10 @@ > #ifndef __ASM_ARM_CPREGS_H > #define __ASM_ARM_CPREGS_H > > +#ifdef CONFIG_MPU NIT: Do we really need to protect this include? I thought we do the ifdefery if we need to include either mmu or mpu. Here we don't have a choice and afaict there's nothing problematic in mpu/cpregs.h > +#include <asm/mpu/cpregs.h> > +#endif > + > /* > * AArch32 Co-processor registers. > * > diff --git a/xen/arch/arm/include/asm/mpu/cpregs.h > b/xen/arch/arm/include/asm/mpu/cpregs.h > new file mode 100644 > index 0000000000..6b20c7ceae > --- /dev/null > +++ b/xen/arch/arm/include/asm/mpu/cpregs.h > @@ -0,0 +1,24 @@ > +/* SPDX-License-Identifier: GPL-2.0-only */ > + > +#ifndef __ASM_ARM_MPU_CPREGS_H > +#define __ASM_ARM_MPU_CPREGS_H > + > +/* CP15 CR0: MPU Type Register */ > +#define HMPUIR p15,4,c0,c0,4 > + > +/* CP15 CR6: MPU Protection Region Base/Limit/Select Address Register */ > +#define HPRSELR p15,4,c6,c2,1 > +#define PRBAR_EL2 p15,4,c6,c3,0 > +#define PRLAR_EL2 p15,4,c6,c8,1 > + > +#define MPUIR_EL2 HMPUIR > +#define PRSELR_EL2 HPRSELR AFAIK, these macros are there to use AArch64 sysreg names in common code when compiling Arm32. This would mean they should be protected with #ifdef CONFIG_ARM_32. ~Michal
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |