From patchwork Mon Apr 7 09:14:24 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Luca Fancellu X-Patchwork-Id: 14040034 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 82606C3601A for ; Mon, 7 Apr 2025 09:14:54 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.939427.1339513 (Exim 4.92) (envelope-from ) id 1u1iZ1-00041a-PU; Mon, 07 Apr 2025 09:14:43 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 939427.1339513; Mon, 07 Apr 2025 09:14:43 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1u1iZ1-0003zu-K3; Mon, 07 Apr 2025 09:14:43 +0000 Received: by outflank-mailman (input) for mailman id 939427; Mon, 07 Apr 2025 09:14:42 +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 1u1iZ0-0003xy-5r for xen-devel@lists.xenproject.org; Mon, 07 Apr 2025 09:14:42 +0000 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by se1-gles-sth1.inumbo.com (Halon) with ESMTP id bc8a70e4-1390-11f0-9eaa-5ba50f476ded; Mon, 07 Apr 2025 11:14:41 +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 9EF1C1424; Mon, 7 Apr 2025 02:14:41 -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 0F64C3F59E; Mon, 7 Apr 2025 02:14:38 -0700 (PDT) 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: bc8a70e4-1390-11f0-9eaa-5ba50f476ded 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 v2 1/7] arm/mpu: Introduce MPU memory region map structure Date: Mon, 7 Apr 2025 10:14:24 +0100 Message-Id: <20250407091430.2342709-2-luca.fancellu@arm.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250407091430.2342709-1-luca.fancellu@arm.com> References: <20250407091430.2342709-1-luca.fancellu@arm.com> MIME-Version: 1.0 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. Introduce the array 'xen_mpumap' that will store a view of the content of the MPU regions. Introduce MAX_MPU_REGIONS macro that uses the value of NUM_MPU_REGIONS_MASK just for clarity, because using the latter as number of elements of the xen_mpumap array might be misleading. Signed-off-by: Penny Zheng Signed-off-by: Wei Chen Signed-off-by: Luca Fancellu --- xen/arch/arm/include/asm/arm64/mpu.h | 44 ++++++++++++++++++++++++++++ xen/arch/arm/include/asm/mpu.h | 5 ++++ xen/arch/arm/mpu/mm.c | 4 +++ 3 files changed, 53 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/asm/arm64/mpu.h new file mode 100644 index 000000000000..4d2bd7d7877f --- /dev/null +++ b/xen/arch/arm/include/asm/arm64/mpu.h @@ -0,0 +1,44 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * mpu.h: Arm Memory Protection Unit definitions for aarch64. + */ + +#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; /* Acess Permission */ + unsigned long sh:2; /* Sharebility */ + unsigned long base:46; /* Base Address */ + unsigned long pad:12; + } 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 res:1; /* Reserved 0 by hardware */ + unsigned long limit:46; /* Limit Address */ + unsigned long pad:12; + } 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__ */ \ No newline at end of file diff --git a/xen/arch/arm/include/asm/mpu.h b/xen/arch/arm/include/asm/mpu.h index d4ec4248b62b..e148c705b82c 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__ +#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)) @@ -13,6 +17,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_REGIONS NUM_MPU_REGIONS_MASK #endif /* __ARM_MPU_H__ */ diff --git a/xen/arch/arm/mpu/mm.c b/xen/arch/arm/mpu/mm.c index 07c8959f4ee9..f83ce04fef8a 100644 --- a/xen/arch/arm/mpu/mm.c +++ b/xen/arch/arm/mpu/mm.c @@ -7,9 +7,13 @@ #include #include #include +#include struct page_info *frame_table; +/* EL2 Xen MPU memory region mapping table. */ +pr_t xen_mpumap[MAX_MPU_REGIONS]; + static void __init __maybe_unused build_assertions(void) { /* From patchwork Mon Apr 7 09:14:25 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Luca Fancellu X-Patchwork-Id: 14040033 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id A9B45C3601E for ; Mon, 7 Apr 2025 09:14:53 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.939428.1339528 (Exim 4.92) (envelope-from ) id 1u1iZ2-0004Qb-V0; Mon, 07 Apr 2025 09:14:44 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 939428.1339528; Mon, 07 Apr 2025 09:14:44 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1u1iZ2-0004QU-Rp; Mon, 07 Apr 2025 09:14:44 +0000 Received: by outflank-mailman (input) for mailman id 939428; Mon, 07 Apr 2025 09:14:43 +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 1u1iZ1-0003xy-5c for xen-devel@lists.xenproject.org; Mon, 07 Apr 2025 09:14:43 +0000 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by se1-gles-sth1.inumbo.com (Halon) with ESMTP id bd4621aa-1390-11f0-9eaa-5ba50f476ded; Mon, 07 Apr 2025 11:14:42 +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 E217A1BF3; Mon, 7 Apr 2025 02:14:42 -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 AFE5C3F59E; Mon, 7 Apr 2025 02:14:40 -0700 (PDT) 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: bd4621aa-1390-11f0-9eaa-5ba50f476ded From: Luca Fancellu To: xen-devel@lists.xenproject.org Cc: Stefano Stabellini , Julien Grall , Bertrand Marquis , Michal Orzel , Volodymyr Babchuk Subject: [PATCH v2 2/7] arm/mpu: Provide access to the MPU region from the C code Date: Mon, 7 Apr 2025 10:14:25 +0100 Message-Id: <20250407091430.2342709-3-luca.fancellu@arm.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250407091430.2342709-1-luca.fancellu@arm.com> References: <20250407091430.2342709-1-luca.fancellu@arm.com> MIME-Version: 1.0 Implement some utility function in order to access the MPU regions from the C world. Signed-off-by: Luca Fancellu --- xen/arch/arm/include/asm/mpu.h | 1 + xen/arch/arm/include/asm/mpu/mm.h | 24 ++++++ xen/arch/arm/mpu/mm.c | 127 ++++++++++++++++++++++++++++++ 3 files changed, 152 insertions(+) diff --git a/xen/arch/arm/include/asm/mpu.h b/xen/arch/arm/include/asm/mpu.h index e148c705b82c..59ff22c804c1 100644 --- a/xen/arch/arm/include/asm/mpu.h +++ b/xen/arch/arm/include/asm/mpu.h @@ -13,6 +13,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 (0xFFFULL << 52) #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/mpu/mm.h index 86f33d9836b7..5cabe9d111ce 100644 --- a/xen/arch/arm/include/asm/mpu/mm.h +++ b/xen/arch/arm/include/asm/mpu/mm.h @@ -8,6 +8,7 @@ #include #include #include +#include extern struct page_info *frame_table; @@ -29,6 +30,29 @@ static inline struct page_info *virt_to_page(const void *v) return mfn_to_page(mfn); } +/* 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 require context_sync_mpu() after being used to modifiy MPU + * regions: + * - write_protection_region + */ + +/* Reads the MPU region with index 'sel' from the HW */ +extern void read_protection_region(pr_t *pr_read, uint8_t sel); +/* Writes the MPU region with index 'sel' to the HW */ +extern void write_protection_region(const pr_t *pr_write, uint8_t sel); + #endif /* __ARM_MPU_MM_H__ */ /* diff --git a/xen/arch/arm/mpu/mm.c b/xen/arch/arm/mpu/mm.c index f83ce04fef8a..bf281f67fb6b 100644 --- a/xen/arch/arm/mpu/mm.c +++ b/xen/arch/arm/mpu/mm.c @@ -8,12 +8,34 @@ #include #include #include +#include +#include struct page_info *frame_table; /* EL2 Xen MPU memory region mapping table. */ pr_t xen_mpumap[MAX_MPU_REGIONS]; +/* The following are needed for the case generator with num==0 */ +#define PRBAR0_EL2 PRBAR_EL2 +#define PRLAR0_EL2 PRLAR_EL2 + +#define GENERATE_WRITE_PR_REG_CASE(num, pr) \ + case num: \ + { \ + WRITE_SYSREG(pr->prbar.bits & ~MPU_REGION_RES0, PRBAR##num##_EL2); \ + WRITE_SYSREG(pr->prlar.bits & ~MPU_REGION_RES0, PRLAR##num##_EL2); \ + break; \ + } + +#define GENERATE_READ_PR_REG_CASE(num, pr) \ + case num: \ + { \ + pr->prbar.bits = READ_SYSREG(PRBAR##num##_EL2); \ + pr->prlar.bits = READ_SYSREG(PRLAR##num##_EL2); \ + break; \ + } + static void __init __maybe_unused build_assertions(void) { /* @@ -24,6 +46,111 @@ static void __init __maybe_unused build_assertions(void) BUILD_BUG_ON(PAGE_SIZE != SZ_4K); } +static void prepare_selector(uint8_t 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. + */ + sel &= 0xF0U; + if ( READ_SYSREG(PRSELR_EL2) != sel ) + { + WRITE_SYSREG(sel, PRSELR_EL2); + isb(); + } +} + +/* + * Armv8-R AArch64 at most supports 255 MPU protection regions. + * See section G1.3.18 of the reference manual for Armv8-R AArch64, + * PRBAR_EL2 and PRLAR_EL2 provide access to the EL2 MPU region + * determined by the value of 'n' and PRSELR_EL2.REGION as + * PRSELR_EL2.REGION<7:4>:n(n = 0, 1, 2, ... , 15) + * For example to access regions from 16 to 31 (0b10000 to 0b11111): + * - Set PRSELR_EL2 to 0b1xxxx + * - Region 16 configuration is accessible through PRBAR_EL2 and PRLAR_EL2 + * - Region 17 configuration is accessible through PRBAR1_EL2 and PRLAR1_EL2 + * - Region 18 configuration is accessible through PRBAR2_EL2 and PRLAR2_EL2 + * - ... + * - Region 31 configuration is accessible through PRBAR15_EL2 and PRLAR15_EL2 + */ +/* + * Read EL2 MPU Protection Region. + * + * @pr_read: mpu protection region returned by read op. + * @sel: mpu protection region selector + */ +void read_protection_region(pr_t *pr_read, uint8_t sel) +{ + /* + * Before accessing EL2 MPU region register PRBAR_EL2/PRLAR_EL2, + * make sure PRSELR_EL2 is set, as it determines which MPU region + * is selected. + */ + prepare_selector(sel); + + switch ( sel & 0xFU ) + { + 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 */ + } +} + +/* + * Write EL2 MPU Protection Region. + * + * @pr_write: const mpu protection region passed through write op. + * @sel: mpu protection region selector + */ +void write_protection_region(const pr_t *pr_write, uint8_t sel) +{ + /* + * Before accessing EL2 MPU region register PRBAR_EL2/PRLAR_EL2, + * make sure PRSELR_EL2 is set, as it determines which MPU region + * is selected. + */ + prepare_selector(sel); + + switch ( sel & 0xFU ) + { + 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 */ + } +} + void __init setup_mm(void) { BUG_ON("unimplemented"); From patchwork Mon Apr 7 09:14:26 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Luca Fancellu X-Patchwork-Id: 14040035 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 3149AC369A1 for ; Mon, 7 Apr 2025 09:14:55 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.939429.1339539 (Exim 4.92) (envelope-from ) id 1u1iZ5-0004gq-8E; Mon, 07 Apr 2025 09:14:47 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 939429.1339539; Mon, 07 Apr 2025 09:14:47 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1u1iZ5-0004gj-2l; Mon, 07 Apr 2025 09:14:47 +0000 Received: by outflank-mailman (input) for mailman id 939429; Mon, 07 Apr 2025 09:14:45 +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 1u1iZ3-0003xw-3I for xen-devel@lists.xenproject.org; Mon, 07 Apr 2025 09:14:45 +0000 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by se1-gles-flk1.inumbo.com (Halon) with ESMTP id be044adc-1390-11f0-9ffb-bf95429c2676; Mon, 07 Apr 2025 11:14:43 +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 31103106F; Mon, 7 Apr 2025 02:14:44 -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 F2EEC3F59E; Mon, 7 Apr 2025 02:14:41 -0700 (PDT) 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: be044adc-1390-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 v2 3/7] arm/mpu: Introduce utility functions for the pr_t type Date: Mon, 7 Apr 2025 10:14:26 +0100 Message-Id: <20250407091430.2342709-4-luca.fancellu@arm.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250407091430.2342709-1-luca.fancellu@arm.com> References: <20250407091430.2342709-1-luca.fancellu@arm.com> MIME-Version: 1.0 Introduce few utility function to manipulate and handle the pr_t type. Signed-off-by: Luca Fancellu --- xen/arch/arm/include/asm/mpu.h | 40 ++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/xen/arch/arm/include/asm/mpu.h b/xen/arch/arm/include/asm/mpu.h index 59ff22c804c1..6971507457fb 100644 --- a/xen/arch/arm/include/asm/mpu.h +++ b/xen/arch/arm/include/asm/mpu.h @@ -20,6 +20,46 @@ #define NUM_MPU_REGIONS_MASK (NUM_MPU_REGIONS - 1) #define MAX_MPU_REGIONS NUM_MPU_REGIONS_MASK +#ifndef __ASSEMBLY__ + +/* Set base address of MPU protection region(pr_t). */ +static inline void pr_set_base(pr_t *pr, paddr_t base) +{ + pr->prbar.reg.base = (base >> MPU_REGION_SHIFT); +} + +/* Set limit address of MPU protection region(pr_t). */ +static inline void pr_set_limit(pr_t *pr, paddr_t limit) +{ + pr->prlar.reg.limit = ((limit - 1) >> MPU_REGION_SHIFT); +} + +/* + * Access to get base address of MPU protection region(pr_t). + * The base address shall be zero extended. + */ +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(pr_t). + * The limit address shall be concatenated with 0x3f. + */ +static inline paddr_t pr_get_limit(pr_t *pr) +{ + return (paddr_t)((pr->prlar.reg.limit << MPU_REGION_SHIFT) + | ~MPU_REGION_MASK); +} + +static inline bool region_is_valid(pr_t *pr) +{ + return pr->prlar.reg.en; +} + +#endif /* __ASSEMBLY__ */ + #endif /* __ARM_MPU_H__ */ /* From patchwork Mon Apr 7 09:14:27 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Luca Fancellu X-Patchwork-Id: 14040039 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id E3AB6C369A3 for ; Mon, 7 Apr 2025 09:14:58 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.939430.1339544 (Exim 4.92) (envelope-from ) id 1u1iZ5-0004kI-IX; Mon, 07 Apr 2025 09:14:47 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 939430.1339544; Mon, 07 Apr 2025 09:14:47 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1u1iZ5-0004iX-AO; Mon, 07 Apr 2025 09:14:47 +0000 Received: by outflank-mailman (input) for mailman id 939430; Mon, 07 Apr 2025 09:14:45 +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 1u1iZ3-0003xy-Cu for xen-devel@lists.xenproject.org; Mon, 07 Apr 2025 09:14:45 +0000 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by se1-gles-sth1.inumbo.com (Halon) with ESMTP id beb9279c-1390-11f0-9eaa-5ba50f476ded; Mon, 07 Apr 2025 11:14:44 +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 74C001424; Mon, 7 Apr 2025 02:14:45 -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 420293F59E; Mon, 7 Apr 2025 02:14:43 -0700 (PDT) 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: beb9279c-1390-11f0-9eaa-5ba50f476ded From: Luca Fancellu To: xen-devel@lists.xenproject.org Cc: Stefano Stabellini , Julien Grall , Bertrand Marquis , Michal Orzel , Volodymyr Babchuk Subject: [PATCH v2 4/7] arm/mpu: Provide a constructor for pr_t type Date: Mon, 7 Apr 2025 10:14:27 +0100 Message-Id: <20250407091430.2342709-5-luca.fancellu@arm.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250407091430.2342709-1-luca.fancellu@arm.com> References: <20250407091430.2342709-1-luca.fancellu@arm.com> MIME-Version: 1.0 Provide a function that creates a pr_t object from a memory range and some attributes. Signed-off-by: Luca Fancellu --- 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 | 3 ++ xen/arch/arm/mpu/mm.c | 73 ++++++++++++++++++++++++++++ 4 files changed, 91 insertions(+) diff --git a/xen/arch/arm/include/asm/arm64/mpu.h b/xen/arch/arm/include/asm/arm64/mpu.h index 4d2bd7d7877f..7cf8d355a1af 100644 --- a/xen/arch/arm/include/asm/arm64/mpu.h +++ b/xen/arch/arm/include/asm/arm64/mpu.h @@ -6,6 +6,17 @@ #ifndef __ARM_ARM64_MPU_H__ #define __ARM_ARM64_MPU_H__ +/* + * 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 XN_EL2_ENABLED 0x2 + #ifndef __ASSEMBLY__ /* Protection Region Base Address Register */ diff --git a/xen/arch/arm/include/asm/mpu.h b/xen/arch/arm/include/asm/mpu.h index 6971507457fb..eba5086cde97 100644 --- a/xen/arch/arm/include/asm/mpu.h +++ b/xen/arch/arm/include/asm/mpu.h @@ -20,6 +20,10 @@ #define NUM_MPU_REGIONS_MASK (NUM_MPU_REGIONS - 1) #define MAX_MPU_REGIONS NUM_MPU_REGIONS_MASK +/* Access permission attributes. */ +/* Read/Write at EL2, No Access at EL1/EL0. */ +#define AP_RW_EL2 0x0 + #ifndef __ASSEMBLY__ /* Set base address of MPU protection region(pr_t). */ diff --git a/xen/arch/arm/include/asm/mpu/mm.h b/xen/arch/arm/include/asm/mpu/mm.h index 5cabe9d111ce..9c7a01d6bd58 100644 --- a/xen/arch/arm/include/asm/mpu/mm.h +++ b/xen/arch/arm/include/asm/mpu/mm.h @@ -53,6 +53,9 @@ extern void read_protection_region(pr_t *pr_read, uint8_t sel); /* Writes the MPU region with index 'sel' to the HW */ extern void write_protection_region(const pr_t *pr_write, uint8_t sel); +/* Creates a pr_t entry for the MPU data structure */ +extern pr_t pr_of_xenaddr(paddr_t base, paddr_t limit, unsigned attr); + #endif /* __ARM_MPU_MM_H__ */ /* diff --git a/xen/arch/arm/mpu/mm.c b/xen/arch/arm/mpu/mm.c index bf281f67fb6b..2c5820a44f13 100644 --- a/xen/arch/arm/mpu/mm.c +++ b/xen/arch/arm/mpu/mm.c @@ -9,6 +9,7 @@ #include #include #include +#include #include struct page_info *frame_table; @@ -151,6 +152,78 @@ void write_protection_region(const pr_t *pr_write, uint8_t sel) } } +/* + * Standard entry for building up the structure of MPU memory region(pr_t). + * It is equivalent to mfn_to_xen_entry in MMU system. + * Base and limit refer to exclusive range [start, limit]. + */ +pr_t pr_of_xenaddr(paddr_t base, paddr_t limit, unsigned attr) +{ + prbar_t prbar; + prlar_t prlar; + pr_t region; + + /* Build up value for PRBAR_EL2. */ + prbar = (prbar_t) { + .reg = { + .ap = AP_RW_EL2, /* Read/Write at EL2, no access at EL1/EL0. */ + .xn = XN_EL2_ENABLED, /* No need to execute outside .text */ + }}; + + switch ( attr ) + { + 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 normal, + * and a resultant cacheability attribute of Inner non-cacheable, + * outer non-cacheable, must have a resultant shareability attribute + * 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 = 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 = LPAE_SH_OUTER; + break; + default: + /* Xen mappings are SMP coherent */ + prbar.reg.sh = LPAE_SH_INNER; + } + + /* Build up value for PRLAR_EL2. */ + prlar = (prlar_t) { + .reg = { + .ns = 0, /* Hyp mode is in secure world */ + .ai = attr, + .en = 1, /* Region enabled */ + }}; + + /* Build up MPU memory region. */ + region = (pr_t) { + .prbar = prbar, + .prlar = prlar, + }; + + /* Set base address and limit address. */ + pr_set_base(®ion, base); + pr_set_limit(®ion, limit); + + return region; +} + void __init setup_mm(void) { BUG_ON("unimplemented"); From patchwork Mon Apr 7 09:14:28 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Luca Fancellu X-Patchwork-Id: 14040036 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 1BB77C3601E for ; Mon, 7 Apr 2025 09:14:58 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.939431.1339551 (Exim 4.92) (envelope-from ) id 1u1iZ6-0004tz-3I; Mon, 07 Apr 2025 09:14:48 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 939431.1339551; Mon, 07 Apr 2025 09:14:48 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1u1iZ5-0004rl-RL; Mon, 07 Apr 2025 09:14:47 +0000 Received: by outflank-mailman (input) for mailman id 939431; Mon, 07 Apr 2025 09:14:46 +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 1u1iZ4-0003xy-N7 for xen-devel@lists.xenproject.org; Mon, 07 Apr 2025 09:14:46 +0000 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by se1-gles-sth1.inumbo.com (Halon) with ESMTP id bf90f20c-1390-11f0-9eaa-5ba50f476ded; Mon, 07 Apr 2025 11:14:46 +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 B8B181BF3; Mon, 7 Apr 2025 02:14:46 -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 85D1A3F59E; Mon, 7 Apr 2025 02:14:44 -0700 (PDT) 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: bf90f20c-1390-11f0-9eaa-5ba50f476ded From: Luca Fancellu To: xen-devel@lists.xenproject.org Cc: Stefano Stabellini , Julien Grall , Bertrand Marquis , Michal Orzel , Volodymyr Babchuk Subject: [PATCH v2 5/7] arm/mpu: Introduce MPU memory mapping flags Date: Mon, 7 Apr 2025 10:14:28 +0100 Message-Id: <20250407091430.2342709-6-luca.fancellu@arm.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250407091430.2342709-1-luca.fancellu@arm.com> References: <20250407091430.2342709-1-luca.fancellu@arm.com> MIME-Version: 1.0 Introduce the MPU memory mapping flags in asm/page.h. Signed-off-by: Luca Fancellu --- 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/page.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 @@ #define MAIRVAL (MAIR1VAL << 32 | MAIR0VAL) +#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) +#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. From patchwork Mon Apr 7 09:14:29 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Luca Fancellu X-Patchwork-Id: 14040038 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id DF863C369A1 for ; Mon, 7 Apr 2025 09:14:58 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.939433.1339567 (Exim 4.92) (envelope-from ) id 1u1iZ9-0005Vl-78; Mon, 07 Apr 2025 09:14:51 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 939433.1339567; Mon, 07 Apr 2025 09:14:51 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1u1iZ9-0005Vc-3V; Mon, 07 Apr 2025 09:14:51 +0000 Received: by outflank-mailman (input) for mailman id 939433; Mon, 07 Apr 2025 09:14:49 +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 1u1iZ7-0003xw-4q for xen-devel@lists.xenproject.org; Mon, 07 Apr 2025 09:14:49 +0000 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by se1-gles-flk1.inumbo.com (Halon) with ESMTP id c04d5ca2-1390-11f0-9ffb-bf95429c2676; Mon, 07 Apr 2025 11:14:47 +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 0770B106F; Mon, 7 Apr 2025 02:14:48 -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 C9A833F59E; Mon, 7 Apr 2025 02:14:45 -0700 (PDT) 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: c04d5ca2-1390-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 v2 6/7] arm/mpu: Implement early_fdt_map support in MPU systems Date: Mon, 7 Apr 2025 10:14:29 +0100 Message-Id: <20250407091430.2342709-7-luca.fancellu@arm.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250407091430.2342709-1-luca.fancellu@arm.com> References: <20250407091430.2342709-1-luca.fancellu@arm.com> MIME-Version: 1.0 Implement early_fdt_map() function, that is responsible to map the device tree blob in the early stages of the boot process, since at this stage the MPU C data structure are not yet initialised, it is using low level APIs to write into the MPU registers at a fixed MPU region number. The MPU memory management is designed to work on pages of PAGE_SIZE in order to reuse helpers and macros already available on the Xen memory management system. Signed-off-by: Luca Fancellu --- xen/arch/arm/mpu/setup.c | 54 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 52 insertions(+), 2 deletions(-) diff --git a/xen/arch/arm/mpu/setup.c b/xen/arch/arm/mpu/setup.c index b4da77003f47..5969065250d4 100644 --- a/xen/arch/arm/mpu/setup.c +++ b/xen/arch/arm/mpu/setup.c @@ -1,17 +1,67 @@ /* SPDX-License-Identifier: GPL-2.0-only */ +#include #include #include +#include #include +#include #include +#include +#include #include +/* Needs to be kept in sync with the regions programmed in arm64/mpu/head.S */ +#define EARLY_FDT_MAP_REGION_NUMBER 6 + void __init setup_pagetables(void) {} void * __init early_fdt_map(paddr_t fdt_paddr) { - BUG_ON("unimplemented"); - return NULL; + /* Map at least a page containing the DTB address, exclusive range */ + paddr_t base_paddr = round_pgdown(fdt_paddr); + paddr_t end_paddr = round_pgup(fdt_paddr + sizeof(struct fdt_header)); + unsigned int flags = PAGE_HYPERVISOR_RO; + void *fdt_virt = (void *)fdt_paddr; /* virt == paddr for MPU */ + pr_t fdt_region; + + /* + * Check whether the physical FDT address is set and meets the minimum + * alignment requirement. Since we are relying on MIN_FDT_ALIGN to be at + * least 8 bytes so that we always access the magic and size fields + * of the FDT header after mapping the first chunk, double check if + * that is indeed the case. + */ + BUILD_BUG_ON(MIN_FDT_ALIGN < 8); + if ( !fdt_paddr || fdt_paddr % MIN_FDT_ALIGN ) + return NULL; + + /* Map the device tree blob header */ + fdt_region = pr_of_xenaddr(base_paddr, end_paddr, PAGE_AI_MASK(flags)); + fdt_region.prbar.reg.ap = PAGE_AP_MASK(flags); + fdt_region.prbar.reg.xn = PAGE_XN_MASK(flags); + + write_protection_region(&fdt_region, EARLY_FDT_MAP_REGION_NUMBER); + context_sync_mpu(); + + if ( fdt_magic(fdt_virt) != FDT_MAGIC ) + return NULL; + + end_paddr = round_pgup(fdt_paddr + fdt_totalsize(fdt_virt)); + + /* + * If the mapped range is not enough, map the rest of the DTB, pr_get_limit + * returns an inclusive address of the range, hence the increment. + */ + if ( end_paddr > (pr_get_limit(&fdt_region) + 1) ) + { + pr_set_limit(&fdt_region, end_paddr); + + write_protection_region(&fdt_region, EARLY_FDT_MAP_REGION_NUMBER); + context_sync_mpu(); + } + + return fdt_virt; } /* From patchwork Mon Apr 7 09:14:30 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Luca Fancellu X-Patchwork-Id: 14040037 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id EB8A4C36010 for ; Mon, 7 Apr 2025 09:14:57 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.939434.1339572 (Exim 4.92) (envelope-from ) id 1u1iZ9-0005YC-KA; Mon, 07 Apr 2025 09:14:51 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 939434.1339572; Mon, 07 Apr 2025 09:14:51 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1u1iZ9-0005Xg-Cd; Mon, 07 Apr 2025 09:14:51 +0000 Received: by outflank-mailman (input) for mailman id 939434; Mon, 07 Apr 2025 09:14:49 +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 1u1iZ7-0003xy-Fd for xen-devel@lists.xenproject.org; Mon, 07 Apr 2025 09:14:49 +0000 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by se1-gles-sth1.inumbo.com (Halon) with ESMTP id c11750d6-1390-11f0-9eaa-5ba50f476ded; Mon, 07 Apr 2025 11:14:48 +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 4A8181424; Mon, 7 Apr 2025 02:14:49 -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 184E03F59E; Mon, 7 Apr 2025 02:14:46 -0700 (PDT) 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: c11750d6-1390-11f0-9eaa-5ba50f476ded From: Luca Fancellu To: xen-devel@lists.xenproject.org Cc: Stefano Stabellini , Julien Grall , Bertrand Marquis , Michal Orzel , Volodymyr Babchuk Subject: [PATCH v2 7/7] arm/mpu: Implement setup_mpu for MPU system Date: Mon, 7 Apr 2025 10:14:30 +0100 Message-Id: <20250407091430.2342709-8-luca.fancellu@arm.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250407091430.2342709-1-luca.fancellu@arm.com> References: <20250407091430.2342709-1-luca.fancellu@arm.com> MIME-Version: 1.0 Implement the function setup_mpu that will logically track the MPU regions defined by hardware registers, start introducing data structures and functions to track the status from the C world. The xen_mpumap_mask bitmap is used to track which MPU region are enabled at runtime. This function is called from setup_mm() which full implementation will be provided in a later stage. Signed-off-by: Luca Fancellu --- xen/arch/arm/include/asm/arm64/mpu.h | 2 ++ xen/arch/arm/mpu/mm.c | 49 +++++++++++++++++++++++++++- 2 files changed, 50 insertions(+), 1 deletion(-) diff --git a/xen/arch/arm/include/asm/arm64/mpu.h b/xen/arch/arm/include/asm/arm64/mpu.h index 7cf8d355a1af..ff5a957bf085 100644 --- a/xen/arch/arm/include/asm/arm64/mpu.h +++ b/xen/arch/arm/include/asm/arm64/mpu.h @@ -6,6 +6,8 @@ #ifndef __ARM_ARM64_MPU_H__ #define __ARM_ARM64_MPU_H__ +#define PRENR_MASK GENMASK(31, 0) + /* * Excute never. * Stage 1 EL2 translation regime. diff --git a/xen/arch/arm/mpu/mm.c b/xen/arch/arm/mpu/mm.c index 2c5820a44f13..fe05c8097155 100644 --- a/xen/arch/arm/mpu/mm.c +++ b/xen/arch/arm/mpu/mm.c @@ -14,6 +14,17 @@ struct page_info *frame_table; +/* 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_REGIONS); + /* EL2 Xen MPU memory region mapping table. */ pr_t xen_mpumap[MAX_MPU_REGIONS]; @@ -224,9 +235,45 @@ pr_t pr_of_xenaddr(paddr_t base, paddr_t limit, unsigned attr) return region; } +/* + * The code in this function needs to track the regions programmed in + * arm64/mpu/head.S + */ +static void __init setup_mpu(void) +{ + register_t prenr; + unsigned int i = 0; + + /* + * MPUIR_EL2.Region[0:7] identifies the number of regions supported by + * the EL2 MPU. + */ + max_xen_mpumap = (uint8_t)(READ_SYSREG(MPUIR_EL2) & NUM_MPU_REGIONS_MASK); + + /* PRENR_EL2 has the N bit set if the N region is enabled, N < 32 */ + prenr = (READ_SYSREG(PRENR_EL2) & PRENR_MASK); + + /* + * Set the bitfield for regions enabled in assembly boot-time. + * This code works under the assumption that the code in head.S has + * allocated and enabled regions below 32 (N < 32). + */ + while ( prenr > 0 ) + { + if (prenr & 0x1) + { + set_bit(i, xen_mpumap_mask); + read_protection_region(&xen_mpumap[i], i); + } + + prenr >>= 1; + i++; + } +} + void __init setup_mm(void) { - BUG_ON("unimplemented"); + setup_mpu(); } int modify_xen_mappings(unsigned long s, unsigned long e, unsigned int nf)