From: Ayan Kumar Halder <ayan.kumar.halder@amd.com>
To: <xen-devel@lists.xenproject.org>
Cc: Ayan Kumar Halder <ayan.kumar.halder@amd.com>,
Stefano Stabellini <sstabellini@kernel.org>,
Julien Grall <julien@xen.org>,
Bertrand Marquis <bertrand.marquis@arm.com>,
Michal Orzel <michal.orzel@amd.com>,
"Volodymyr Babchuk" <Volodymyr_Babchuk@epam.com>,
Luca Fancellu <luca.fancellu@arm.com>,
Hari Limaye <hari.limaye@arm.com>,
Julien Grall <jgrall@amazon.com>
Subject: [PATCH v5 3/3] arm/mpu: Enable read/write to protection regions for arm32
Date: Thu, 19 Jun 2025 12:31:52 +0100 [thread overview]
Message-ID: <20250619113152.2723066-4-ayan.kumar.halder@amd.com> (raw)
In-Reply-To: <20250619113152.2723066-1-ayan.kumar.halder@amd.com>
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
prev parent reply other threads:[~2025-06-19 11:32 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
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 [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20250619113152.2723066-4-ayan.kumar.halder@amd.com \
--to=ayan.kumar.halder@amd.com \
--cc=Volodymyr_Babchuk@epam.com \
--cc=bertrand.marquis@arm.com \
--cc=hari.limaye@arm.com \
--cc=jgrall@amazon.com \
--cc=julien@xen.org \
--cc=luca.fancellu@arm.com \
--cc=michal.orzel@amd.com \
--cc=sstabellini@kernel.org \
--cc=xen-devel@lists.xenproject.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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.