* [PATCH v2 0/3] Enable R52 support for the first chunk of MPU support
@ 2025-06-06 16:48 Ayan Kumar Halder
2025-06-06 16:48 ` [PATCH v2 1/3] arm/mpu: Introduce MPU memory region map structure Ayan Kumar Halder
` (2 more replies)
0 siblings, 3 replies; 15+ messages in thread
From: Ayan Kumar Halder @ 2025-06-06 16:48 UTC (permalink / raw)
To: xen-devel
Cc: Ayan Kumar Halder, Stefano Stabellini, Julien Grall,
Bertrand Marquis, Michal Orzel, Volodymyr Babchuk
Hi all,
This patch serie enables R52 support based on Luca's series.
"[PATCH v6 0/6] First chunk for Arm R82 and MPU support".
Ayan Kumar Halder (3):
arm/mpu: Introduce MPU memory region map structure
arm/mpu: Provide and populate MPU C data structures
arm/mpu: Provide access to the MPU region from the C code
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/arm32/mpu.h | 34 ++++++++++-
xen/arch/arm/include/asm/mpu.h | 2 -
xen/arch/arm/include/asm/mpu/cpregs.h | 72 +++++++++++++++++++++++-
xen/arch/arm/include/asm/mpu/regions.inc | 2 +-
xen/arch/arm/mpu/mm.c | 51 +++++++++++++++--
9 files changed, 224 insertions(+), 10 deletions(-)
create mode 100644 xen/arch/arm/arm32/cache.S
--
2.25.1
^ permalink raw reply [flat|nested] 15+ messages in thread* [PATCH v2 1/3] arm/mpu: Introduce MPU memory region map structure 2025-06-06 16:48 [PATCH v2 0/3] Enable R52 support for the first chunk of MPU support Ayan Kumar Halder @ 2025-06-06 16:48 ` Ayan Kumar Halder 2025-06-09 7:31 ` Orzel, Michal 2025-06-06 16:48 ` [PATCH v2 2/3] arm/mpu: Provide and populate MPU C data structures Ayan Kumar Halder 2025-06-06 16:48 ` [PATCH v2 3/3] arm/mpu: Provide access to the MPU region from the C code Ayan Kumar Halder 2 siblings, 1 reply; 15+ messages in thread From: Ayan Kumar Halder @ 2025-06-06 16:48 UTC (permalink / raw) To: xen-devel Cc: Ayan Kumar Halder, Stefano Stabellini, Julien Grall, Bertrand Marquis, Michal Orzel, Volodymyr Babchuk Introduce pr_t typedef which is a structure having the prbar and prlar members, each being structured as the registers of the AArch32 Armv8-R architecture. Also, define MPU_REGION_RES0 to 0 as there are no reserved 0 bits beyond the BASE or LIMIT bitfields in prbar or prlar respectively. Signed-off-by: Ayan Kumar Halder <ayan.kumar.halder@amd.com> --- Changes from v1 :- 1. Preserve pr_t typedef in arch specific files. 2. Fix typo. xen/arch/arm/include/asm/arm32/mpu.h | 34 ++++++++++++++++++++++++++-- xen/arch/arm/mpu/mm.c | 2 ++ 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/xen/arch/arm/include/asm/arm32/mpu.h b/xen/arch/arm/include/asm/arm32/mpu.h index f0d4d4055c..fe139a2abe 100644 --- a/xen/arch/arm/include/asm/arm32/mpu.h +++ b/xen/arch/arm/include/asm/arm32/mpu.h @@ -5,10 +5,40 @@ #ifndef __ASSEMBLY__ +/* + * Unlike arm64, there are no reserved 0 bits beyond base and limit bitfield in + * prbar and prlar registers respectively. + */ +#define MPU_REGION_RES0 0x0 + +/* Hypervisor Protection Region Base Address Register */ +typedef union { + struct { + unsigned int xn:1; /* Execute-Never */ + unsigned int ap_0:1; /* Access Permission AP[0] */ + unsigned long ro:1; /* Access Permission AP[1] */ + unsigned int sh:2; /* Shareability */ + unsigned int res0:1; + unsigned int base:26; /* Base Address */ + } reg; + uint32_t bits; +} prbar_t; + +/* Hypervisor Protection Region Limit Address Register */ +typedef union { + struct { + unsigned int en:1; /* Region enable */ + unsigned int ai:3; /* Memory Attribute Index */ + unsigned int res0:2; + unsigned int limit:26; /* Limit Address */ + } reg; + uint32_t bits; +} prlar_t; + /* MPU Protection Region */ typedef struct { - uint32_t prbar; - uint32_t prlar; + prbar_t prbar; + prlar_t prlar; } pr_t; #endif /* __ASSEMBLY__ */ diff --git a/xen/arch/arm/mpu/mm.c b/xen/arch/arm/mpu/mm.c index 86fbe105af..2fb6b822c6 100644 --- a/xen/arch/arm/mpu/mm.c +++ b/xen/arch/arm/mpu/mm.c @@ -167,7 +167,9 @@ pr_t pr_of_addr(paddr_t base, paddr_t limit, unsigned int flags) /* Build up value for PRBAR_EL2. */ prbar = (prbar_t) { .reg = { +#ifdef CONFIG_ARM64 .xn_0 = 0, +#endif .xn = PAGE_XN_MASK(flags), .ap_0 = 0, .ro = PAGE_RO_MASK(flags) -- 2.25.1 ^ permalink raw reply related [flat|nested] 15+ messages in thread
* Re: [PATCH v2 1/3] arm/mpu: Introduce MPU memory region map structure 2025-06-06 16:48 ` [PATCH v2 1/3] arm/mpu: Introduce MPU memory region map structure Ayan Kumar Halder @ 2025-06-09 7:31 ` Orzel, Michal 0 siblings, 0 replies; 15+ messages in thread From: Orzel, Michal @ 2025-06-09 7:31 UTC (permalink / raw) To: Ayan Kumar Halder, xen-devel Cc: Stefano Stabellini, Julien Grall, Bertrand Marquis, Volodymyr Babchuk On 06/06/2025 18:48, Ayan Kumar Halder wrote: > Introduce pr_t typedef which is a structure having the prbar and prlar members, > each being structured as the registers of the AArch32 Armv8-R architecture. > > Also, define MPU_REGION_RES0 to 0 as there are no reserved 0 bits beyond the > BASE or LIMIT bitfields in prbar or prlar respectively. > > Signed-off-by: Ayan Kumar Halder <ayan.kumar.halder@amd.com> > --- > Changes from v1 :- > > 1. Preserve pr_t typedef in arch specific files. > > 2. Fix typo. > > xen/arch/arm/include/asm/arm32/mpu.h | 34 ++++++++++++++++++++++++++-- > xen/arch/arm/mpu/mm.c | 2 ++ > 2 files changed, 34 insertions(+), 2 deletions(-) > > diff --git a/xen/arch/arm/include/asm/arm32/mpu.h b/xen/arch/arm/include/asm/arm32/mpu.h > index f0d4d4055c..fe139a2abe 100644 > --- a/xen/arch/arm/include/asm/arm32/mpu.h > +++ b/xen/arch/arm/include/asm/arm32/mpu.h > @@ -5,10 +5,40 @@ > > #ifndef __ASSEMBLY__ > > +/* > + * Unlike arm64, there are no reserved 0 bits beyond base and limit bitfield in > + * prbar and prlar registers respectively. > + */ > +#define MPU_REGION_RES0 0x0 > + > +/* Hypervisor Protection Region Base Address Register */ > +typedef union { > + struct { > + unsigned int xn:1; /* Execute-Never */ > + unsigned int ap_0:1; /* Access Permission AP[0] */ > + unsigned long ro:1; /* Access Permission AP[1] */ It should be unsigned int, not long. With that fixed: Reviewed-by: Michal Orzel <michal.orzel@amd.com> ~Michal ^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH v2 2/3] arm/mpu: Provide and populate MPU C data structures 2025-06-06 16:48 [PATCH v2 0/3] Enable R52 support for the first chunk of MPU support Ayan Kumar Halder 2025-06-06 16:48 ` [PATCH v2 1/3] arm/mpu: Introduce MPU memory region map structure Ayan Kumar Halder @ 2025-06-06 16:48 ` Ayan Kumar Halder 2025-06-09 7:41 ` Orzel, Michal 2025-06-06 16:48 ` [PATCH v2 3/3] arm/mpu: Provide access to the MPU region from the C code Ayan Kumar Halder 2 siblings, 1 reply; 15+ messages in thread From: Ayan Kumar Halder @ 2025-06-06 16:48 UTC (permalink / raw) To: xen-devel Cc: Ayan Kumar Halder, Stefano Stabellini, Julien Grall, Bertrand Marquis, Michal Orzel, Volodymyr Babchuk 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@amd.com> --- 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 */ + 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 + */ +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 */ .endm #endif -- 2.25.1 ^ permalink raw reply related [flat|nested] 15+ messages in thread
* Re: [PATCH v2 2/3] arm/mpu: Provide and populate MPU C data structures 2025-06-06 16:48 ` [PATCH v2 2/3] arm/mpu: Provide and populate MPU C data structures Ayan Kumar Halder @ 2025-06-09 7:41 ` Orzel, Michal 2025-06-09 8:27 ` Ayan Kumar Halder 0 siblings, 1 reply; 15+ messages in thread From: Orzel, Michal @ 2025-06-09 7:41 UTC (permalink / raw) To: Ayan Kumar Halder, xen-devel Cc: Stefano Stabellini, Julien Grall, Bertrand Marquis, Volodymyr Babchuk 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@amd.com> > --- > 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 ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH v2 2/3] arm/mpu: Provide and populate MPU C data structures 2025-06-09 7:41 ` Orzel, Michal @ 2025-06-09 8:27 ` Ayan Kumar Halder 2025-06-09 8:42 ` Julien Grall 0 siblings, 1 reply; 15+ messages in thread From: Ayan Kumar Halder @ 2025-06-09 8:27 UTC (permalink / raw) To: Orzel, Michal, Ayan Kumar Halder, xen-devel Cc: Stefano Stabellini, Julien Grall, Bertrand Marquis, Volodymyr Babchuk Hi Michal, On 09/06/2025 08:41, Orzel, Michal wrote: > > 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@amd.com> >> --- >> 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)? Ah my last response was not sent. I realized that I cannot use strd due to the following error Error: first transfer register must be even -- `strd r3,r4,[r1]' So, I am using stm with the following comment stm \dst, {\reg1, \reg2} /* reg2 should be a higher register than reg1 */ - Ayan > > ~Michal > ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH v2 2/3] arm/mpu: Provide and populate MPU C data structures 2025-06-09 8:27 ` Ayan Kumar Halder @ 2025-06-09 8:42 ` Julien Grall 2025-06-09 9:16 ` Ayan Kumar Halder 0 siblings, 1 reply; 15+ messages in thread From: Julien Grall @ 2025-06-09 8:42 UTC (permalink / raw) To: Ayan Kumar Halder, Orzel, Michal, Ayan Kumar Halder, xen-devel Cc: Stefano Stabellini, Bertrand Marquis, Volodymyr Babchuk Hi Ayan, On 09/06/2025 09:27, Ayan Kumar Halder wrote: > On 09/06/2025 08:41, Orzel, Michal wrote: >>> 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)? > > Ah my last response was not sent. > > I realized that I cannot use strd due to the following error > > Error: first transfer register must be even -- `strd r3,r4,[r1]' Ah I missed the "even" part when reading the specification. However, we control the set of registers, so we can't we follow the restriction? This would be better... > > So, I am using stm with the following comment ... than a comment and hoping the developper/reviewer will notice it (the code is also misplaced). I am ready to bet this will likely cause some problem in the future. Cheers, -- Julien Grall ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH v2 2/3] arm/mpu: Provide and populate MPU C data structures 2025-06-09 8:42 ` Julien Grall @ 2025-06-09 9:16 ` Ayan Kumar Halder 2025-06-09 10:43 ` Ayan Kumar Halder 0 siblings, 1 reply; 15+ messages in thread From: Ayan Kumar Halder @ 2025-06-09 9:16 UTC (permalink / raw) To: Julien Grall, Orzel, Michal, Ayan Kumar Halder, xen-devel Cc: Stefano Stabellini, Bertrand Marquis, Volodymyr Babchuk On 09/06/2025 09:42, Julien Grall wrote: > Hi Ayan, Hi Julien, > > On 09/06/2025 09:27, Ayan Kumar Halder wrote: >> On 09/06/2025 08:41, Orzel, Michal wrote: >>>> 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)? >> >> Ah my last response was not sent. >> >> I realized that I cannot use strd due to the following error >> >> Error: first transfer register must be even -- `strd r3,r4,[r1]' > > Ah I missed the "even" part when reading the specification. However, > we control the set of registers, so we can't we follow the > restriction? This would be better... I am ok to follow this. I just want to make sure that this looks ok to you prepare_xen_region() invokes store_pair(). They are in common header. So we need to make the change wherever prepare_xen_region() is invoked from arm32/mpu/head.S. This would look like --- a/xen/arch/arm/arm32/mpu/head.S +++ b/xen/arch/arm/arm32/mpu/head.S @@ -58,33 +58,33 @@ FUNC(enable_boot_cpu_mm) /* 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 + prepare_xen_region r0, r1, r2, r4, r3, 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 + prepare_xen_region r0, r1, r2, r4, r3, 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 + prepare_xen_region r0, r1, r2, r4, r3, 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 + prepare_xen_region r0, r1, r2, r4, r3, 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 + prepare_xen_region r0, r1, r2, r4, r3, 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 + prepare_xen_region r0, r1, r2, r4, r3, r5, attr_prbar=REGION_DEVICE_PRBAR, attr_prlar=REGION_DEVICE_PRLAR #endif zero_mpu: @@ -93,7 +93,7 @@ zero_mpu: beq out_zero_mpu mov r1, #0 mov r2, #1 - prepare_xen_region r0, r1, r2, r3, r4, r5, attr_prlar=REGION_DISABLED_PRLAR + prepare_xen_region r0, r1, r2, r4, r3, r5, attr_prlar=REGION_DISABLED_PRLAR So this would look a different different from its arm64 counterpart. Are you ok with this change ? - Ayan > >> >> So, I am using stm with the following comment > > ... than a comment and hoping the developper/reviewer will notice it > (the code is also misplaced). I am ready to bet this will likely cause > some problem in the future. > > Cheers, > ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH v2 2/3] arm/mpu: Provide and populate MPU C data structures 2025-06-09 9:16 ` Ayan Kumar Halder @ 2025-06-09 10:43 ` Ayan Kumar Halder 2025-06-09 11:26 ` Julien Grall 0 siblings, 1 reply; 15+ messages in thread From: Ayan Kumar Halder @ 2025-06-09 10:43 UTC (permalink / raw) To: Julien Grall, Orzel, Michal, Ayan Kumar Halder, xen-devel Cc: Stefano Stabellini, Bertrand Marquis, Volodymyr Babchuk Hi, On 09/06/2025 10:16, Ayan Kumar Halder wrote: > > On 09/06/2025 09:42, Julien Grall wrote: >> Hi Ayan, > Hi Julien, >> >> On 09/06/2025 09:27, Ayan Kumar Halder wrote: >>> On 09/06/2025 08:41, Orzel, Michal wrote: >>>>> 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)? >>> >>> Ah my last response was not sent. >>> >>> I realized that I cannot use strd due to the following error >>> >>> Error: first transfer register must be even -- `strd r3,r4,[r1]' >> >> Ah I missed the "even" part when reading the specification. However, >> we control the set of registers, so we can't we follow the >> restriction? This would be better... > > I am ok to follow this. I just want to make sure that this looks ok to > you > > prepare_xen_region() invokes store_pair(). They are in common header. > > So we need to make the change wherever prepare_xen_region() is invoked > from arm32/mpu/head.S. This would look like > > --- a/xen/arch/arm/arm32/mpu/head.S > +++ b/xen/arch/arm/arm32/mpu/head.S > @@ -58,33 +58,33 @@ FUNC(enable_boot_cpu_mm) > /* 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 > + prepare_xen_region r0, r1, r2, r4, r3, r5, > attr_prbar=REGION_TEXT_PRBAR My mistake, It should be prepare_xen_region r0, r1, r2, r4, r5, r6, attr_prbar=REGION_TEXT_PRBAR We will be clobbering an extra register. - Ayan ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH v2 2/3] arm/mpu: Provide and populate MPU C data structures 2025-06-09 10:43 ` Ayan Kumar Halder @ 2025-06-09 11:26 ` Julien Grall 0 siblings, 0 replies; 15+ messages in thread From: Julien Grall @ 2025-06-09 11:26 UTC (permalink / raw) To: Ayan Kumar Halder, Orzel, Michal, Ayan Kumar Halder, xen-devel Cc: Stefano Stabellini, Bertrand Marquis, Volodymyr Babchuk Hi Ayan, On 09/06/2025 11:43, Ayan Kumar Halder wrote: > Hi, > > On 09/06/2025 10:16, Ayan Kumar Halder wrote: >> >> On 09/06/2025 09:42, Julien Grall wrote: >>> Hi Ayan, >> Hi Julien, >>> >>> On 09/06/2025 09:27, Ayan Kumar Halder wrote: >>>> On 09/06/2025 08:41, Orzel, Michal wrote: >>>>>> 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)? >>>> >>>> Ah my last response was not sent. >>>> >>>> I realized that I cannot use strd due to the following error >>>> >>>> Error: first transfer register must be even -- `strd r3,r4,[r1]' >>> >>> Ah I missed the "even" part when reading the specification. However, >>> we control the set of registers, so we can't we follow the >>> restriction? This would be better... >> >> I am ok to follow this. I just want to make sure that this looks ok to >> you >> >> prepare_xen_region() invokes store_pair(). They are in common header. >> >> So we need to make the change wherever prepare_xen_region() is invoked >> from arm32/mpu/head.S. This would look like >> >> --- a/xen/arch/arm/arm32/mpu/head.S >> +++ b/xen/arch/arm/arm32/mpu/head.S >> @@ -58,33 +58,33 @@ FUNC(enable_boot_cpu_mm) >> /* 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 >> + prepare_xen_region r0, r1, r2, r4, r3, r5, >> attr_prbar=REGION_TEXT_PRBAR > > My mistake, It should be > > prepare_xen_region r0, r1, r2, r4, r5, r6, attr_prbar=REGION_TEXT_PRBAR > > We will be clobbering an extra register. Why can't we use r3 instead of r6? > So this would look a different different from its arm64 counterpart. I don't see the problem with that. The code is not common. And TBH prepare_xen_region should never have been common ... but I will not re-open this discussion :). Cheers, -- Julien Grall ^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH v2 3/3] arm/mpu: Provide access to the MPU region from the C code 2025-06-06 16:48 [PATCH v2 0/3] Enable R52 support for the first chunk of MPU support Ayan Kumar Halder 2025-06-06 16:48 ` [PATCH v2 1/3] arm/mpu: Introduce MPU memory region map structure Ayan Kumar Halder 2025-06-06 16:48 ` [PATCH v2 2/3] arm/mpu: Provide and populate MPU C data structures Ayan Kumar Halder @ 2025-06-06 16:48 ` Ayan Kumar Halder 2025-06-09 7:44 ` Orzel, Michal 2025-06-09 8:37 ` Luca Fancellu 2 siblings, 2 replies; 15+ messages in thread From: Ayan Kumar Halder @ 2025-06-06 16:48 UTC (permalink / raw) To: xen-devel Cc: Ayan Kumar Halder, Stefano Stabellini, Julien Grall, Bertrand Marquis, Michal Orzel, Volodymyr Babchuk Enable the helper functions defined in mpu/mm.c and asm/mpu.h for ARM32. Define the register definitions for HPRBAR{0..31} and HPRLAR{0..31}. One can directly access the first 32 MPU regions using the above registers without the use of PRSELR. Also fix the register definition for HPRLAR. Signed-off-by: Ayan Kumar Halder <ayan.kumar.halder@amd.com> --- Change from :- v1 - 1. Enable write_protection_region() for aarch32. xen/arch/arm/include/asm/mpu.h | 2 - xen/arch/arm/include/asm/mpu/cpregs.h | 72 ++++++++++++++++++++++++++- xen/arch/arm/mpu/mm.c | 49 ++++++++++++++++-- 3 files changed, 116 insertions(+), 7 deletions(-) diff --git a/xen/arch/arm/include/asm/mpu.h b/xen/arch/arm/include/asm/mpu.h index 8f06ddac0f..63560c613b 100644 --- a/xen/arch/arm/include/asm/mpu.h +++ b/xen/arch/arm/include/asm/mpu.h @@ -25,7 +25,6 @@ #ifndef __ASSEMBLY__ -#ifdef CONFIG_ARM_64 /* * Set base address of MPU protection region. * @@ -85,7 +84,6 @@ static inline bool region_is_valid(const pr_t *pr) { return pr->prlar.reg.en; } -#endif /* CONFIG_ARM_64 */ #endif /* __ASSEMBLY__ */ diff --git a/xen/arch/arm/include/asm/mpu/cpregs.h b/xen/arch/arm/include/asm/mpu/cpregs.h index d5cd0e04d5..9f3b32acd7 100644 --- a/xen/arch/arm/include/asm/mpu/cpregs.h +++ b/xen/arch/arm/include/asm/mpu/cpregs.h @@ -6,16 +6,86 @@ /* CP15 CR0: MPU Type Register */ #define HMPUIR p15,4,c0,c0,4 +/* CP15 CR6: Protection Region Enable Register */ +#define HPRENR p15,4,c6,c1,1 + /* CP15 CR6: MPU Protection Region Base/Limit/Select Address Register */ #define HPRSELR p15,4,c6,c2,1 #define HPRBAR p15,4,c6,c3,0 -#define HPRLAR p15,4,c6,c8,1 +#define HPRLAR p15,4,c6,c3,1 + +/* CP15 CR6: MPU Protection Region Base/Limit Address Register */ +#define HPRBAR0 p15,4,c6,c8,0 +#define HPRLAR0 p15,4,c6,c8,1 +#define HPRBAR1 p15,4,c6,c8,4 +#define HPRLAR1 p15,4,c6,c8,5 +#define HPRBAR2 p15,4,c6,c9,0 +#define HPRLAR2 p15,4,c6,c9,1 +#define HPRBAR3 p15,4,c6,c9,4 +#define HPRLAR3 p15,4,c6,c9,5 +#define HPRBAR4 p15,4,c6,c10,0 +#define HPRLAR4 p15,4,c6,c10,1 +#define HPRBAR5 p15,4,c6,c10,4 +#define HPRLAR5 p15,4,c6,c10,5 +#define HPRBAR6 p15,4,c6,c11,0 +#define HPRLAR6 p15,4,c6,c11,1 +#define HPRBAR7 p15,4,c6,c11,4 +#define HPRLAR7 p15,4,c6,c11,5 +#define HPRBAR8 p15,4,c6,c12,0 +#define HPRLAR8 p15,4,c6,c12,1 +#define HPRBAR9 p15,4,c6,c12,4 +#define HPRLAR9 p15,4,c6,c12,5 +#define HPRBAR10 p15,4,c6,c13,0 +#define HPRLAR10 p15,4,c6,c13,1 +#define HPRBAR11 p15,4,c6,c13,4 +#define HPRLAR11 p15,4,c6,c13,5 +#define HPRBAR12 p15,4,c6,c14,0 +#define HPRLAR12 p15,4,c6,c14,1 +#define HPRBAR13 p15,4,c6,c14,4 +#define HPRLAR13 p15,4,c6,c14,5 +#define HPRBAR14 p15,4,c6,c15,0 +#define HPRLAR14 p15,4,c6,c15,1 +#define HPRBAR15 p15,4,c6,c15,4 +#define HPRLAR15 p15,4,c6,c15,5 +#define HPRBAR16 p15,5,c6,c8,0 +#define HPRLAR16 p15,5,c6,c8,1 +#define HPRBAR17 p15,5,c6,c8,4 +#define HPRLAR17 p15,5,c6,c8,5 +#define HPRBAR18 p15,5,c6,c9,0 +#define HPRLAR18 p15,5,c6,c9,1 +#define HPRBAR19 p15,5,c6,c9,4 +#define HPRLAR19 p15,5,c6,c9,5 +#define HPRBAR20 p15,5,c6,c10,0 +#define HPRLAR20 p15,5,c6,c10,1 +#define HPRBAR21 p15,5,c6,c10,4 +#define HPRLAR21 p15,5,c6,c10,5 +#define HPRBAR22 p15,5,c6,c11,0 +#define HPRLAR22 p15,5,c6,c11,1 +#define HPRBAR23 p15,5,c6,c11,4 +#define HPRLAR23 p15,5,c6,c11,5 +#define HPRBAR24 p15,5,c6,c12,0 +#define HPRLAR24 p15,5,c6,c12,1 +#define HPRBAR25 p15,5,c6,c12,4 +#define HPRLAR25 p15,5,c6,c12,5 +#define HPRBAR26 p15,5,c6,c13,0 +#define HPRLAR26 p15,5,c6,c13,1 +#define HPRBAR27 p15,5,c6,c13,4 +#define HPRLAR27 p15,5,c6,c13,5 +#define HPRBAR28 p15,5,c6,c14,0 +#define HPRLAR28 p15,5,c6,c14,1 +#define HPRBAR29 p15,5,c6,c14,4 +#define HPRLAR29 p15,5,c6,c14,5 +#define HPRBAR30 p15,5,c6,c15,0 +#define HPRLAR30 p15,5,c6,c15,1 +#define HPRBAR31 p15,5,c6,c15,4 +#define HPRLAR31 p15,5,c6,c15,5 /* Aliases of AArch64 names for use in common code */ #ifdef CONFIG_ARM_32 /* Alphabetically... */ #define MPUIR_EL2 HMPUIR #define PRBAR_EL2 HPRBAR +#define PRENR_EL2 HPRENR #define PRLAR_EL2 HPRLAR #define PRSELR_EL2 HPRSELR #endif /* CONFIG_ARM_32 */ diff --git a/xen/arch/arm/mpu/mm.c b/xen/arch/arm/mpu/mm.c index 2fb6b822c6..74e96ca571 100644 --- a/xen/arch/arm/mpu/mm.c +++ b/xen/arch/arm/mpu/mm.c @@ -40,7 +40,10 @@ pr_t __cacheline_aligned __section(".data") xen_mpumap[MAX_MPU_REGION_NR]; #define PRBAR_EL2_(n) PRBAR##n##_EL2 #define PRLAR_EL2_(n) PRLAR##n##_EL2 -#endif /* CONFIG_ARM_64 */ +#else /* CONFIG_ARM_64 */ +#define PRBAR_EL2_(n) HPRBAR##n +#define PRLAR_EL2_(n) HPRLAR##n +#endif /* !CONFIG_ARM_64 */ #define GENERATE_WRITE_PR_REG_CASE(num, pr) \ case num: \ @@ -68,7 +71,6 @@ static void __init __maybe_unused build_assertions(void) BUILD_BUG_ON(PAGE_SIZE != SZ_4K); } -#ifdef CONFIG_ARM_64 /* * Armv8-R supports direct access and indirect access to the MPU regions through * registers: @@ -85,6 +87,7 @@ static void __init __maybe_unused build_assertions(void) */ static void prepare_selector(uint8_t *sel) { +#ifdef CONFIG_ARM_64 uint8_t cur_sel = *sel; /* @@ -98,7 +101,8 @@ static void prepare_selector(uint8_t *sel) WRITE_SYSREG(cur_sel, PRSELR_EL2); isb(); } - *sel &= 0xFU; + *sel = *sel & 0xFU; +#endif } void read_protection_region(pr_t *pr_read, uint8_t sel) @@ -123,6 +127,24 @@ void read_protection_region(pr_t *pr_read, uint8_t sel) GENERATE_READ_PR_REG_CASE(13, pr_read); GENERATE_READ_PR_REG_CASE(14, pr_read); GENERATE_READ_PR_REG_CASE(15, pr_read); +#ifdef CONFIG_ARM_32 + GENERATE_READ_PR_REG_CASE(16, pr_read); + GENERATE_READ_PR_REG_CASE(17, pr_read); + GENERATE_READ_PR_REG_CASE(18, pr_read); + GENERATE_READ_PR_REG_CASE(19, pr_read); + GENERATE_READ_PR_REG_CASE(20, pr_read); + GENERATE_READ_PR_REG_CASE(21, pr_read); + GENERATE_READ_PR_REG_CASE(22, pr_read); + GENERATE_READ_PR_REG_CASE(23, pr_read); + GENERATE_READ_PR_REG_CASE(24, pr_read); + GENERATE_READ_PR_REG_CASE(25, pr_read); + GENERATE_READ_PR_REG_CASE(26, pr_read); + GENERATE_READ_PR_REG_CASE(27, pr_read); + GENERATE_READ_PR_REG_CASE(28, pr_read); + GENERATE_READ_PR_REG_CASE(29, pr_read); + GENERATE_READ_PR_REG_CASE(30, pr_read); + GENERATE_READ_PR_REG_CASE(31, pr_read); +#endif default: BUG(); /* Can't happen */ break; @@ -151,6 +173,24 @@ void write_protection_region(const pr_t *pr_write, uint8_t sel) GENERATE_WRITE_PR_REG_CASE(13, pr_write); GENERATE_WRITE_PR_REG_CASE(14, pr_write); GENERATE_WRITE_PR_REG_CASE(15, pr_write); +#ifdef CONFIG_ARM_32 + GENERATE_WRITE_PR_REG_CASE(16, pr_write); + GENERATE_WRITE_PR_REG_CASE(17, pr_write); + GENERATE_WRITE_PR_REG_CASE(18, pr_write); + GENERATE_WRITE_PR_REG_CASE(19, pr_write); + GENERATE_WRITE_PR_REG_CASE(20, pr_write); + GENERATE_WRITE_PR_REG_CASE(21, pr_write); + GENERATE_WRITE_PR_REG_CASE(22, pr_write); + GENERATE_WRITE_PR_REG_CASE(23, pr_write); + GENERATE_WRITE_PR_REG_CASE(24, pr_write); + GENERATE_WRITE_PR_REG_CASE(25, pr_write); + GENERATE_WRITE_PR_REG_CASE(26, pr_write); + GENERATE_WRITE_PR_REG_CASE(27, pr_write); + GENERATE_WRITE_PR_REG_CASE(28, pr_write); + GENERATE_WRITE_PR_REG_CASE(29, pr_write); + GENERATE_WRITE_PR_REG_CASE(30, pr_write); + GENERATE_WRITE_PR_REG_CASE(31, pr_write); +#endif default: BUG(); /* Can't happen */ break; @@ -208,7 +248,9 @@ pr_t pr_of_addr(paddr_t base, paddr_t limit, unsigned int flags) /* Build up value for PRLAR_EL2. */ prlar = (prlar_t) { .reg = { +#ifdef CONFIG_ARM_64 .ns = 0, /* Hyp mode is in secure world */ +#endif .ai = attr_idx, .en = 1, /* Region enabled */ }}; @@ -225,7 +267,6 @@ pr_t pr_of_addr(paddr_t base, paddr_t limit, unsigned int flags) return region; } -#endif /* CONFIG_ARM_64 */ void __init setup_mm(void) { -- 2.25.1 ^ permalink raw reply related [flat|nested] 15+ messages in thread
* Re: [PATCH v2 3/3] arm/mpu: Provide access to the MPU region from the C code 2025-06-06 16:48 ` [PATCH v2 3/3] arm/mpu: Provide access to the MPU region from the C code Ayan Kumar Halder @ 2025-06-09 7:44 ` Orzel, Michal 2025-06-09 8:37 ` Luca Fancellu 1 sibling, 0 replies; 15+ messages in thread From: Orzel, Michal @ 2025-06-09 7:44 UTC (permalink / raw) To: Ayan Kumar Halder, xen-devel Cc: Stefano Stabellini, Julien Grall, Bertrand Marquis, Volodymyr Babchuk On 06/06/2025 18:48, Ayan Kumar Halder wrote: > Enable the helper functions defined in mpu/mm.c and asm/mpu.h for ARM32. > Define the register definitions for HPRBAR{0..31} and HPRLAR{0..31}. > One can directly access the first 32 MPU regions using the above registers > without the use of PRSELR. > > Also fix the register definition for HPRLAR. > > Signed-off-by: Ayan Kumar Halder <ayan.kumar.halder@amd.com> It looks good apart from ... [snip] > @@ -98,7 +101,8 @@ static void prepare_selector(uint8_t *sel) > WRITE_SYSREG(cur_sel, PRSELR_EL2); > isb(); > } > - *sel &= 0xFU; > + *sel = *sel & 0xFU; this change. Why? Apart from that: Acked-by: Michal Orzel <michal.orzel@amd.com> ~Michal ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH v2 3/3] arm/mpu: Provide access to the MPU region from the C code 2025-06-06 16:48 ` [PATCH v2 3/3] arm/mpu: Provide access to the MPU region from the C code Ayan Kumar Halder 2025-06-09 7:44 ` Orzel, Michal @ 2025-06-09 8:37 ` Luca Fancellu 2025-06-09 9:16 ` Luca Fancellu 2025-06-09 9:26 ` Ayan Kumar Halder 1 sibling, 2 replies; 15+ messages in thread From: Luca Fancellu @ 2025-06-09 8:37 UTC (permalink / raw) To: Ayan Kumar Halder Cc: xen-devel@lists.xenproject.org, Stefano Stabellini, Julien Grall, Bertrand Marquis, Michal Orzel, Volodymyr Babchuk Hi Ayan, If I understand correctly Armv8-R AArch32 supports up to 255 regions, so I would expect ... > /* > * Armv8-R supports direct access and indirect access to the MPU regions through > * registers: > @@ -85,6 +87,7 @@ static void __init __maybe_unused build_assertions(void) > */ > static void prepare_selector(uint8_t *sel) > { > +#ifdef CONFIG_ARM_64 > uint8_t cur_sel = *sel; > > /* > @@ -98,7 +101,8 @@ static void prepare_selector(uint8_t *sel) > WRITE_SYSREG(cur_sel, PRSELR_EL2); > isb(); > } > - *sel &= 0xFU; > + *sel = *sel & 0xFU; > +#endif something here to check if the selector is 0-31 or not and: - set the selector to 0 if set is 0-31 - set the selector to 32-255 if sel > 32 And ... > } > > void read_protection_region(pr_t *pr_read, uint8_t sel) > @@ -123,6 +127,24 @@ void read_protection_region(pr_t *pr_read, uint8_t sel) > GENERATE_READ_PR_REG_CASE(13, pr_read); > GENERATE_READ_PR_REG_CASE(14, pr_read); > GENERATE_READ_PR_REG_CASE(15, pr_read); > +#ifdef CONFIG_ARM_32 > + GENERATE_READ_PR_REG_CASE(16, pr_read); > + GENERATE_READ_PR_REG_CASE(17, pr_read); > + GENERATE_READ_PR_REG_CASE(18, pr_read); > + GENERATE_READ_PR_REG_CASE(19, pr_read); > + GENERATE_READ_PR_REG_CASE(20, pr_read); > + GENERATE_READ_PR_REG_CASE(21, pr_read); > + GENERATE_READ_PR_REG_CASE(22, pr_read); > + GENERATE_READ_PR_REG_CASE(23, pr_read); > + GENERATE_READ_PR_REG_CASE(24, pr_read); > + GENERATE_READ_PR_REG_CASE(25, pr_read); > + GENERATE_READ_PR_REG_CASE(26, pr_read); > + GENERATE_READ_PR_REG_CASE(27, pr_read); > + GENERATE_READ_PR_REG_CASE(28, pr_read); > + GENERATE_READ_PR_REG_CASE(29, pr_read); > + GENERATE_READ_PR_REG_CASE(30, pr_read); > + GENERATE_READ_PR_REG_CASE(31, pr_read); > +#endif > default: have something here for Arm32 to access the regions 32-255 > BUG(); /* Can't happen */ > break; > @@ -151,6 +173,24 @@ void write_protection_region(const pr_t *pr_write, uint8_t sel) > GENERATE_WRITE_PR_REG_CASE(13, pr_write); > GENERATE_WRITE_PR_REG_CASE(14, pr_write); > GENERATE_WRITE_PR_REG_CASE(15, pr_write); > +#ifdef CONFIG_ARM_32 > + GENERATE_WRITE_PR_REG_CASE(16, pr_write); > + GENERATE_WRITE_PR_REG_CASE(17, pr_write); > + GENERATE_WRITE_PR_REG_CASE(18, pr_write); > + GENERATE_WRITE_PR_REG_CASE(19, pr_write); > + GENERATE_WRITE_PR_REG_CASE(20, pr_write); > + GENERATE_WRITE_PR_REG_CASE(21, pr_write); > + GENERATE_WRITE_PR_REG_CASE(22, pr_write); > + GENERATE_WRITE_PR_REG_CASE(23, pr_write); > + GENERATE_WRITE_PR_REG_CASE(24, pr_write); > + GENERATE_WRITE_PR_REG_CASE(25, pr_write); > + GENERATE_WRITE_PR_REG_CASE(26, pr_write); > + GENERATE_WRITE_PR_REG_CASE(27, pr_write); > + GENERATE_WRITE_PR_REG_CASE(28, pr_write); > + GENERATE_WRITE_PR_REG_CASE(29, pr_write); > + GENERATE_WRITE_PR_REG_CASE(30, pr_write); > + GENERATE_WRITE_PR_REG_CASE(31, pr_write); > +#endif > default: also here have something for Arm32 to access the regions 32-255 > BUG(); /* Can't happen */ > break; Please let me know your thoughts. Cheers, Luca ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH v2 3/3] arm/mpu: Provide access to the MPU region from the C code 2025-06-09 8:37 ` Luca Fancellu @ 2025-06-09 9:16 ` Luca Fancellu 2025-06-09 9:26 ` Ayan Kumar Halder 1 sibling, 0 replies; 15+ messages in thread From: Luca Fancellu @ 2025-06-09 9:16 UTC (permalink / raw) To: Ayan Kumar Halder Cc: xen-devel@lists.xenproject.org, Stefano Stabellini, Julien Grall, Bertrand Marquis, Michal Orzel, Volodymyr Babchuk Oh sorry forgot one thing ... > >> /* >> * Armv8-R supports direct access and indirect access to the MPU regions through >> * registers: >> @@ -85,6 +87,7 @@ static void __init __maybe_unused build_assertions(void) >> */ >> static void prepare_selector(uint8_t *sel) >> { >> +#ifdef CONFIG_ARM_64 >> uint8_t cur_sel = *sel; >> >> /* >> @@ -98,7 +101,8 @@ static void prepare_selector(uint8_t *sel) >> WRITE_SYSREG(cur_sel, PRSELR_EL2); >> isb(); >> } >> - *sel &= 0xFU; >> + *sel = *sel & 0xFU; this line is not part of this commit, maybe rebase clash? Cheers, Luca ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH v2 3/3] arm/mpu: Provide access to the MPU region from the C code 2025-06-09 8:37 ` Luca Fancellu 2025-06-09 9:16 ` Luca Fancellu @ 2025-06-09 9:26 ` Ayan Kumar Halder 1 sibling, 0 replies; 15+ messages in thread From: Ayan Kumar Halder @ 2025-06-09 9:26 UTC (permalink / raw) To: Luca Fancellu, Ayan Kumar Halder Cc: xen-devel@lists.xenproject.org, Stefano Stabellini, Julien Grall, Bertrand Marquis, Michal Orzel, Volodymyr Babchuk On 09/06/2025 09:37, Luca Fancellu wrote: > Hi Ayan, Hi Luca, > > If I understand correctly Armv8-R AArch32 supports up to 255 regions, so I would expect ... > >> /* >> * Armv8-R supports direct access and indirect access to the MPU regions through >> * registers: >> @@ -85,6 +87,7 @@ static void __init __maybe_unused build_assertions(void) >> */ >> static void prepare_selector(uint8_t *sel) >> { >> +#ifdef CONFIG_ARM_64 >> uint8_t cur_sel = *sel; >> >> /* >> @@ -98,7 +101,8 @@ static void prepare_selector(uint8_t *sel) >> WRITE_SYSREG(cur_sel, PRSELR_EL2); >> isb(); >> } >> - *sel &= 0xFU; >> + *sel = *sel & 0xFU; >> +#endif > something here to check if the selector is 0-31 or not and: > > - set the selector to 0 if set is 0-31 > - set the selector to 32-255 if sel > 32 yes, good catch. I was initially thinking of supporting only the first 32 regions for arm32. So, it would BUG() for region numbered 32 onwards. I can expand the patch to support all the 255 regions. > > And ... > > >> } >> >> void read_protection_region(pr_t *pr_read, uint8_t sel) >> @@ -123,6 +127,24 @@ void read_protection_region(pr_t *pr_read, uint8_t sel) >> GENERATE_READ_PR_REG_CASE(13, pr_read); >> GENERATE_READ_PR_REG_CASE(14, pr_read); >> GENERATE_READ_PR_REG_CASE(15, pr_read); >> +#ifdef CONFIG_ARM_32 >> + GENERATE_READ_PR_REG_CASE(16, pr_read); >> + GENERATE_READ_PR_REG_CASE(17, pr_read); >> + GENERATE_READ_PR_REG_CASE(18, pr_read); >> + GENERATE_READ_PR_REG_CASE(19, pr_read); >> + GENERATE_READ_PR_REG_CASE(20, pr_read); >> + GENERATE_READ_PR_REG_CASE(21, pr_read); >> + GENERATE_READ_PR_REG_CASE(22, pr_read); >> + GENERATE_READ_PR_REG_CASE(23, pr_read); >> + GENERATE_READ_PR_REG_CASE(24, pr_read); >> + GENERATE_READ_PR_REG_CASE(25, pr_read); >> + GENERATE_READ_PR_REG_CASE(26, pr_read); >> + GENERATE_READ_PR_REG_CASE(27, pr_read); >> + GENERATE_READ_PR_REG_CASE(28, pr_read); >> + GENERATE_READ_PR_REG_CASE(29, pr_read); >> + GENERATE_READ_PR_REG_CASE(30, pr_read); >> + GENERATE_READ_PR_REG_CASE(31, pr_read); >> +#endif >> default: > have something here for Arm32 to access the regions 32-255 > > >> BUG(); /* Can't happen */ >> break; >> @@ -151,6 +173,24 @@ void write_protection_region(const pr_t *pr_write, uint8_t sel) >> GENERATE_WRITE_PR_REG_CASE(13, pr_write); >> GENERATE_WRITE_PR_REG_CASE(14, pr_write); >> GENERATE_WRITE_PR_REG_CASE(15, pr_write); >> +#ifdef CONFIG_ARM_32 >> + GENERATE_WRITE_PR_REG_CASE(16, pr_write); >> + GENERATE_WRITE_PR_REG_CASE(17, pr_write); >> + GENERATE_WRITE_PR_REG_CASE(18, pr_write); >> + GENERATE_WRITE_PR_REG_CASE(19, pr_write); >> + GENERATE_WRITE_PR_REG_CASE(20, pr_write); >> + GENERATE_WRITE_PR_REG_CASE(21, pr_write); >> + GENERATE_WRITE_PR_REG_CASE(22, pr_write); >> + GENERATE_WRITE_PR_REG_CASE(23, pr_write); >> + GENERATE_WRITE_PR_REG_CASE(24, pr_write); >> + GENERATE_WRITE_PR_REG_CASE(25, pr_write); >> + GENERATE_WRITE_PR_REG_CASE(26, pr_write); >> + GENERATE_WRITE_PR_REG_CASE(27, pr_write); >> + GENERATE_WRITE_PR_REG_CASE(28, pr_write); >> + GENERATE_WRITE_PR_REG_CASE(29, pr_write); >> + GENERATE_WRITE_PR_REG_CASE(30, pr_write); >> + GENERATE_WRITE_PR_REG_CASE(31, pr_write); >> +#endif >> default: > also here have something for Arm32 to access the regions 32-255 > >> BUG(); /* Can't happen */ >> break; > > Please let me know your thoughts. Ack - Ayan > > Cheers, > Luca > > ^ permalink raw reply [flat|nested] 15+ messages in thread
end of thread, other threads:[~2025-06-09 11:27 UTC | newest] Thread overview: 15+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2025-06-06 16:48 [PATCH v2 0/3] Enable R52 support for the first chunk of MPU support Ayan Kumar Halder 2025-06-06 16:48 ` [PATCH v2 1/3] arm/mpu: Introduce MPU memory region map structure Ayan Kumar Halder 2025-06-09 7:31 ` Orzel, Michal 2025-06-06 16:48 ` [PATCH v2 2/3] arm/mpu: Provide and populate MPU C data structures Ayan Kumar Halder 2025-06-09 7:41 ` Orzel, Michal 2025-06-09 8:27 ` Ayan Kumar Halder 2025-06-09 8:42 ` Julien Grall 2025-06-09 9:16 ` Ayan Kumar Halder 2025-06-09 10:43 ` Ayan Kumar Halder 2025-06-09 11:26 ` Julien Grall 2025-06-06 16:48 ` [PATCH v2 3/3] arm/mpu: Provide access to the MPU region from the C code Ayan Kumar Halder 2025-06-09 7:44 ` Orzel, Michal 2025-06-09 8:37 ` Luca Fancellu 2025-06-09 9:16 ` Luca Fancellu 2025-06-09 9:26 ` Ayan Kumar Halder
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.