From nobody Fri Oct 31 16:19:14 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=fail(p=none dis=none) header.from=arm.com Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1745940096805373.21865199017293; Tue, 29 Apr 2025 08:21:36 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.972774.1361097 (Exim 4.92) (envelope-from ) id 1u9mln-0002XA-GR; Tue, 29 Apr 2025 15:21:15 +0000 Received: by outflank-mailman (output) from mailman id 972774.1361097; Tue, 29 Apr 2025 15:21:15 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1u9mln-0002Vt-Aj; Tue, 29 Apr 2025 15:21:15 +0000 Received: by outflank-mailman (input) for mailman id 972774; Tue, 29 Apr 2025 15:21:13 +0000 Received: from se1-gles-flk1-in.inumbo.com ([94.247.172.50] helo=se1-gles-flk1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1u9mll-0002Ky-RN for xen-devel@lists.xenproject.org; Tue, 29 Apr 2025 15:21:13 +0000 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by se1-gles-flk1.inumbo.com (Halon) with ESMTP id 92c143b9-250d-11f0-9ffb-bf95429c2676; Tue, 29 Apr 2025 17:21:08 +0200 (CEST) Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 5ABD81516; Tue, 29 Apr 2025 08:21:00 -0700 (PDT) Received: from e125770.cambridge.arm.com (e125770.arm.com [10.1.199.43]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 3E2133F673; Tue, 29 Apr 2025 08:21:06 -0700 (PDT) X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: 92c143b9-250d-11f0-9ffb-bf95429c2676 From: Luca Fancellu To: xen-devel@lists.xenproject.org Cc: Stefano Stabellini , Julien Grall , Bertrand Marquis , Michal Orzel , Volodymyr Babchuk Subject: [PATCH v4 1/7] docs/arm: Document Xen booting protocol on Armv8-R Date: Tue, 29 Apr 2025 16:20:51 +0100 Message-Id: <20250429152057.2380536-2-luca.fancellu@arm.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250429152057.2380536-1-luca.fancellu@arm.com> References: <20250429152057.2380536-1-luca.fancellu@arm.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ZM-MESSAGEID: 1745940096999019000 Content-Type: text/plain; charset="utf-8" Document the requirement needed to boot Xen on Armv8-R platforms. Signed-off-by: Luca Fancellu Reviewed-by: Ayan Kumar Halder Reviewed-by: Michal Orzel --- v4 changes: - New patch --- docs/misc/arm/booting.txt | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/docs/misc/arm/booting.txt b/docs/misc/arm/booting.txt index 21ae74837dcc..719af74f1e69 100644 --- a/docs/misc/arm/booting.txt +++ b/docs/misc/arm/booting.txt @@ -62,6 +62,14 @@ Xen relies on some settings the firmware has to configur= e in EL3 before starting =20 * The bit SCR_EL3.HCE (resp. SCR.HCE for 32-bit ARM) must be set to 1. =20 +When Xen runs on Armv8-R, the highest exception level is EL2 and the only +available state is secure (S) on Arm64 and non secure (NS) on Arm32, hence= the +above requirements need to be adjusted to this case: + +* Xen must be entered in S EL2 mode on Arm64 and in NS EL2 mode on Arm32. + +* Xen must be entered with MPU off and data cache disabled (SCTLR_EL2.M bi= t and + SCTLR_EL2.C set to 0). =20 [1] linux/Documentation/arm/booting.rst Latest version: http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux= .git/tree/Documentation/arch/arm/booting.rst --=20 2.34.1 From nobody Fri Oct 31 16:19:14 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=fail(p=none dis=none) header.from=arm.com Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1745940087560549.1637912082689; Tue, 29 Apr 2025 08:21:27 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.972775.1361103 (Exim 4.92) (envelope-from ) id 1u9mln-0002cT-Qm; Tue, 29 Apr 2025 15:21:15 +0000 Received: by outflank-mailman (output) from mailman id 972775.1361103; Tue, 29 Apr 2025 15:21:15 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1u9mln-0002b0-Mu; Tue, 29 Apr 2025 15:21:15 +0000 Received: by outflank-mailman (input) for mailman id 972775; Tue, 29 Apr 2025 15:21:14 +0000 Received: from se1-gles-flk1-in.inumbo.com ([94.247.172.50] helo=se1-gles-flk1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1u9mlm-0002Ky-H3 for xen-devel@lists.xenproject.org; Tue, 29 Apr 2025 15:21:14 +0000 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by se1-gles-flk1.inumbo.com (Halon) with ESMTP id 93b05b5b-250d-11f0-9ffb-bf95429c2676; Tue, 29 Apr 2025 17:21:09 +0200 (CEST) Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 08D1616F3; Tue, 29 Apr 2025 08:21:02 -0700 (PDT) Received: from e125770.cambridge.arm.com (e125770.arm.com [10.1.199.43]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 841FA3F673; Tue, 29 Apr 2025 08:21:07 -0700 (PDT) X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: 93b05b5b-250d-11f0-9ffb-bf95429c2676 From: Luca Fancellu To: xen-devel@lists.xenproject.org Cc: Penny Zheng , Stefano Stabellini , Julien Grall , Bertrand Marquis , Michal Orzel , Volodymyr Babchuk , Penny Zheng , Wei Chen Subject: [PATCH v4 2/7] arm/mpu: Introduce MPU memory region map structure Date: Tue, 29 Apr 2025 16:20:52 +0100 Message-Id: <20250429152057.2380536-3-luca.fancellu@arm.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250429152057.2380536-1-luca.fancellu@arm.com> References: <20250429152057.2380536-1-luca.fancellu@arm.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ZM-MESSAGEID: 1745940089394019100 Content-Type: text/plain; charset="utf-8" From: Penny Zheng Introduce pr_t typedef which is a structure having the prbar and prlar members, each being structured as the registers of the aarch64 armv8-r architecture. Signed-off-by: Penny Zheng Signed-off-by: Wei Chen Signed-off-by: Luca Fancellu Acked-by: Julien Grall Reviewed-by: Michal Orzel --- Changes in v4: - Fixed typos, changed name for reserved bitfields, add emacs bits to arm64/mpu.h. Now base and limit are 42 bits as we consider FEAT_LPA disabled, since we support max 1TB of memory. Moved data structure in commit that uses it --- xen/arch/arm/include/asm/arm64/mpu.h | 50 ++++++++++++++++++++++++++++ xen/arch/arm/include/asm/mpu.h | 4 +++ 2 files changed, 54 insertions(+) create mode 100644 xen/arch/arm/include/asm/arm64/mpu.h diff --git a/xen/arch/arm/include/asm/arm64/mpu.h b/xen/arch/arm/include/as= m/arm64/mpu.h new file mode 100644 index 000000000000..b27fccd77550 --- /dev/null +++ b/xen/arch/arm/include/asm/arm64/mpu.h @@ -0,0 +1,50 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef __ARM_ARM64_MPU_H__ +#define __ARM_ARM64_MPU_H__ + +#ifndef __ASSEMBLY__ + +/* Protection Region Base Address Register */ +typedef union { + struct __packed { + unsigned long xn:2; /* Execute-Never */ + unsigned long ap:2; /* Access Permission */ + unsigned long sh:2; /* Shareability */ + unsigned long base:42; /* Base Address */ + unsigned long res0:16; /* RES0 */ + } reg; + uint64_t bits; +} prbar_t; + +/* Protection Region Limit Address Register */ +typedef union { + struct __packed { + unsigned long en:1; /* Region enable */ + unsigned long ai:3; /* Memory Attribute Index */ + unsigned long ns:1; /* Not-Secure */ + unsigned long res0:1; /* RES0 */ + unsigned long limit:42; /* Limit Address */ + unsigned long res1:16; /* RES0 */ + } reg; + uint64_t bits; +} prlar_t; + +/* MPU Protection Region */ +typedef struct { + prbar_t prbar; + prlar_t prlar; +} pr_t; + +#endif /* __ASSEMBLY__ */ + +#endif /* __ARM_ARM64_MPU_H__ */ + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/xen/arch/arm/include/asm/mpu.h b/xen/arch/arm/include/asm/mpu.h index d4ec4248b62b..bb83f5a5f580 100644 --- a/xen/arch/arm/include/asm/mpu.h +++ b/xen/arch/arm/include/asm/mpu.h @@ -6,6 +6,10 @@ #ifndef __ARM_MPU_H__ #define __ARM_MPU_H__ =20 +#if defined(CONFIG_ARM_64) +# include +#endif + #define MPU_REGION_SHIFT 6 #define MPU_REGION_ALIGN (_AC(1, UL) << MPU_REGION_SHIFT) #define MPU_REGION_MASK (~(MPU_REGION_ALIGN - 1)) --=20 2.34.1 From nobody Fri Oct 31 16:19:14 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=fail(p=none dis=none) header.from=arm.com Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1745940099101353.3012163424421; Tue, 29 Apr 2025 08:21:39 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.972776.1361125 (Exim 4.92) (envelope-from ) id 1u9mlp-0003Bl-9c; Tue, 29 Apr 2025 15:21:17 +0000 Received: by outflank-mailman (output) from mailman id 972776.1361125; Tue, 29 Apr 2025 15:21:17 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1u9mlp-0003Ad-1P; Tue, 29 Apr 2025 15:21:17 +0000 Received: by outflank-mailman (input) for mailman id 972776; Tue, 29 Apr 2025 15:21:15 +0000 Received: from se1-gles-flk1-in.inumbo.com ([94.247.172.50] helo=se1-gles-flk1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1u9mln-0002Ky-HP for xen-devel@lists.xenproject.org; Tue, 29 Apr 2025 15:21:15 +0000 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by se1-gles-flk1.inumbo.com (Halon) with ESMTP id 948b960a-250d-11f0-9ffb-bf95429c2676; Tue, 29 Apr 2025 17:21:10 +0200 (CEST) Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 6DDE61BC0; Tue, 29 Apr 2025 08:21:03 -0700 (PDT) Received: from e125770.cambridge.arm.com (e125770.arm.com [10.1.199.43]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 324413F673; Tue, 29 Apr 2025 08:21:09 -0700 (PDT) X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: 948b960a-250d-11f0-9ffb-bf95429c2676 From: Luca Fancellu To: xen-devel@lists.xenproject.org Cc: Stefano Stabellini , Julien Grall , Bertrand Marquis , Michal Orzel , Volodymyr Babchuk Subject: [PATCH v4 3/7] arm/mpu: Provide and populate MPU C data structures Date: Tue, 29 Apr 2025 16:20:53 +0100 Message-Id: <20250429152057.2380536-4-luca.fancellu@arm.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250429152057.2380536-1-luca.fancellu@arm.com> References: <20250429152057.2380536-1-luca.fancellu@arm.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ZM-MESSAGEID: 1745940101254019000 Content-Type: text/plain; charset="utf-8" Provide some data structure in the C world to track the MPU status, these structures will be filled at boot by the assembly early code with the boot MPU regions and afterwards they will be used at runtime. Provide methods to update a bitmap created with DECLARE_BITMAP from the assembly code for both Arm32 and Arm64. Modify Arm64 assembly boot code to reset any unused MPU region, initialise 'max_xen_mpumap' with the number of supported MPU regions and modify the common asm macro 'prepare_xen_region' to load into xen_mpumap the MPU status and set/clear the bitmap 'xen_mpumap_mask' used to track the enabled regions. Changed parameters name from 'base', 'limit' to 'tmp1' and 'tmp2' in order to use them also for intermediate operations on the MPU and the bitmap C data structures, the help on top of the macro is enough to understand how the macro will work and this will save some registers. Provide a stub implementation for the pr_t type and few asm macro for the Arm32 to prevent compilation break, they will be implemented later. Signed-off-by: Luca Fancellu --- v4 changes: - new patch --- xen/arch/arm/arm64/mpu/head.S | 13 +++++ xen/arch/arm/include/asm/arm32/mpu.h | 25 +++++++++ xen/arch/arm/include/asm/bitmap-op.inc | 67 ++++++++++++++++++++++ xen/arch/arm/include/asm/mpu.h | 5 ++ xen/arch/arm/include/asm/mpu/mm.h | 7 +++ xen/arch/arm/include/asm/mpu/regions.inc | 71 ++++++++++++++++++++---- xen/arch/arm/mpu/mm.c | 16 ++++++ 7 files changed, 194 insertions(+), 10 deletions(-) create mode 100644 xen/arch/arm/include/asm/arm32/mpu.h create mode 100644 xen/arch/arm/include/asm/bitmap-op.inc diff --git a/xen/arch/arm/arm64/mpu/head.S b/xen/arch/arm/arm64/mpu/head.S index 6d336cafbbaf..c0cac06b015f 100644 --- a/xen/arch/arm/arm64/mpu/head.S +++ b/xen/arch/arm/arm64/mpu/head.S @@ -40,6 +40,9 @@ FUNC(enable_boot_cpu_mm) mrs x5, MPUIR_EL2 and x5, x5, #NUM_MPU_REGIONS_MASK =20 + ldr x0, =3Dmax_xen_mpumap + strb w5, [x0] + /* x0: region sel */ mov x0, xzr /* Xen text section. */ @@ -74,6 +77,16 @@ FUNC(enable_boot_cpu_mm) prepare_xen_region x0, x1, x2, x3, x4, x5, attr_prbar=3DREGION_DEVICE_= PRBAR, attr_prlar=3DREGION_DEVICE_PRLAR #endif =20 +zero_mpu: + /* Reset remaining MPU regions */ + cmp x0, x5 + beq out_zero_mpu + mov x1, #0 + mov x2, #1 + prepare_xen_region x0, x1, x2, x3, x4, x5, attr_prlar=3DREGION_DISABLE= D_PRLAR + b zero_mpu + +out_zero_mpu: b enable_mpu ret END(enable_boot_cpu_mm) diff --git a/xen/arch/arm/include/asm/arm32/mpu.h b/xen/arch/arm/include/as= m/arm32/mpu.h new file mode 100644 index 000000000000..1bdae4c309dc --- /dev/null +++ b/xen/arch/arm/include/asm/arm32/mpu.h @@ -0,0 +1,25 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef __ARM_ARM32_MPU_H__ +#define __ARM_ARM32_MPU_H__ + +#ifndef __ASSEMBLY__ + +/* MPU Protection Region */ +typedef struct { + uint32_t prbar; + uint32_t prlar; +} pr_t; + +#endif /* __ASSEMBLY__ */ + +#endif /* __ARM_ARM32_MPU_H__ */ + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/xen/arch/arm/include/asm/bitmap-op.inc b/xen/arch/arm/include/= asm/bitmap-op.inc new file mode 100644 index 000000000000..e316d9417bb9 --- /dev/null +++ b/xen/arch/arm/include/asm/bitmap-op.inc @@ -0,0 +1,67 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +/* + * Sets a bit in a bitmap declared by DECLARE_BITMAP, symbol name passed t= hrough + * bitmap_symbol. + * + * bitmap_set_bit: symbol of the bitmap declared by DECLARE_BITMAP + * bit: bit number to be set in the bitmap + * tmp1-tmp4: temporary registers used for the computation + * + * Preserves bit. + * Output: + * tmp1: Address of the word containing the changed bit. + * Clobbers: bit, tmp1, tmp2, tmp3, tmp4. + */ +.macro bitmap_set_bit bitmap_symbol, bit, tmp1, tmp2, tmp3, tmp4 + adr_l \tmp1, \bitmap_symbol + mov \tmp2, #(BYTES_PER_LONG - 1) + mvn \tmp2, \tmp2 + lsr \tmp3, \bit, #3 + and \tmp2, \tmp3, \tmp2 + add \tmp1, \tmp1, \tmp2 // bitmap_symbol + (bit/BI= TS_PER_LONG)*BYTES_PER_LONG + and \tmp2, \bit, #(BITS_PER_LONG - 1) // bit offset inside word + + ldr \tmp3, [\tmp1] + mov \tmp4, #1 + lsl \tmp4, \tmp4, \tmp2 // (1 << offset) + orr \tmp3, \tmp3, \tmp4 // set the bit + str \tmp3, [\tmp1] +.endm + +/* + * Clears a bit in a bitmap declared by DECLARE_BITMAP, symbol name passed + * through bitmap_symbol. + * + * bitmap_set_bit: symbol of the bitmap declared by DECLARE_BITMAP + * bit: bit number to be set in the bitmap + * tmp1-tmp4: temporary registers used for the computation + * + * Preserves bit. + * Output: + * tmp1: Address of the word containing the changed bit. + * Clobbers: bit, tmp1, tmp2, tmp3, tmp4. + */ +.macro bitmap_clear_bit bitmap_symbol, bit, tmp1, tmp2, tmp3, tmp4 + adr_l \tmp1, \bitmap_symbol + mov \tmp2, #(BYTES_PER_LONG - 1) + mvn \tmp2, \tmp2 + lsr \tmp3, \bit, #3 + and \tmp2, \tmp3, \tmp2 + add \tmp1, \tmp1, \tmp2 // bitmap_symbol + (bit/BI= TS_PER_LONG)*BYTES_PER_LONG + and \tmp2, \bit, #(BITS_PER_LONG - 1) // bit offset inside word + + ldr \tmp3, [\tmp1] + mov \tmp4, #1 + lsl \tmp4, \tmp4, \tmp2 // (1 << offset) + mvn \tmp4, \tmp4 // ~(1 << offset) + and \tmp3, \tmp3, \tmp4 // clear the bit + str \tmp3, [\tmp1] +.endm + +/* + * Local variables: + * mode: ASM + * indent-tabs-mode: nil + * End: + */ diff --git a/xen/arch/arm/include/asm/mpu.h b/xen/arch/arm/include/asm/mpu.h index bb83f5a5f580..1368b2eb990f 100644 --- a/xen/arch/arm/include/asm/mpu.h +++ b/xen/arch/arm/include/asm/mpu.h @@ -8,6 +8,10 @@ =20 #if defined(CONFIG_ARM_64) # include +#elif defined(CONFIG_ARM_32) +# include +#else +# error "unknown ARM variant" #endif =20 #define MPU_REGION_SHIFT 6 @@ -17,6 +21,7 @@ #define NUM_MPU_REGIONS_SHIFT 8 #define NUM_MPU_REGIONS (_AC(1, UL) << NUM_MPU_REGIONS_SHIFT) #define NUM_MPU_REGIONS_MASK (NUM_MPU_REGIONS - 1) +#define MAX_MPU_REGION_NR 255 =20 #endif /* __ARM_MPU_H__ */ =20 diff --git a/xen/arch/arm/include/asm/mpu/mm.h b/xen/arch/arm/include/asm/m= pu/mm.h index bfd840fa5d31..28339259c458 100644 --- a/xen/arch/arm/include/asm/mpu/mm.h +++ b/xen/arch/arm/include/asm/mpu/mm.h @@ -8,9 +8,16 @@ #include #include #include +#include =20 extern struct page_info *frame_table; =20 +extern uint8_t max_xen_mpumap; + +extern DECLARE_BITMAP(xen_mpumap_mask, MAX_MPU_REGION_NR); + +extern pr_t xen_mpumap[MAX_MPU_REGION_NR]; + #define virt_to_maddr(va) ((paddr_t)((vaddr_t)(va) & PADDR_MASK)) =20 #ifdef CONFIG_ARM_32 diff --git a/xen/arch/arm/include/asm/mpu/regions.inc b/xen/arch/arm/includ= e/asm/mpu/regions.inc index 47868a152662..dc0306f8c5fc 100644 --- a/xen/arch/arm/include/asm/mpu/regions.inc +++ b/xen/arch/arm/include/asm/mpu/regions.inc @@ -1,22 +1,50 @@ /* SPDX-License-Identifier: GPL-2.0-only */ =20 +#include #include #include =20 /* Backgroud region enable/disable */ #define SCTLR_ELx_BR BIT(17, UL) =20 +#define REGION_DISABLED_PRLAR 0x00 /* NS=3D0 ATTR=3D000 EN=3D0 */ #define REGION_NORMAL_PRLAR 0x0f /* NS=3D0 ATTR=3D111 EN=3D1 */ #define REGION_DEVICE_PRLAR 0x09 /* NS=3D0 ATTR=3D100 EN=3D1 */ =20 +#define PRLAR_ELx_EN 0x1 + +#ifdef CONFIG_ARM_64 +#define XEN_MPUMAP_ENTRY_SHIFT 0x4 /* 16 byte structure */ + +.macro store_pair reg1, reg2, dst + stp \reg1, \reg2, [\dst] +.endm + +.macro invalidate_dcache_one reg + dc ivac, \reg +.endm + +#else +#define XEN_MPUMAP_ENTRY_SHIFT 0x2 /* 8 byte structure */ + +.macro store_pair reg1, reg2, dst + nop +.endm + +.macro invalidate_dcache_one reg + nop +.endm + +#endif + /* * Macro to prepare and set a EL2 MPU memory region. * We will also create an according MPU memory region entry, which * is a structure of pr_t, in table \prmap. * * sel: region selector - * base: reg storing base address - * limit: reg storing limit address + * tmp1: reg storing base address + * tmp2: reg storing limit address * prbar: store computed PRBAR_EL2 value * prlar: store computed PRLAR_EL2 value * maxcount: maximum number of EL2 regions supported @@ -28,13 +56,13 @@ * Preserves maxcount * Output: * sel: Next available region selector index. - * Clobbers base, limit, prbar, prlar + * Clobbers tmp1, tmp2, prbar, prlar * * Note that all parameters using registers should be distinct. */ -.macro prepare_xen_region, sel, base, limit, prbar, prlar, maxcount, attr_= prbar=3DREGION_DATA_PRBAR, attr_prlar=3DREGION_NORMAL_PRLAR +.macro prepare_xen_region, sel, tmp1, tmp2, prbar, prlar, maxcount, attr_p= rbar=3DREGION_DATA_PRBAR, attr_prlar=3DREGION_NORMAL_PRLAR /* Check if the region is empty */ - cmp \base, \limit + cmp \tmp1, \tmp2 beq 1f =20 /* Check if the number of regions exceeded the count specified in MPUI= R_EL2 */ @@ -42,20 +70,43 @@ bge fail_insufficient_regions =20 /* Prepare value for PRBAR_EL2 reg and preserve it in \prbar.*/ - and \base, \base, #MPU_REGION_MASK + and \tmp1, \tmp1, #MPU_REGION_MASK mov \prbar, #\attr_prbar - orr \prbar, \prbar, \base + orr \prbar, \prbar, \tmp1 =20 /* Limit address should be inclusive */ - sub \limit, \limit, #1 - and \limit, \limit, #MPU_REGION_MASK + sub \tmp2, \tmp2, #1 + and \tmp2, \tmp2, #MPU_REGION_MASK mov \prlar, #\attr_prlar - orr \prlar, \prlar, \limit + orr \prlar, \prlar, \tmp2 =20 WRITE_SYSREG_ASM(\sel, PRSELR_EL2) isb WRITE_SYSREG_ASM(\prbar, PRBAR_EL2) WRITE_SYSREG_ASM(\prlar, PRLAR_EL2) + + /* Load pair into xen_mpumap and invalidate cache */ + mov \tmp1, \sel + lsl \tmp1, \tmp1, #XEN_MPUMAP_ENTRY_SHIFT + adr_l \tmp2, xen_mpumap + add \tmp2, \tmp2, \tmp1 + store_pair \prbar, \prlar, \tmp2 + invalidate_dcache_one \tmp2 + + /* Set/clear xen_mpumap_mask bitmap */ + tst \prlar, #PRLAR_ELx_EN + bne 2f + // Region is disabled, clear the bit in the bitmap + bitmap_clear_bit xen_mpumap_mask, \sel, \tmp1, \tmp2, \prbar, \prlar + b 3f + +2: + // Region is enabled, set the bit in the bitmap + bitmap_set_bit xen_mpumap_mask, \sel, \tmp1, \tmp2, \prbar, \prlar + +3: + invalidate_dcache_one \tmp1 + dsb sy isb =20 diff --git a/xen/arch/arm/mpu/mm.c b/xen/arch/arm/mpu/mm.c index 07c8959f4ee9..9eab09ff2044 100644 --- a/xen/arch/arm/mpu/mm.c +++ b/xen/arch/arm/mpu/mm.c @@ -7,9 +7,25 @@ #include #include #include +#include =20 struct page_info *frame_table; =20 +/* Maximum number of supported MPU memory regions by the EL2 MPU. */ +uint8_t __ro_after_init max_xen_mpumap; + +/* + * Bitmap xen_mpumap_mask is to record the usage of EL2 MPU memory regions. + * Bit 0 represents MPU memory region 0, bit 1 represents MPU memory + * region 1, ..., and so on. + * If a MPU memory region gets enabled, set the according bit to 1. + */ +DECLARE_BITMAP(xen_mpumap_mask, MAX_MPU_REGION_NR) \ + __section(".data.page_aligned"); + +/* EL2 Xen MPU memory region mapping table. */ +pr_t __section(".data.page_aligned") xen_mpumap[MAX_MPU_REGION_NR]; + static void __init __maybe_unused build_assertions(void) { /* --=20 2.34.1 From nobody Fri Oct 31 16:19:14 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=fail(p=none dis=none) header.from=arm.com Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1745940092998319.68545569956586; Tue, 29 Apr 2025 08:21:32 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.972772.1361085 (Exim 4.92) (envelope-from ) id 1u9mlm-0002LS-P1; Tue, 29 Apr 2025 15:21:14 +0000 Received: by outflank-mailman (output) from mailman id 972772.1361085; Tue, 29 Apr 2025 15:21:14 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1u9mlm-0002LK-M6; Tue, 29 Apr 2025 15:21:14 +0000 Received: by outflank-mailman (input) for mailman id 972772; Tue, 29 Apr 2025 15:21:13 +0000 Received: from se1-gles-sth1-in.inumbo.com ([159.253.27.254] helo=se1-gles-sth1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1u9mll-00026m-2r for xen-devel@lists.xenproject.org; Tue, 29 Apr 2025 15:21:13 +0000 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by se1-gles-sth1.inumbo.com (Halon) with ESMTP id 955d2742-250d-11f0-9eb4-5ba50f476ded; Tue, 29 Apr 2025 17:21:12 +0200 (CEST) Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id B283A1DB5; Tue, 29 Apr 2025 08:21:04 -0700 (PDT) Received: from e125770.cambridge.arm.com (e125770.arm.com [10.1.199.43]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 96A223F673; Tue, 29 Apr 2025 08:21:10 -0700 (PDT) X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: 955d2742-250d-11f0-9eb4-5ba50f476ded From: Luca Fancellu To: xen-devel@lists.xenproject.org Cc: Stefano Stabellini , Julien Grall , Bertrand Marquis , Michal Orzel , Volodymyr Babchuk Subject: [PATCH v4 4/7] arm/mpu: Provide access to the MPU region from the C code Date: Tue, 29 Apr 2025 16:20:54 +0100 Message-Id: <20250429152057.2380536-5-luca.fancellu@arm.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250429152057.2380536-1-luca.fancellu@arm.com> References: <20250429152057.2380536-1-luca.fancellu@arm.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ZM-MESSAGEID: 1745940095314019000 Content-Type: text/plain; charset="utf-8" Implement some utility function in order to access the MPU regions from the C world. Signed-off-by: Luca Fancellu --- v4 changes: - moved back PRBAR0_EL2/PRLAR0_EL2 to mm.c and protect them with CONFIG_ARM_64, changed comments, fixed typos and code style - Add PRBAR_EL2_(n) definition, to be overriden by Arm32 - protect prepare_selector, read_protection_region, write_protection_region by Arm64 to ensure compilation on both arm32 and arm64, Arm32 will modify that later while introducing the arm32 bits. v3 changes: - Moved PRBAR0_EL2/PRLAR0_EL2 to arm64 specific - Modified prepare_selector() to be easily made a NOP for Arm32, which can address up to 32 region without changing selector and it is also its maximum amount of MPU regions. --- --- xen/arch/arm/include/asm/mpu.h | 1 + xen/arch/arm/include/asm/mpu/mm.h | 34 +++++++++ xen/arch/arm/mpu/mm.c | 117 ++++++++++++++++++++++++++++++ 3 files changed, 152 insertions(+) diff --git a/xen/arch/arm/include/asm/mpu.h b/xen/arch/arm/include/asm/mpu.h index 1368b2eb990f..40a86140b6cc 100644 --- a/xen/arch/arm/include/asm/mpu.h +++ b/xen/arch/arm/include/asm/mpu.h @@ -17,6 +17,7 @@ #define MPU_REGION_SHIFT 6 #define MPU_REGION_ALIGN (_AC(1, UL) << MPU_REGION_SHIFT) #define MPU_REGION_MASK (~(MPU_REGION_ALIGN - 1)) +#define MPU_REGION_RES0 (0xFFFFULL << 48) =20 #define NUM_MPU_REGIONS_SHIFT 8 #define NUM_MPU_REGIONS (_AC(1, UL) << NUM_MPU_REGIONS_SHIFT) diff --git a/xen/arch/arm/include/asm/mpu/mm.h b/xen/arch/arm/include/asm/m= pu/mm.h index 28339259c458..e2235e568e81 100644 --- a/xen/arch/arm/include/asm/mpu/mm.h +++ b/xen/arch/arm/include/asm/mpu/mm.h @@ -41,6 +41,40 @@ static inline struct page_info *virt_to_page(const void = *v) return mfn_to_page(mfn); } =20 +/* Utility function to be used whenever MPU regions are modified */ +static inline void context_sync_mpu(void) +{ + /* + * ARM DDI 0600B.a, C1.7.1 + * Writes to MPU registers are only guaranteed to be visible following= a + * Context synchronization event and DSB operation. + */ + dsb(sy); + isb(); +} + +/* + * The following API requires context_sync_mpu() after being used to modif= y MPU + * regions: + * - write_protection_region + */ + +/* + * Reads the MPU region with index 'sel' from the HW. + * + * @pr_read: mpu protection region returned by read op. + * @sel: mpu protection region selector + */ +extern void read_protection_region(pr_t *pr_read, uint8_t sel); + +/* + * Writes the MPU region with index 'sel' to the HW. + * + * @pr_write: const mpu protection region passed through write op. + * @sel: mpu protection region selector + */ +extern void write_protection_region(const pr_t *pr_write, uint8_t sel); + #endif /* __ARM_MPU_MM_H__ */ =20 /* diff --git a/xen/arch/arm/mpu/mm.c b/xen/arch/arm/mpu/mm.c index 9eab09ff2044..40ccf99adc94 100644 --- a/xen/arch/arm/mpu/mm.c +++ b/xen/arch/arm/mpu/mm.c @@ -8,6 +8,8 @@ #include #include #include +#include +#include =20 struct page_info *frame_table; =20 @@ -26,6 +28,35 @@ DECLARE_BITMAP(xen_mpumap_mask, MAX_MPU_REGION_NR) \ /* EL2 Xen MPU memory region mapping table. */ pr_t __section(".data.page_aligned") xen_mpumap[MAX_MPU_REGION_NR]; =20 +#ifdef CONFIG_ARM_64 +/* + * The following are needed for the case generators GENERATE_WRITE_PR_REG_= CASE + * and GENERATE_READ_PR_REG_CASE with num=3D=3D0 + */ +#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 + +#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 =3D READ_SYSREG(PRBAR_EL2_(num)); \ + pr->prlar.bits =3D READ_SYSREG(PRLAR_EL2_(num)); \ + break; \ + } + static void __init __maybe_unused build_assertions(void) { /* @@ -36,6 +67,92 @@ static void __init __maybe_unused build_assertions(void) BUILD_BUG_ON(PAGE_SIZE !=3D SZ_4K); } =20 +#ifdef CONFIG_ARM_64 +/* + * Armv8-R supports direct access and indirect access to the MPU regions t= hrough + * registers, indirect access involves changing the MPU region selector, i= ssuing + * an isb barrier and accessing the selected region through specific regis= ters; + * instead direct access involves accessing specific registers that points= to + * a specific MPU region, without changing the selector (in some cases) and + * issuing barriers because of that. + * For Arm64 the PR{B,L}AR_ELx (for n=3D0) and PR{B,L}AR_ELx, n=3D1..15= , are used + * for the direct access to the regions selected by PRSELR_EL2.REGION<7:4>= :n, so + * 16 regions can be directly access when the selector is multiple of 16, = giving + * access to all the supported memory regions. + */ +static void prepare_selector(uint8_t *sel) +{ + uint8_t cur_sel =3D *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 cha= nge. + */ + cur_sel &=3D 0xF0U; + if ( READ_SYSREG(PRSELR_EL2) !=3D cur_sel ) + { + WRITE_SYSREG(cur_sel, PRSELR_EL2); + isb(); + } + *sel =3D *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 */ + } +} + +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 */ + } +} +#endif + void __init setup_mm(void) { BUG_ON("unimplemented"); --=20 2.34.1 From nobody Fri Oct 31 16:19:14 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=fail(p=none dis=none) header.from=arm.com Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1745940094035783.6034370420838; Tue, 29 Apr 2025 08:21:34 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.972773.1361090 (Exim 4.92) (envelope-from ) id 1u9mln-0002QT-4v; Tue, 29 Apr 2025 15:21:15 +0000 Received: by outflank-mailman (output) from mailman id 972773.1361090; Tue, 29 Apr 2025 15:21:15 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1u9mlm-0002Om-W2; Tue, 29 Apr 2025 15:21:14 +0000 Received: by outflank-mailman (input) for mailman id 972773; Tue, 29 Apr 2025 15:21:13 +0000 Received: from se1-gles-sth1-in.inumbo.com ([159.253.27.254] helo=se1-gles-sth1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1u9mll-00026m-PA for xen-devel@lists.xenproject.org; Tue, 29 Apr 2025 15:21:13 +0000 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by se1-gles-sth1.inumbo.com (Halon) with ESMTP id 960a2133-250d-11f0-9eb4-5ba50f476ded; Tue, 29 Apr 2025 17:21:13 +0200 (CEST) Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 0424B22FC; Tue, 29 Apr 2025 08:21:06 -0700 (PDT) Received: from e125770.cambridge.arm.com (e125770.arm.com [10.1.199.43]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id DB0EB3F673; Tue, 29 Apr 2025 08:21:11 -0700 (PDT) X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: 960a2133-250d-11f0-9eb4-5ba50f476ded From: Luca Fancellu To: xen-devel@lists.xenproject.org Cc: Stefano Stabellini , Julien Grall , Bertrand Marquis , Michal Orzel , Volodymyr Babchuk Subject: [PATCH v4 5/7] arm/mpu: Introduce utility functions for the pr_t type Date: Tue, 29 Apr 2025 16:20:55 +0100 Message-Id: <20250429152057.2380536-6-luca.fancellu@arm.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250429152057.2380536-1-luca.fancellu@arm.com> References: <20250429152057.2380536-1-luca.fancellu@arm.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ZM-MESSAGEID: 1745940095172019000 Content-Type: text/plain; charset="utf-8" Introduce few utility function to manipulate and handle the pr_t type. Signed-off-by: Luca Fancellu --- v4 changes: - Modify comment on top of the helpers. Clarify pr_set_limit takes exclusive address. Protected common code with #ifdef Arm64 until Arm32 is ready with pr_t --- xen/arch/arm/include/asm/mpu.h | 64 ++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/xen/arch/arm/include/asm/mpu.h b/xen/arch/arm/include/asm/mpu.h index 40a86140b6cc..0e0a7f05ade9 100644 --- a/xen/arch/arm/include/asm/mpu.h +++ b/xen/arch/arm/include/asm/mpu.h @@ -24,6 +24,70 @@ #define NUM_MPU_REGIONS_MASK (NUM_MPU_REGIONS - 1) #define MAX_MPU_REGION_NR 255 =20 +#ifndef __ASSEMBLY__ + +#ifdef CONFIG_ARM_64 +/* + * Set base address of MPU protection region. + * + * @pr: pointer to the protection region structure. + * @base: base address as base of the protection region. + */ +static inline void pr_set_base(pr_t *pr, paddr_t base) +{ + pr->prbar.reg.base =3D (base >> MPU_REGION_SHIFT); +} + +/* + * Set limit address of MPU protection region. + * + * @pr: pointer to the protection region structure. + * @limit: exclusive address as limit of the protection region. + */ +static inline void pr_set_limit(pr_t *pr, paddr_t limit) +{ + pr->prlar.reg.limit =3D ((limit - 1) >> MPU_REGION_SHIFT); +} + +/* + * Access to get base address of MPU protection region. + * The base address shall be zero extended. + * + * @pr: pointer to the protection region structure. + * @return: Base address configured for the passed protection region. + */ +static inline paddr_t pr_get_base(pr_t *pr) +{ + return (paddr_t)(pr->prbar.reg.base << MPU_REGION_SHIFT); +} + +/* + * Access to get limit address of MPU protection region. + * The limit address shall be concatenated with 0x3f. + * + * @pr: pointer to the protection region structure. + * @return: Inclusive limit address configured for the passed protection r= egion. + */ +static inline paddr_t pr_get_limit(pr_t *pr) +{ + return (paddr_t)((pr->prlar.reg.limit << MPU_REGION_SHIFT) + | ~MPU_REGION_MASK); +} + +/* + * Checks if the protection region is valid (enabled). + * + * @pr: pointer to the protection region structure. + * @return: True if the region is valid (enabled), false otherwise. + */ +static inline bool region_is_valid(pr_t *pr) +{ + return pr->prlar.reg.en; +} +#endif + +#endif /* __ASSEMBLY__ */ + #endif /* __ARM_MPU_H__ */ =20 /* --=20 2.34.1 From nobody Fri Oct 31 16:19:14 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=fail(p=none dis=none) header.from=arm.com Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 174594009084034.19159756322972; Tue, 29 Apr 2025 08:21:30 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.972777.1361130 (Exim 4.92) (envelope-from ) id 1u9mlp-0003Ib-N4; Tue, 29 Apr 2025 15:21:17 +0000 Received: by outflank-mailman (output) from mailman id 972777.1361130; Tue, 29 Apr 2025 15:21:17 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1u9mlp-0003H3-Fy; Tue, 29 Apr 2025 15:21:17 +0000 Received: by outflank-mailman (input) for mailman id 972777; Tue, 29 Apr 2025 15:21:16 +0000 Received: from se1-gles-flk1-in.inumbo.com ([94.247.172.50] helo=se1-gles-flk1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1u9mlo-0002Ky-Js for xen-devel@lists.xenproject.org; Tue, 29 Apr 2025 15:21:16 +0000 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by se1-gles-flk1.inumbo.com (Halon) with ESMTP id 96dc413d-250d-11f0-9ffb-bf95429c2676; Tue, 29 Apr 2025 17:21:14 +0200 (CEST) Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 474882308; Tue, 29 Apr 2025 08:21:07 -0700 (PDT) Received: from e125770.cambridge.arm.com (e125770.arm.com [10.1.199.43]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 2BCBC3F673; Tue, 29 Apr 2025 08:21:13 -0700 (PDT) X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: 96dc413d-250d-11f0-9ffb-bf95429c2676 From: Luca Fancellu To: xen-devel@lists.xenproject.org Cc: Stefano Stabellini , Julien Grall , Bertrand Marquis , Michal Orzel , Volodymyr Babchuk Subject: [PATCH v4 6/7] arm/mpu: Provide a constructor for pr_t type Date: Tue, 29 Apr 2025 16:20:56 +0100 Message-Id: <20250429152057.2380536-7-luca.fancellu@arm.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250429152057.2380536-1-luca.fancellu@arm.com> References: <20250429152057.2380536-1-luca.fancellu@arm.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ZM-MESSAGEID: 1745940093099019000 Content-Type: text/plain; charset="utf-8" Provide a function that creates a pr_t object from a memory range and some attributes. Signed-off-by: Luca Fancellu --- v4 changes: - update helper comments - rename XN_EL2_ENABLED to PRBAR_EL2_XN_ENABLED - protected pr_of_xenaddr() with #ifdef Arm64 until Arm32 can build with it --- xen/arch/arm/include/asm/arm64/mpu.h | 11 +++++ xen/arch/arm/include/asm/mpu.h | 4 ++ xen/arch/arm/include/asm/mpu/mm.h | 10 ++++ xen/arch/arm/mpu/mm.c | 68 ++++++++++++++++++++++++++++ 4 files changed, 93 insertions(+) diff --git a/xen/arch/arm/include/asm/arm64/mpu.h b/xen/arch/arm/include/as= m/arm64/mpu.h index b27fccd77550..39233b43a5aa 100644 --- a/xen/arch/arm/include/asm/arm64/mpu.h +++ b/xen/arch/arm/include/asm/arm64/mpu.h @@ -3,6 +3,17 @@ #ifndef __ARM_ARM64_MPU_H__ #define __ARM_ARM64_MPU_H__ =20 +/* + * Excute never. + * Stage 1 EL2 translation regime. + * XN[1] determines whether execution of the instruction fetched from the = MPU + * memory region is permitted. + * Stage 2 EL1/EL0 translation regime. + * XN[0] determines whether execution of the instruction fetched from the = MPU + * memory region is permitted. + */ +#define PRBAR_EL2_XN_ENABLED 0x2 + #ifndef __ASSEMBLY__ =20 /* Protection Region Base Address Register */ diff --git a/xen/arch/arm/include/asm/mpu.h b/xen/arch/arm/include/asm/mpu.h index 0e0a7f05ade9..7b82f10d336b 100644 --- a/xen/arch/arm/include/asm/mpu.h +++ b/xen/arch/arm/include/asm/mpu.h @@ -24,6 +24,10 @@ #define NUM_MPU_REGIONS_MASK (NUM_MPU_REGIONS - 1) #define MAX_MPU_REGION_NR 255 =20 +/* Access permission attributes. */ +/* Read/Write at EL2, No Access at EL1/EL0. */ +#define AP_RW_EL2 0x0 + #ifndef __ASSEMBLY__ =20 #ifdef CONFIG_ARM_64 diff --git a/xen/arch/arm/include/asm/mpu/mm.h b/xen/arch/arm/include/asm/m= pu/mm.h index e2235e568e81..296fe74c5d61 100644 --- a/xen/arch/arm/include/asm/mpu/mm.h +++ b/xen/arch/arm/include/asm/mpu/mm.h @@ -75,6 +75,16 @@ extern void read_protection_region(pr_t *pr_read, uint8_= t sel); */ extern void write_protection_region(const pr_t *pr_write, uint8_t sel); =20 +/* + * Creates a pr_t structure describing a protection region. + * + * @base: base address as base of the protection region. + * @limit: exclusive address as limit of the protection region. + * @attr: attribute index for the memory type. + * @return: pr_t structure describing a protection region. + */ +extern pr_t pr_of_xenaddr(paddr_t base, paddr_t limit, unsigned int attr_i= dx); + #endif /* __ARM_MPU_MM_H__ */ =20 /* diff --git a/xen/arch/arm/mpu/mm.c b/xen/arch/arm/mpu/mm.c index 40ccf99adc94..2e0aeb486ff8 100644 --- a/xen/arch/arm/mpu/mm.c +++ b/xen/arch/arm/mpu/mm.c @@ -9,6 +9,7 @@ #include #include #include +#include #include =20 struct page_info *frame_table; @@ -151,6 +152,73 @@ void write_protection_region(const pr_t *pr_write, uin= t8_t sel) BUG(); /* Can't happen */ } } + +pr_t pr_of_xenaddr(paddr_t base, paddr_t limit, unsigned int attr_idx) +{ + prbar_t prbar; + prlar_t prlar; + pr_t region; + + /* Build up value for PRBAR_EL2. */ + prbar =3D (prbar_t) { + .reg =3D { + .ap =3D AP_RW_EL2, /* Read/Write at EL2, no access at EL1= /EL0. */ + .xn =3D PRBAR_EL2_XN_ENABLED, /* No need to execute outside = .text */ + }}; + + switch ( attr_idx ) + { + case MT_NORMAL_NC: + /* + * ARM ARM: Overlaying the shareability attribute (DDI + * 0406C.b B3-1376 to 1377) + * + * A memory region with a resultant memory type attribute of norma= l, + * and a resultant cacheability attribute of Inner non-cacheable, + * outer non-cacheable, must have a resultant shareability attribu= te + * of outer shareable, otherwise shareability is UNPREDICTABLE. + * + * On ARMv8 sharability is ignored and explicitly treated as outer + * shareable for normal inner non-cacheable, outer non-cacheable. + */ + prbar.reg.sh =3D LPAE_SH_OUTER; + break; + case MT_DEVICE_nGnRnE: + case MT_DEVICE_nGnRE: + /* + * Shareability is ignored for non-normal memory, Outer is as + * good as anything. + * + * On ARMv8 sharability is ignored and explicitly treated as outer + * shareable for any device memory type. + */ + prbar.reg.sh =3D LPAE_SH_OUTER; + break; + default: + /* Xen mappings are SMP coherent */ + prbar.reg.sh =3D LPAE_SH_INNER; + } + + /* Build up value for PRLAR_EL2. */ + prlar =3D (prlar_t) { + .reg =3D { + .ns =3D 0, /* Hyp mode is in secure world */ + .ai =3D attr_idx, + .en =3D 1, /* Region enabled */ + }}; + + /* Build up MPU memory region. */ + region =3D (pr_t) { + .prbar =3D prbar, + .prlar =3D prlar, + }; + + /* Set base address and limit address. */ + pr_set_base(®ion, base); + pr_set_limit(®ion, limit); + + return region; +} #endif =20 void __init setup_mm(void) --=20 2.34.1 From nobody Fri Oct 31 16:19:14 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=fail(p=none dis=none) header.from=arm.com Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1745940095663790.0823995580811; Tue, 29 Apr 2025 08:21:35 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.972778.1361135 (Exim 4.92) (envelope-from ) id 1u9mlq-0003Nb-1z; Tue, 29 Apr 2025 15:21:18 +0000 Received: by outflank-mailman (output) from mailman id 972778.1361135; Tue, 29 Apr 2025 15:21:17 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1u9mlp-0003Lk-Pk; Tue, 29 Apr 2025 15:21:17 +0000 Received: by outflank-mailman (input) for mailman id 972778; Tue, 29 Apr 2025 15:21:16 +0000 Received: from se1-gles-sth1-in.inumbo.com ([159.253.27.254] helo=se1-gles-sth1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1u9mlo-00026m-Ix for xen-devel@lists.xenproject.org; Tue, 29 Apr 2025 15:21:16 +0000 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by se1-gles-sth1.inumbo.com (Halon) with ESMTP id 97a4d1cb-250d-11f0-9eb4-5ba50f476ded; Tue, 29 Apr 2025 17:21:16 +0200 (CEST) Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 8B36A2309; Tue, 29 Apr 2025 08:21:08 -0700 (PDT) Received: from e125770.cambridge.arm.com (e125770.arm.com [10.1.199.43]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 700D43F673; Tue, 29 Apr 2025 08:21:14 -0700 (PDT) X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: 97a4d1cb-250d-11f0-9eb4-5ba50f476ded From: Luca Fancellu To: xen-devel@lists.xenproject.org Cc: Stefano Stabellini , Julien Grall , Bertrand Marquis , Michal Orzel , Volodymyr Babchuk Subject: [PATCH v4 7/7] arm/mpu: Introduce MPU memory mapping flags Date: Tue, 29 Apr 2025 16:20:57 +0100 Message-Id: <20250429152057.2380536-8-luca.fancellu@arm.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250429152057.2380536-1-luca.fancellu@arm.com> References: <20250429152057.2380536-1-luca.fancellu@arm.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ZM-MESSAGEID: 1745940096977019000 Content-Type: text/plain; charset="utf-8" Introduce the MPU memory mapping flags in asm/page.h. Signed-off-by: Luca Fancellu --- v4 changes: - no changes, I'm not sure how I can merge XN and Permission flags. --- xen/arch/arm/include/asm/page.h | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/xen/arch/arm/include/asm/page.h b/xen/arch/arm/include/asm/pag= e.h index 69f817d1e68a..22f7d2c6cb30 100644 --- a/xen/arch/arm/include/asm/page.h +++ b/xen/arch/arm/include/asm/page.h @@ -62,6 +62,7 @@ =20 #define MAIRVAL (MAIR1VAL << 32 | MAIR0VAL) =20 +#ifdef CONFIG_MMU /* * Layout of the flags used for updating the hypervisor page tables * @@ -90,6 +91,30 @@ #define _PAGE_CONTIG_BIT 8 #define _PAGE_CONTIG (1U << _PAGE_CONTIG_BIT) =20 +#else /* !CONFIG_MMU */ + +/* + * Layout of the flags used for updating MPU memory region attributes + * [0:2] Memory attribute Index + * [3:4] Execute Never + * [5:6] Access Permission + * [7] Region Present + */ +#define _PAGE_AI_BIT 0 +#define _PAGE_XN_BIT 3 +#define _PAGE_AP_BIT 5 +#define _PAGE_PRESENT_BIT 7 +#define _PAGE_AI (7U << _PAGE_AI_BIT) +#define _PAGE_XN (2U << _PAGE_XN_BIT) +#define _PAGE_RO (2U << _PAGE_AP_BIT) +#define _PAGE_PRESENT (1U << _PAGE_PRESENT_BIT) +#define PAGE_AI_MASK(x) (((x) >> _PAGE_AI_BIT) & 0x7U) +#define PAGE_XN_MASK(x) (((x) >> _PAGE_XN_BIT) & 0x3U) +#define PAGE_AP_MASK(x) (((x) >> _PAGE_AP_BIT) & 0x3U) +#define PAGE_RO_MASK(x) (((x) >> _PAGE_AP_BIT) & 0x2U) + +#endif /* CONFIG_MMU */ + /* * _PAGE_DEVICE and _PAGE_NORMAL are convenience defines. They are not * meant to be used outside of this header. --=20 2.34.1