* [PATCH v5 0/3] Enable R52 support for the first chunk of MPU support
@ 2025-06-19 11:31 Ayan Kumar Halder
2025-06-19 11:31 ` [PATCH v5 1/3] arm/mpu: Move the functions to arm64 specific files Ayan Kumar Halder
` (2 more replies)
0 siblings, 3 replies; 4+ messages in thread
From: Ayan Kumar Halder @ 2025-06-19 11:31 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".
Changes from :-
v1 - Changes mentioned in individual patches
v2 - Split "arm/mpu: Provide access to the MPU region from the C code"
into 4 patches.
v3 - Patches 1,2 are merged. Patch 3 is dropped.
v4 - Add R-b, A-b, T-b tags to the individual patches.
Ayan Kumar Halder (3):
arm/mpu: Move the functions to arm64 specific files
arm/mpu: Define arm32 system registers
arm/mpu: Enable read/write to protection regions for arm32
xen/arch/arm/include/asm/mpu.h | 2 -
xen/arch/arm/include/asm/mpu/cpregs.h | 68 ++++++++++-
xen/arch/arm/mpu/Makefile | 2 +
xen/arch/arm/mpu/arm32/Makefile | 1 +
xen/arch/arm/mpu/arm32/mm.c | 164 ++++++++++++++++++++++++++
xen/arch/arm/mpu/arm64/Makefile | 1 +
xen/arch/arm/mpu/arm64/mm.c | 130 ++++++++++++++++++++
xen/arch/arm/mpu/mm.c | 119 -------------------
8 files changed, 365 insertions(+), 122 deletions(-)
create mode 100644 xen/arch/arm/mpu/arm32/Makefile
create mode 100644 xen/arch/arm/mpu/arm32/mm.c
create mode 100644 xen/arch/arm/mpu/arm64/Makefile
create mode 100644 xen/arch/arm/mpu/arm64/mm.c
--
2.25.1
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH v5 1/3] arm/mpu: Move the functions to arm64 specific files
2025-06-19 11:31 [PATCH v5 0/3] Enable R52 support for the first chunk of MPU support Ayan Kumar Halder
@ 2025-06-19 11:31 ` Ayan Kumar Halder
2025-06-19 11:31 ` [PATCH v5 2/3] arm/mpu: Define arm32 system registers Ayan Kumar Halder
2025-06-19 11:31 ` [PATCH v5 3/3] arm/mpu: Enable read/write to protection regions for arm32 Ayan Kumar Halder
2 siblings, 0 replies; 4+ messages in thread
From: Ayan Kumar Halder @ 2025-06-19 11:31 UTC (permalink / raw)
To: xen-devel
Cc: Ayan Kumar Halder, Stefano Stabellini, Julien Grall,
Bertrand Marquis, Michal Orzel, Volodymyr Babchuk, Luca Fancellu
prepare_selector(), read_protection_region() and write_protection_region()
differ significantly between arm32 and arm64. Thus, move these functions
to their sub-arch specific folder.
Also the macro GENERATE_{WRITE/READ}_PR_REG_CASE are moved, in order to
keep them in the same file of their usage and improve readability.
Signed-off-by: Ayan Kumar Halder <ayan.kumar.halder@amd.com>
Reviewed-by: Luca Fancellu <luca.fancellu@arm.com>
Acked-by: Michal Orzel <michal.orzel@amd.com>
---
Changes from -
v2 - New patch introduced in v3.
v3 - 1. Add Luca's R-b.
v4 - 1. Reorder entries in mpu/Makefile alphabetically.
2. Add Michal's A-b.
xen/arch/arm/mpu/Makefile | 1 +
xen/arch/arm/mpu/arm64/Makefile | 1 +
xen/arch/arm/mpu/arm64/mm.c | 130 ++++++++++++++++++++++++++++++++
xen/arch/arm/mpu/mm.c | 117 ----------------------------
4 files changed, 132 insertions(+), 117 deletions(-)
create mode 100644 xen/arch/arm/mpu/arm64/Makefile
create mode 100644 xen/arch/arm/mpu/arm64/mm.c
diff --git a/xen/arch/arm/mpu/Makefile b/xen/arch/arm/mpu/Makefile
index 808e3e2cb3..09326a5248 100644
--- a/xen/arch/arm/mpu/Makefile
+++ b/xen/arch/arm/mpu/Makefile
@@ -1,3 +1,4 @@
+obj-$(CONFIG_ARM_64) += arm64/
obj-$(CONFIG_ARM_32) += domain-page.o
obj-y += mm.o
obj-y += p2m.o
diff --git a/xen/arch/arm/mpu/arm64/Makefile b/xen/arch/arm/mpu/arm64/Makefile
new file mode 100644
index 0000000000..b18cec4836
--- /dev/null
+++ b/xen/arch/arm/mpu/arm64/Makefile
@@ -0,0 +1 @@
+obj-y += mm.o
diff --git a/xen/arch/arm/mpu/arm64/mm.c b/xen/arch/arm/mpu/arm64/mm.c
new file mode 100644
index 0000000000..ed643cad40
--- /dev/null
+++ b/xen/arch/arm/mpu/arm64/mm.c
@@ -0,0 +1,130 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <xen/bug.h>
+#include <xen/types.h>
+#include <asm/mpu.h>
+#include <asm/sysregs.h>
+#include <asm/system.h>
+
+/*
+ * The following are needed for the cases: GENERATE_WRITE_PR_REG_CASE
+ * and GENERATE_READ_PR_REG_CASE with num==0
+ */
+#define PRBAR0_EL2 PRBAR_EL2
+#define PRLAR0_EL2 PRLAR_EL2
+
+#define PRBAR_EL2_(n) PRBAR##n##_EL2
+#define PRLAR_EL2_(n) PRLAR##n##_EL2
+
+#define GENERATE_WRITE_PR_REG_CASE(num, pr) \
+ case num: \
+ { \
+ WRITE_SYSREG(pr->prbar.bits & ~MPU_REGION_RES0, PRBAR_EL2_(num)); \
+ WRITE_SYSREG(pr->prlar.bits & ~MPU_REGION_RES0, PRLAR_EL2_(num)); \
+ break; \
+ }
+
+#define GENERATE_READ_PR_REG_CASE(num, pr) \
+ case num: \
+ { \
+ pr->prbar.bits = READ_SYSREG(PRBAR_EL2_(num)); \
+ pr->prlar.bits = READ_SYSREG(PRLAR_EL2_(num)); \
+ break; \
+ }
+
+/*
+ * Armv8-R supports direct access and indirect access to the MPU regions through
+ * registers:
+ * - indirect access involves changing the MPU region selector, issuing an isb
+ * barrier and accessing the selected region through specific registers
+ * - direct access involves accessing specific registers that point to
+ * specific MPU regions, without changing the selector, avoiding the use of
+ * a barrier.
+ * For Arm64 the PR{B,L}AR_ELx (for n=0) and PR{B,L}AR<n>_ELx (for n=1..15) are
+ * used for the direct access to the regions selected by
+ * PRSELR_EL2.REGION<7:4>:n, so 16 regions can be directly accessed when the
+ * selector is a multiple of 16, giving access to all the supported memory
+ * regions.
+ */
+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.
+ */
+ cur_sel &= 0xF0U;
+ if ( READ_SYSREG(PRSELR_EL2) != cur_sel )
+ {
+ WRITE_SYSREG(cur_sel, PRSELR_EL2);
+ isb();
+ }
+ *sel &= 0xFU;
+}
+
+void read_protection_region(pr_t *pr_read, uint8_t sel)
+{
+ prepare_selector(&sel);
+
+ switch ( sel )
+ {
+ GENERATE_READ_PR_REG_CASE(0, pr_read);
+ GENERATE_READ_PR_REG_CASE(1, pr_read);
+ GENERATE_READ_PR_REG_CASE(2, pr_read);
+ GENERATE_READ_PR_REG_CASE(3, pr_read);
+ GENERATE_READ_PR_REG_CASE(4, pr_read);
+ GENERATE_READ_PR_REG_CASE(5, pr_read);
+ GENERATE_READ_PR_REG_CASE(6, pr_read);
+ GENERATE_READ_PR_REG_CASE(7, pr_read);
+ GENERATE_READ_PR_REG_CASE(8, pr_read);
+ GENERATE_READ_PR_REG_CASE(9, pr_read);
+ GENERATE_READ_PR_REG_CASE(10, pr_read);
+ GENERATE_READ_PR_REG_CASE(11, pr_read);
+ GENERATE_READ_PR_REG_CASE(12, pr_read);
+ GENERATE_READ_PR_REG_CASE(13, pr_read);
+ GENERATE_READ_PR_REG_CASE(14, pr_read);
+ GENERATE_READ_PR_REG_CASE(15, pr_read);
+ default:
+ BUG(); /* Can't happen */
+ break;
+ }
+}
+
+void write_protection_region(const pr_t *pr_write, uint8_t sel)
+{
+ prepare_selector(&sel);
+
+ switch ( sel )
+ {
+ GENERATE_WRITE_PR_REG_CASE(0, pr_write);
+ GENERATE_WRITE_PR_REG_CASE(1, pr_write);
+ GENERATE_WRITE_PR_REG_CASE(2, pr_write);
+ GENERATE_WRITE_PR_REG_CASE(3, pr_write);
+ GENERATE_WRITE_PR_REG_CASE(4, pr_write);
+ GENERATE_WRITE_PR_REG_CASE(5, pr_write);
+ GENERATE_WRITE_PR_REG_CASE(6, pr_write);
+ GENERATE_WRITE_PR_REG_CASE(7, pr_write);
+ GENERATE_WRITE_PR_REG_CASE(8, pr_write);
+ GENERATE_WRITE_PR_REG_CASE(9, pr_write);
+ GENERATE_WRITE_PR_REG_CASE(10, pr_write);
+ GENERATE_WRITE_PR_REG_CASE(11, pr_write);
+ GENERATE_WRITE_PR_REG_CASE(12, pr_write);
+ GENERATE_WRITE_PR_REG_CASE(13, pr_write);
+ GENERATE_WRITE_PR_REG_CASE(14, pr_write);
+ GENERATE_WRITE_PR_REG_CASE(15, pr_write);
+ default:
+ BUG(); /* Can't happen */
+ break;
+ }
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/xen/arch/arm/mpu/mm.c b/xen/arch/arm/mpu/mm.c
index 3d37beab57..7ab68fc8c7 100644
--- a/xen/arch/arm/mpu/mm.c
+++ b/xen/arch/arm/mpu/mm.c
@@ -29,35 +29,6 @@ DECLARE_BITMAP(xen_mpumap_mask, MAX_MPU_REGION_NR) \
/* EL2 Xen MPU memory region mapping table. */
pr_t __cacheline_aligned __section(".data") xen_mpumap[MAX_MPU_REGION_NR];
-#ifdef CONFIG_ARM_64
-/*
- * The following are needed for the cases: GENERATE_WRITE_PR_REG_CASE
- * and GENERATE_READ_PR_REG_CASE with num==0
- */
-#define PRBAR0_EL2 PRBAR_EL2
-#define PRLAR0_EL2 PRLAR_EL2
-
-#define PRBAR_EL2_(n) PRBAR##n##_EL2
-#define PRLAR_EL2_(n) PRLAR##n##_EL2
-
-#endif /* CONFIG_ARM_64 */
-
-#define GENERATE_WRITE_PR_REG_CASE(num, pr) \
- case num: \
- { \
- WRITE_SYSREG(pr->prbar.bits & ~MPU_REGION_RES0, PRBAR_EL2_(num)); \
- WRITE_SYSREG(pr->prlar.bits & ~MPU_REGION_RES0, PRLAR_EL2_(num)); \
- break; \
- }
-
-#define GENERATE_READ_PR_REG_CASE(num, pr) \
- case num: \
- { \
- pr->prbar.bits = READ_SYSREG(PRBAR_EL2_(num)); \
- pr->prlar.bits = READ_SYSREG(PRLAR_EL2_(num)); \
- break; \
- }
-
static void __init __maybe_unused build_assertions(void)
{
/*
@@ -69,94 +40,6 @@ static void __init __maybe_unused build_assertions(void)
}
#ifdef CONFIG_ARM_64
-/*
- * Armv8-R supports direct access and indirect access to the MPU regions through
- * registers:
- * - indirect access involves changing the MPU region selector, issuing an isb
- * barrier and accessing the selected region through specific registers
- * - direct access involves accessing specific registers that point to
- * specific MPU regions, without changing the selector, avoiding the use of
- * a barrier.
- * For Arm64 the PR{B,L}AR_ELx (for n=0) and PR{B,L}AR<n>_ELx (for n=1..15) are
- * used for the direct access to the regions selected by
- * PRSELR_EL2.REGION<7:4>:n, so 16 regions can be directly accessed when the
- * selector is a multiple of 16, giving access to all the supported memory
- * regions.
- */
-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.
- */
- cur_sel &= 0xF0U;
- if ( READ_SYSREG(PRSELR_EL2) != cur_sel )
- {
- WRITE_SYSREG(cur_sel, PRSELR_EL2);
- isb();
- }
- *sel &= 0xFU;
-}
-
-void read_protection_region(pr_t *pr_read, uint8_t sel)
-{
- prepare_selector(&sel);
-
- switch ( sel )
- {
- GENERATE_READ_PR_REG_CASE(0, pr_read);
- GENERATE_READ_PR_REG_CASE(1, pr_read);
- GENERATE_READ_PR_REG_CASE(2, pr_read);
- GENERATE_READ_PR_REG_CASE(3, pr_read);
- GENERATE_READ_PR_REG_CASE(4, pr_read);
- GENERATE_READ_PR_REG_CASE(5, pr_read);
- GENERATE_READ_PR_REG_CASE(6, pr_read);
- GENERATE_READ_PR_REG_CASE(7, pr_read);
- GENERATE_READ_PR_REG_CASE(8, pr_read);
- GENERATE_READ_PR_REG_CASE(9, pr_read);
- GENERATE_READ_PR_REG_CASE(10, pr_read);
- GENERATE_READ_PR_REG_CASE(11, pr_read);
- GENERATE_READ_PR_REG_CASE(12, pr_read);
- GENERATE_READ_PR_REG_CASE(13, pr_read);
- GENERATE_READ_PR_REG_CASE(14, pr_read);
- GENERATE_READ_PR_REG_CASE(15, pr_read);
- default:
- BUG(); /* Can't happen */
- break;
- }
-}
-
-void write_protection_region(const pr_t *pr_write, uint8_t sel)
-{
- prepare_selector(&sel);
-
- switch ( sel )
- {
- GENERATE_WRITE_PR_REG_CASE(0, pr_write);
- GENERATE_WRITE_PR_REG_CASE(1, pr_write);
- GENERATE_WRITE_PR_REG_CASE(2, pr_write);
- GENERATE_WRITE_PR_REG_CASE(3, pr_write);
- GENERATE_WRITE_PR_REG_CASE(4, pr_write);
- GENERATE_WRITE_PR_REG_CASE(5, pr_write);
- GENERATE_WRITE_PR_REG_CASE(6, pr_write);
- GENERATE_WRITE_PR_REG_CASE(7, pr_write);
- GENERATE_WRITE_PR_REG_CASE(8, pr_write);
- GENERATE_WRITE_PR_REG_CASE(9, pr_write);
- GENERATE_WRITE_PR_REG_CASE(10, pr_write);
- GENERATE_WRITE_PR_REG_CASE(11, pr_write);
- GENERATE_WRITE_PR_REG_CASE(12, pr_write);
- GENERATE_WRITE_PR_REG_CASE(13, pr_write);
- GENERATE_WRITE_PR_REG_CASE(14, pr_write);
- GENERATE_WRITE_PR_REG_CASE(15, pr_write);
- default:
- BUG(); /* Can't happen */
- break;
- }
-}
-
pr_t pr_of_addr(paddr_t base, paddr_t limit, unsigned int flags)
{
unsigned int attr_idx = PAGE_AI_MASK(flags);
--
2.25.1
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH v5 2/3] arm/mpu: Define arm32 system registers
2025-06-19 11:31 [PATCH v5 0/3] Enable R52 support for the first chunk of MPU support Ayan Kumar Halder
2025-06-19 11:31 ` [PATCH v5 1/3] arm/mpu: Move the functions to arm64 specific files Ayan Kumar Halder
@ 2025-06-19 11:31 ` Ayan Kumar Halder
2025-06-19 11:31 ` [PATCH v5 3/3] arm/mpu: Enable read/write to protection regions for arm32 Ayan Kumar Halder
2 siblings, 0 replies; 4+ messages in thread
From: Ayan Kumar Halder @ 2025-06-19 11:31 UTC (permalink / raw)
To: xen-devel
Cc: Ayan Kumar Halder, Stefano Stabellini, Julien Grall,
Bertrand Marquis, Michal Orzel, Volodymyr Babchuk, Hari Limaye
Fix the definition for HPRLAR.
Define the base/limit address registers to access the first 32 protection
regions.
Signed-off-by: Ayan Kumar Halder <ayan.kumar.halder@amd.com>
Reviewed-by: Hari Limaye <hari.limaye@arm.com>
Acked-by: Michal Orzel <michal.orzel@amd.com>
---
Changes from :-
v2 - New patch introduced in v3 (Extracted from
"arm/mpu: Provide access to the MPU region from the C code").
v3 - Add Hari's R-b.
v4 - Add Michal's A-b.
xen/arch/arm/include/asm/mpu/cpregs.h | 68 ++++++++++++++++++++++++++-
1 file changed, 67 insertions(+), 1 deletion(-)
diff --git a/xen/arch/arm/include/asm/mpu/cpregs.h b/xen/arch/arm/include/asm/mpu/cpregs.h
index d5cd0e04d5..bb15e02df6 100644
--- a/xen/arch/arm/include/asm/mpu/cpregs.h
+++ b/xen/arch/arm/include/asm/mpu/cpregs.h
@@ -9,7 +9,73 @@
/* 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
--
2.25.1
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH v5 3/3] arm/mpu: Enable read/write to protection regions for arm32
2025-06-19 11:31 [PATCH v5 0/3] Enable R52 support for the first chunk of MPU support Ayan Kumar Halder
2025-06-19 11:31 ` [PATCH v5 1/3] arm/mpu: Move the functions to arm64 specific files Ayan Kumar Halder
2025-06-19 11:31 ` [PATCH v5 2/3] arm/mpu: Define arm32 system registers Ayan Kumar Halder
@ 2025-06-19 11:31 ` Ayan Kumar Halder
2 siblings, 0 replies; 4+ messages in thread
From: Ayan Kumar Halder @ 2025-06-19 11:31 UTC (permalink / raw)
To: xen-devel
Cc: Ayan Kumar Halder, Stefano Stabellini, Julien Grall,
Bertrand Marquis, Michal Orzel, Volodymyr Babchuk, Luca Fancellu,
Hari Limaye, Julien Grall
Define prepare_selector(), read_protection_region() and
write_protection_region() for arm32. Also, define
GENERATE_{READ/WRITE}_PR_REG_OTHERS to access MPU regions from 32 to 254.
Enable pr_{get/set}_{base/limit}(), region_is_valid() for arm32.
Enable pr_of_addr() for arm32.
The maximum number of regions supported is 255 (which corresponds to the
maximum value in HMPUIR).
Signed-off-by: Ayan Kumar Halder <ayan.kumar.halder@amd.com>
Reviewed-by: Luca Fancellu <luca.fancellu@arm.com>
Reviewed-by: Hari Limaye <hari.limaye@arm.com>
Tested-by: Hari Limaye <hari.limaye@arm.com>
Acked-by: Julien Grall <jgrall@amazon.com>
---
Changes from :-
v1 - 1. Enable write_protection_region() for aarch32.
v2 - 1. Enable access to protection regions from 0 - 255.
v3 - 1. The maximum number of regions is 255. Thus, regions numbered 0 - 254
are supported.
2. prepare_selector() is modified to ensure HPRSELR is written when accessing
any region beyond 31 and the current value differs from the region number to
be accessed.
v4 - 1. Add R-b, A-b and T-b.
xen/arch/arm/include/asm/mpu.h | 2 -
xen/arch/arm/mpu/Makefile | 1 +
xen/arch/arm/mpu/arm32/Makefile | 1 +
xen/arch/arm/mpu/arm32/mm.c | 164 ++++++++++++++++++++++++++++++++
xen/arch/arm/mpu/mm.c | 2 -
5 files changed, 166 insertions(+), 4 deletions(-)
create mode 100644 xen/arch/arm/mpu/arm32/Makefile
create mode 100644 xen/arch/arm/mpu/arm32/mm.c
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/mpu/Makefile b/xen/arch/arm/mpu/Makefile
index 09326a5248..50f8fe4326 100644
--- a/xen/arch/arm/mpu/Makefile
+++ b/xen/arch/arm/mpu/Makefile
@@ -1,3 +1,4 @@
+obj-$(CONFIG_ARM_32) += arm32/
obj-$(CONFIG_ARM_64) += arm64/
obj-$(CONFIG_ARM_32) += domain-page.o
obj-y += mm.o
diff --git a/xen/arch/arm/mpu/arm32/Makefile b/xen/arch/arm/mpu/arm32/Makefile
new file mode 100644
index 0000000000..b18cec4836
--- /dev/null
+++ b/xen/arch/arm/mpu/arm32/Makefile
@@ -0,0 +1 @@
+obj-y += mm.o
diff --git a/xen/arch/arm/mpu/arm32/mm.c b/xen/arch/arm/mpu/arm32/mm.c
new file mode 100644
index 0000000000..a4673c3511
--- /dev/null
+++ b/xen/arch/arm/mpu/arm32/mm.c
@@ -0,0 +1,164 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <xen/bug.h>
+#include <xen/types.h>
+#include <asm/mpu.h>
+#include <asm/sysregs.h>
+#include <asm/system.h>
+
+#define GENERATE_WRITE_PR_REG_CASE(num, pr) \
+ case num: \
+ { \
+ WRITE_SYSREG(pr->prbar.bits, HPRBAR##num); \
+ WRITE_SYSREG(pr->prlar.bits, HPRLAR##num); \
+ break; \
+ }
+
+#define GENERATE_WRITE_PR_REG_OTHERS(num, pr) \
+ case num: \
+ { \
+ WRITE_SYSREG(pr->prbar.bits, HPRBAR); \
+ WRITE_SYSREG(pr->prlar.bits, HPRLAR); \
+ break; \
+ }
+
+#define GENERATE_READ_PR_REG_CASE(num, pr) \
+ case num: \
+ { \
+ pr->prbar.bits = READ_SYSREG(HPRBAR##num); \
+ pr->prlar.bits = READ_SYSREG(HPRLAR##num); \
+ break; \
+ }
+
+#define GENERATE_READ_PR_REG_OTHERS(num, pr) \
+ case num: \
+ { \
+ pr->prbar.bits = READ_SYSREG(HPRBAR); \
+ pr->prlar.bits = READ_SYSREG(HPRLAR); \
+ break; \
+ }
+
+/*
+ * Armv8-R supports direct access and indirect access to the MPU regions through
+ * registers:
+ * - indirect access involves changing the MPU region selector, issuing an isb
+ * barrier and accessing the selected region through specific registers
+ * - direct access involves accessing specific registers that point to
+ * specific MPU regions, without changing the selector, avoiding the use of
+ * a barrier.
+ * For Arm32 the HPR{B,L}AR<n> (for n=0..31) are used for direct access to the
+ * first 32 MPU regions.
+ * For MPU regions numbered 32..254, one needs to set the region number in
+ * HPRSELR, followed by configuring HPR{B,L}AR.
+ */
+static void prepare_selector(uint8_t *sel)
+{
+ uint8_t cur_sel = *sel;
+ /* The top 24 bits of HPRSELR are RES0. */
+ uint8_t val = READ_SYSREG(HPRSELR) & 0xff;
+
+ if ( (cur_sel > 31) && (cur_sel != val) )
+ {
+ WRITE_SYSREG(cur_sel, HPRSELR);
+ isb();
+ }
+}
+
+void read_protection_region(pr_t *pr_read, uint8_t sel)
+{
+ prepare_selector(&sel);
+
+ switch ( sel )
+ {
+ GENERATE_READ_PR_REG_CASE(0, pr_read);
+ GENERATE_READ_PR_REG_CASE(1, pr_read);
+ GENERATE_READ_PR_REG_CASE(2, pr_read);
+ GENERATE_READ_PR_REG_CASE(3, pr_read);
+ GENERATE_READ_PR_REG_CASE(4, pr_read);
+ GENERATE_READ_PR_REG_CASE(5, pr_read);
+ GENERATE_READ_PR_REG_CASE(6, pr_read);
+ GENERATE_READ_PR_REG_CASE(7, pr_read);
+ GENERATE_READ_PR_REG_CASE(8, pr_read);
+ GENERATE_READ_PR_REG_CASE(9, pr_read);
+ GENERATE_READ_PR_REG_CASE(10, pr_read);
+ GENERATE_READ_PR_REG_CASE(11, pr_read);
+ GENERATE_READ_PR_REG_CASE(12, pr_read);
+ GENERATE_READ_PR_REG_CASE(13, pr_read);
+ GENERATE_READ_PR_REG_CASE(14, pr_read);
+ GENERATE_READ_PR_REG_CASE(15, pr_read);
+ 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);
+ GENERATE_READ_PR_REG_OTHERS(32 ... 254, pr_read);
+ default:
+ BUG(); /* Can't happen */
+ break;
+ }
+}
+
+void write_protection_region(const pr_t *pr_write, uint8_t sel)
+{
+ prepare_selector(&sel);
+
+ switch ( sel )
+ {
+ GENERATE_WRITE_PR_REG_CASE(0, pr_write);
+ GENERATE_WRITE_PR_REG_CASE(1, pr_write);
+ GENERATE_WRITE_PR_REG_CASE(2, pr_write);
+ GENERATE_WRITE_PR_REG_CASE(3, pr_write);
+ GENERATE_WRITE_PR_REG_CASE(4, pr_write);
+ GENERATE_WRITE_PR_REG_CASE(5, pr_write);
+ GENERATE_WRITE_PR_REG_CASE(6, pr_write);
+ GENERATE_WRITE_PR_REG_CASE(7, pr_write);
+ GENERATE_WRITE_PR_REG_CASE(8, pr_write);
+ GENERATE_WRITE_PR_REG_CASE(9, pr_write);
+ GENERATE_WRITE_PR_REG_CASE(10, pr_write);
+ GENERATE_WRITE_PR_REG_CASE(11, pr_write);
+ GENERATE_WRITE_PR_REG_CASE(12, pr_write);
+ GENERATE_WRITE_PR_REG_CASE(13, pr_write);
+ GENERATE_WRITE_PR_REG_CASE(14, pr_write);
+ GENERATE_WRITE_PR_REG_CASE(15, pr_write);
+ 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);
+ GENERATE_WRITE_PR_REG_OTHERS(32 ... 254, pr_write);
+ default:
+ BUG(); /* Can't happen */
+ break;
+ }
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/xen/arch/arm/mpu/mm.c b/xen/arch/arm/mpu/mm.c
index 7ab68fc8c7..ccfb37a67b 100644
--- a/xen/arch/arm/mpu/mm.c
+++ b/xen/arch/arm/mpu/mm.c
@@ -39,7 +39,6 @@ static void __init __maybe_unused build_assertions(void)
BUILD_BUG_ON(PAGE_SIZE != SZ_4K);
}
-#ifdef CONFIG_ARM_64
pr_t pr_of_addr(paddr_t base, paddr_t limit, unsigned int flags)
{
unsigned int attr_idx = PAGE_AI_MASK(flags);
@@ -110,7 +109,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] 4+ messages in thread
end of thread, other threads:[~2025-06-19 11:32 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-06-19 11:31 [PATCH v5 0/3] Enable R52 support for the first chunk of MPU support Ayan Kumar Halder
2025-06-19 11:31 ` [PATCH v5 1/3] arm/mpu: Move the functions to arm64 specific files Ayan Kumar Halder
2025-06-19 11:31 ` [PATCH v5 2/3] arm/mpu: Define arm32 system registers Ayan Kumar Halder
2025-06-19 11:31 ` [PATCH v5 3/3] arm/mpu: Enable read/write to protection regions for arm32 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.