From: Wei Chen <wei.chen@arm.com>
To: <xen-devel@lists.xenproject.org>
Cc: <nd@arm.com>, Penny Zheng <penny.zheng@arm.com>,
Stefano Stabellini <sstabellini@kernel.org>,
Julien Grall <julien@xen.org>,
Bertrand Marquis <bertrand.marquis@arm.com>,
Volodymyr Babchuk <Volodymyr_Babchuk@epam.com>,
Wei Chen <wei.chen@arm.com>
Subject: [PATCH v6 09/11] xen/arm64: create boot-time MPU protection regions
Date: Fri, 4 Nov 2022 18:07:39 +0800 [thread overview]
Message-ID: <20221104100741.2176307-10-wei.chen@arm.com> (raw)
In-Reply-To: <20221104100741.2176307-1-wei.chen@arm.com>
From: Penny Zheng <penny.zheng@arm.com>
Like boot-time page table in MMU system, we need a boot-time
MPU protection region configuration in MPU system so Xen can
fetch code and data from normal memory.
This operation need to access Armv8-R MPU system registers, but
these system registers are not supported in GCC version < 11.
So we have to encode these Armv8-R MPU system registers in header
file explicitly.
As MMU system and MPU system have different functions to create
the boot MMU/MPU data, this will introduce extra #ifdef in code
flow, so we introduce a neutral name prepare_early_mappings to
replace create_page_tables for MMU and MPU.
Signed-off-by: Wei Chen <wei.chen@arm.com>
Signed-off-by: Penny Zheng <penny.zheng@arm.com>
---
xen/arch/arm/arm64/Makefile | 2 +
xen/arch/arm/arm64/head.S | 13 ++--
xen/arch/arm/arm64/head_mmu.S | 4 +-
xen/arch/arm/arm64/head_mpu.S | 70 +++++++++++++++++++
xen/arch/arm/include/asm/arm64/mpu.h | 13 ++++
xen/arch/arm/include/asm/arm64/sysregs.h | 89 ++++++++++++++++++++++++
6 files changed, 185 insertions(+), 6 deletions(-)
create mode 100644 xen/arch/arm/arm64/head_mpu.S
create mode 100644 xen/arch/arm/include/asm/arm64/mpu.h
diff --git a/xen/arch/arm/arm64/Makefile b/xen/arch/arm/arm64/Makefile
index 22da2f54b5..438c9737ad 100644
--- a/xen/arch/arm/arm64/Makefile
+++ b/xen/arch/arm/arm64/Makefile
@@ -10,6 +10,8 @@ obj-y += entry.o
obj-y += head.o
ifneq ($(CONFIG_HAS_MPU),y)
obj-y += head_mmu.o
+else
+obj-y += head_mpu.o
endif
obj-y += insn.o
obj-$(CONFIG_LIVEPATCH) += livepatch.o
diff --git a/xen/arch/arm/arm64/head.S b/xen/arch/arm/arm64/head.S
index d9a8da9120..6c1a5f74a1 100644
--- a/xen/arch/arm/arm64/head.S
+++ b/xen/arch/arm/arm64/head.S
@@ -79,12 +79,12 @@
* ---------------------------
*
* The requirements are:
- * MMU = off, D-cache = off, I-cache = on or off,
+ * MMU/MPU = off, D-cache = off, I-cache = on or off,
* x0 = physical address to the FDT blob.
*
* This must be the very first address in the loaded image.
* It should be linked at XEN_VIRT_START, and loaded at any
- * 4K-aligned address. All of text+data+bss must fit in 2MB,
+ * 4K-aligned address. All of text+data+bss must fit in 2MB,
* or the initial pagetable code below will need adjustment.
*/
@@ -249,7 +249,12 @@ real_start_efi:
bl check_cpu_mode
bl cpu_init
- bl create_page_tables
+
+ /*
+ * Create boot memory management data, pagetable for MMU systems
+ * and protection regions for MPU systems.
+ */
+ bl prepare_early_mappings
bl enable_mmu
/* We are still in the 1:1 mapping. Jump to the runtime Virtual Address. */
@@ -307,7 +312,7 @@ GLOBAL(init_secondary)
#endif
bl check_cpu_mode
bl cpu_init
- bl create_page_tables
+ bl prepare_early_mappings
bl enable_mmu
/* We are still in the 1:1 mapping. Jump to the runtime Virtual Address. */
diff --git a/xen/arch/arm/arm64/head_mmu.S b/xen/arch/arm/arm64/head_mmu.S
index 1a3df81a38..fc64819a98 100644
--- a/xen/arch/arm/arm64/head_mmu.S
+++ b/xen/arch/arm/arm64/head_mmu.S
@@ -123,7 +123,7 @@
*
* Clobbers x0 - x4
*/
-ENTRY(create_page_tables)
+ENTRY(prepare_early_mappings)
/* Prepare the page-tables for mapping Xen */
ldr x0, =XEN_VIRT_START
create_table_entry boot_pgtable, boot_first, x0, 0, x1, x2, x3
@@ -208,7 +208,7 @@ virtphys_clash:
/* Identity map clashes with boot_third, which we cannot handle yet */
PRINT("- Unable to build boot page tables - virt and phys addresses clash. -\r\n")
b fail
-ENDPROC(create_page_tables)
+ENDPROC(prepare_early_mappings)
/*
* Turn on the Data Cache and the MMU. The function will return on the 1:1
diff --git a/xen/arch/arm/arm64/head_mpu.S b/xen/arch/arm/arm64/head_mpu.S
new file mode 100644
index 0000000000..f60611b556
--- /dev/null
+++ b/xen/arch/arm/arm64/head_mpu.S
@@ -0,0 +1,70 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Start-of-day code for an Armv8-R MPU system.
+ */
+
+#include <asm/arm64/mpu.h>
+#include <asm/page.h>
+#include <asm/early_printk.h>
+
+/*
+ * From the requirements of head.S we know that Xen image should
+ * be linked at XEN_START_ADDRESS, and all of text + data + bss
+ * must fit in 2MB. On MPU systems, XEN_START_ADDRESS is also the
+ * address that Xen image should be loaded at. So for initial MPU
+ * regions setup, we use 2MB for Xen data memory to setup boot
+ * region, or the create boot regions code below will need adjustment.
+ */
+#define XEN_START_MEM_SIZE 0x200000
+
+/*
+ * In boot stage, we will use 1 MPU region:
+ * Region#0: Normal memory for Xen text + data + bss (2MB)
+ */
+#define BOOT_NORMAL_REGION_IDX 0x0
+
+/* MPU normal memory attributes. */
+#define PRBAR_NORMAL_MEM 0x30 /* SH=11 AP=00 XN=00 */
+#define PRLAR_NORMAL_MEM 0x0f /* NS=0 ATTR=111 EN=1 */
+
+.macro write_pr, sel, prbar, prlar
+ msr PRSELR_EL2, \sel
+ dsb sy
+ msr PRBAR_EL2, \prbar
+ msr PRLAR_EL2, \prlar
+ dsb sy
+ isb
+.endm
+
+.section .text.header, "ax", %progbits
+
+/*
+ * Static start-of-day EL2 MPU memory layout.
+ *
+ * It has a very simple structure, including:
+ * - 2MB normal memory mappings of xen at XEN_START_ADDRESS, which
+ * is the address where Xen was loaded by the bootloader.
+ */
+ENTRY(prepare_early_mappings)
+ /* Map Xen start memory to a normal memory region. */
+ mov x0, #BOOT_NORMAL_REGION_IDX
+ ldr x1, =XEN_START_ADDRESS
+ and x1, x1, #MPU_REGION_MASK
+ mov x3, #PRBAR_NORMAL_MEM
+ orr x1, x1, x3
+
+ ldr x2, =XEN_START_ADDRESS
+ mov x3, #(XEN_START_MEM_SIZE - 1)
+ add x2, x2, x3
+ and x2, x2, #MPU_REGION_MASK
+ mov x3, #PRLAR_NORMAL_MEM
+ orr x2, x2, x3
+
+ /*
+ * Write to MPU protection region:
+ * x0 for pr_sel, x1 for prbar x2 for prlar
+ */
+ write_pr x0, x1, x2
+
+ ret
+ENDPROC(prepare_early_mappings)
diff --git a/xen/arch/arm/include/asm/arm64/mpu.h b/xen/arch/arm/include/asm/arm64/mpu.h
new file mode 100644
index 0000000000..d209eef6db
--- /dev/null
+++ b/xen/arch/arm/include/asm/arm64/mpu.h
@@ -0,0 +1,13 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * mpu.h: Arm Memory Protection Unit definitions.
+ */
+
+#ifndef __ARM64_MPU_H__
+#define __ARM64_MPU_H__
+
+#define MPU_REGION_SHIFT 6
+#define MPU_REGION_ALIGN (_AC(1, UL) << MPU_REGION_SHIFT)
+#define MPU_REGION_MASK (~(MPU_REGION_ALIGN - 1))
+
+#endif /* __ARM64_MPU_H__ */
diff --git a/xen/arch/arm/include/asm/arm64/sysregs.h b/xen/arch/arm/include/asm/arm64/sysregs.h
index 54670084c3..a596042d6c 100644
--- a/xen/arch/arm/include/asm/arm64/sysregs.h
+++ b/xen/arch/arm/include/asm/arm64/sysregs.h
@@ -458,6 +458,95 @@
#define ZCR_ELx_LEN_SIZE 9
#define ZCR_ELx_LEN_MASK 0x1ff
+/* System registers for AArch64 with PMSA */
+#ifdef CONFIG_HAS_MPU
+
+/* EL1 MPU Protection Region Base Address Register encode */
+#define PRBAR_EL1 S3_0_C6_C8_0
+#define PRBAR1_EL1 S3_0_C6_C8_4
+#define PRBAR2_EL1 S3_0_C6_C9_0
+#define PRBAR3_EL1 S3_0_C6_C9_4
+#define PRBAR4_EL1 S3_0_C6_C10_0
+#define PRBAR5_EL1 S3_0_C6_C10_4
+#define PRBAR6_EL1 S3_0_C6_C11_0
+#define PRBAR7_EL1 S3_0_C6_C11_4
+#define PRBAR8_EL1 S3_0_C6_C12_0
+#define PRBAR9_EL1 S3_0_C6_C12_4
+#define PRBAR10_EL1 S3_0_C6_C13_0
+#define PRBAR11_EL1 S3_0_C6_C13_4
+#define PRBAR12_EL1 S3_0_C6_C14_0
+#define PRBAR13_EL1 S3_0_C6_C14_4
+#define PRBAR14_EL1 S3_0_C6_C15_0
+#define PRBAR15_EL1 S3_0_C6_C15_4
+
+/* EL1 MPU Protection Region Limit Address Register encode */
+#define PRLAR_EL1 S3_0_C6_C8_1
+#define PRLAR1_EL1 S3_0_C6_C8_5
+#define PRLAR2_EL1 S3_0_C6_C9_1
+#define PRLAR3_EL1 S3_0_C6_C9_5
+#define PRLAR4_EL1 S3_0_C6_C10_1
+#define PRLAR5_EL1 S3_0_C6_C10_5
+#define PRLAR6_EL1 S3_0_C6_C11_1
+#define PRLAR7_EL1 S3_0_C6_C11_5
+#define PRLAR8_EL1 S3_0_C6_C12_1
+#define PRLAR9_EL1 S3_0_C6_C12_5
+#define PRLAR10_EL1 S3_0_C6_C13_1
+#define PRLAR11_EL1 S3_0_C6_C13_5
+#define PRLAR12_EL1 S3_0_C6_C14_1
+#define PRLAR13_EL1 S3_0_C6_C14_5
+#define PRLAR14_EL1 S3_0_C6_C15_1
+#define PRLAR15_EL1 S3_0_C6_C15_5
+
+/* EL2 MPU Protection Region Base Address Register encode */
+#define PRBAR_EL2 S3_4_C6_C8_0
+#define PRBAR1_EL2 S3_4_C6_C8_4
+#define PRBAR2_EL2 S3_4_C6_C9_0
+#define PRBAR3_EL2 S3_4_C6_C9_4
+#define PRBAR4_EL2 S3_4_C6_C10_0
+#define PRBAR5_EL2 S3_4_C6_C10_4
+#define PRBAR6_EL2 S3_4_C6_C11_0
+#define PRBAR7_EL2 S3_4_C6_C11_4
+#define PRBAR8_EL2 S3_4_C6_C12_0
+#define PRBAR9_EL2 S3_4_C6_C12_4
+#define PRBAR10_EL2 S3_4_C6_C13_0
+#define PRBAR11_EL2 S3_4_C6_C13_4
+#define PRBAR12_EL2 S3_4_C6_C14_0
+#define PRBAR13_EL2 S3_4_C6_C14_4
+#define PRBAR14_EL2 S3_4_C6_C15_0
+#define PRBAR15_EL2 S3_4_C6_C15_4
+
+/* EL2 MPU Protection Region Limit Address Register encode */
+#define PRLAR_EL2 S3_4_C6_C8_1
+#define PRLAR1_EL2 S3_4_C6_C8_5
+#define PRLAR2_EL2 S3_4_C6_C9_1
+#define PRLAR3_EL2 S3_4_C6_C9_5
+#define PRLAR4_EL2 S3_4_C6_C10_1
+#define PRLAR5_EL2 S3_4_C6_C10_5
+#define PRLAR6_EL2 S3_4_C6_C11_1
+#define PRLAR7_EL2 S3_4_C6_C11_5
+#define PRLAR8_EL2 S3_4_C6_C12_1
+#define PRLAR9_EL2 S3_4_C6_C12_5
+#define PRLAR10_EL2 S3_4_C6_C13_1
+#define PRLAR11_EL2 S3_4_C6_C13_5
+#define PRLAR12_EL2 S3_4_C6_C14_1
+#define PRLAR13_EL2 S3_4_C6_C14_5
+#define PRLAR14_EL2 S3_4_C6_C15_1
+#define PRLAR15_EL2 S3_4_C6_C15_5
+
+/* MPU Protection Region Enable Register encode */
+#define PRENR_EL1 S3_0_C6_C1_1
+#define PRENR_EL2 S3_4_C6_C1_1
+
+/* MPU Protection Region Selection Register encode */
+#define PRSELR_EL1 S3_0_C6_C2_1
+#define PRSELR_EL2 S3_4_C6_C2_1
+
+/* MPU Type registers encode */
+#define MPUIR_EL1 S3_0_C0_C0_4
+#define MPUIR_EL2 S3_4_C0_C0_4
+
+#endif
+
/* Access to system registers */
#define WRITE_SYSREG64(v, name) do { \
--
2.25.1
next prev parent reply other threads:[~2022-11-04 10:20 UTC|newest]
Thread overview: 63+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-11-04 10:07 [PATCH v6 00/11] xen/arm: Add Armv8-R64 MPU support to Xen - Part#1 Wei Chen
2022-11-04 10:07 ` [PATCH v6 01/11] xen/arm: remove xen_phys_start and xenheap_phys_end from config.h Wei Chen
2022-11-06 18:42 ` Julien Grall
2022-11-04 10:07 ` [PATCH v6 02/11] xen/arm: add iounmap after initrd has been loaded in domain_build Wei Chen
2022-11-06 18:55 ` Julien Grall
2022-11-07 1:33 ` Henry Wang
2022-11-07 9:09 ` Julien Grall
2022-11-07 9:11 ` Henry Wang
2022-11-07 19:00 ` Julien Grall
2022-11-08 2:14 ` Wei Chen
2022-11-08 2:24 ` Wei Chen
2022-11-04 10:07 ` [PATCH v6 03/11] xen/arm: disable EFI boot services for MPU systems Wei Chen
2022-11-06 19:12 ` Julien Grall
2022-11-06 19:13 ` Julien Grall
2022-11-08 3:02 ` Wei Chen
2022-11-15 8:21 ` Wei Chen
2022-11-04 10:07 ` [PATCH v6 04/11] xen/arm: adjust Xen TLB helpers for Armv8-R64 PMSA Wei Chen
2022-11-04 10:07 ` [PATCH v6 05/11] xen/arm: define Xen start address for FVP BaseR platform Wei Chen
2022-11-06 19:19 ` Julien Grall
2022-11-09 4:55 ` Wei Chen
2022-11-09 18:24 ` Julien Grall
2022-11-10 22:12 ` Stefano Stabellini
2022-11-11 10:13 ` Wei Chen
2022-11-11 20:15 ` Stefano Stabellini
2022-12-05 10:17 ` Wei Chen
2022-12-05 11:02 ` Julien Grall
2022-11-14 18:52 ` Ayan Kumar Halder
2022-11-15 5:42 ` Wei Chen
2022-11-04 10:07 ` [PATCH v6 06/11] xen/arm: split MMU and MPU config files from config.h Wei Chen
2022-11-04 10:07 ` [PATCH v6 07/11] xen/arm: implement FIXMAP_ADDR for MPU systems Wei Chen
2022-11-06 19:44 ` Julien Grall
2022-11-09 6:46 ` Wei Chen
2022-11-09 18:30 ` Julien Grall
2022-11-11 7:56 ` Wei Chen
2022-11-11 9:40 ` Julien Grall
2022-11-04 10:07 ` [PATCH v6 08/11] xen/arm64: move MMU related code from head.S to head_mmu.S Wei Chen
2022-11-06 20:06 ` Julien Grall
2022-11-07 9:34 ` Julien Grall
2022-11-09 7:36 ` Wei Chen
2022-11-09 18:33 ` Julien Grall
2022-11-13 21:42 ` Julien Grall
2022-11-14 5:36 ` Wei Chen
2022-11-04 10:07 ` Wei Chen [this message]
2022-11-06 20:46 ` [PATCH v6 09/11] xen/arm64: create boot-time MPU protection regions Julien Grall
2022-11-07 6:59 ` Penny Zheng
2022-11-07 9:29 ` Julien Grall
2022-11-07 10:17 ` Penny Zheng
2022-11-04 10:07 ` [PATCH v6 10/11] xen/arm64: introduce helpers for MPU enable/disable Wei Chen
2022-11-06 20:56 ` Julien Grall
2022-11-07 9:57 ` Penny Zheng
2022-11-07 10:38 ` Julien Grall
2022-11-08 3:01 ` Penny Zheng
2022-11-04 10:07 ` [PATCH v6 11/11] xen/arm64: add setup_fixmap and remove_identity_mapping for MPU Wei Chen
2022-11-06 21:02 ` Julien Grall
2022-11-07 8:13 ` Penny Zheng
2022-11-07 9:32 ` Julien Grall
2022-11-04 10:29 ` [PATCH v6 00/11] xen/arm: Add Armv8-R64 MPU support to Xen - Part#1 Wei Chen
2022-11-06 19:02 ` Julien Grall
2022-11-07 9:52 ` Wei Chen
2022-11-07 10:16 ` Julien Grall
2022-11-07 10:30 ` Wei Chen
2022-11-10 22:25 ` Stefano Stabellini
2022-11-11 10:41 ` Wei Chen
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=20221104100741.2176307-10-wei.chen@arm.com \
--to=wei.chen@arm.com \
--cc=Volodymyr_Babchuk@epam.com \
--cc=bertrand.marquis@arm.com \
--cc=julien@xen.org \
--cc=nd@arm.com \
--cc=penny.zheng@arm.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.