From nobody Fri Oct 31 03:47:35 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 1750413018592685.8342939501883; Fri, 20 Jun 2025 02:50:18 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1020714.1396845 (Exim 4.92) (envelope-from ) id 1uSYNs-0005xr-5t; Fri, 20 Jun 2025 09:50:08 +0000 Received: by outflank-mailman (output) from mailman id 1020714.1396845; Fri, 20 Jun 2025 09:50:08 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uSYNs-0005xh-35; Fri, 20 Jun 2025 09:50:08 +0000 Received: by outflank-mailman (input) for mailman id 1020714; Fri, 20 Jun 2025 09:50:07 +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 1uSYNr-0004kQ-AX for xen-devel@lists.xenproject.org; Fri, 20 Jun 2025 09:50:07 +0000 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by se1-gles-flk1.inumbo.com (Halon) with ESMTP id f15d5528-4dbb-11f0-b894-0df219b8e170; Fri, 20 Jun 2025 11:50:05 +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 3C10C1A25; Fri, 20 Jun 2025 02:49:45 -0700 (PDT) Received: from PWQ0QT7DJ1.arm.com (unknown [10.57.67.38]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 998D63F673; Fri, 20 Jun 2025 02:50:03 -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: f15d5528-4dbb-11f0-b894-0df219b8e170 From: Hari Limaye To: xen-devel@lists.xenproject.org Cc: luca.fancellu@arm.com, Stefano Stabellini , Julien Grall , Bertrand Marquis , Michal Orzel , Volodymyr Babchuk Subject: [PATCH 1/6] arm/mpu: Find MPU region by range Date: Fri, 20 Jun 2025 10:49:19 +0100 Message-ID: X-Mailer: git-send-email 2.42.1 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ZM-MESSAGEID: 1750413020137116600 Content-Type: text/plain; charset="utf-8" From: Luca Fancellu Implement a function to find the index of a MPU region in the xen_mpumap MPU region array. Signed-off-by: Luca Fancellu Signed-off-by: Hari Limaye Reviewed-by: Ayan Kumar Halder --- xen/arch/arm/include/asm/mpu/mm.h | 29 ++++++++++++++ xen/arch/arm/mpu/mm.c | 66 +++++++++++++++++++++++++++++++ 2 files changed, 95 insertions(+) diff --git a/xen/arch/arm/include/asm/mpu/mm.h b/xen/arch/arm/include/asm/m= pu/mm.h index a7f970b465..a0f0d86d4a 100644 --- a/xen/arch/arm/include/asm/mpu/mm.h +++ b/xen/arch/arm/include/asm/mpu/mm.h @@ -10,6 +10,13 @@ #include #include =20 +#define MPUMAP_REGION_OVERLAP -1 +#define MPUMAP_REGION_NOTFOUND 0 +#define MPUMAP_REGION_FOUND 1 +#define MPUMAP_REGION_INCLUSIVE 2 + +#define INVALID_REGION_IDX 0xFFU + extern struct page_info *frame_table; =20 extern uint8_t max_mpu_regions; @@ -75,6 +82,28 @@ void write_protection_region(const pr_t *pr_write, uint8= _t sel); */ pr_t pr_of_addr(paddr_t base, paddr_t limit, unsigned int flags); =20 +/* + * Checks whether a given memory range is present in the provided table of + * MPU protection regions. + * + * @param table Array of pr_t protection regions. + * @param r_regions Number of elements in `table`. + * @param base Start of the memory region to be checked (inclusiv= e). + * @param limit End of the memory region to be checked (exclusive). + * @param index Set to the index of the region if an exact or incl= usive + * match is found, and INVALID_REGION otherwise. + * @return: Return code indicating the result of the search: + * MPUMAP_REGION_NOTFOUND: no part of the range is present in #ta= ble + * MPUMAP_REGION_FOUND: found an exact match in #table + * MPUMAP_REGION_INCLUSIVE: found an inclusive match in #table + * MPUMAP_REGION_OVERLAP: found an overlap with a mapping in #tab= le + * + * Note: make sure that the range [#base, #limit) refers to the half-open + * interval inclusive of #base and exclusive of #limit. + */ +int mpumap_contain_region(pr_t *table, uint8_t nr_regions, paddr_t base, + paddr_t limit, uint8_t *index); + #endif /* __ARM_MPU_MM_H__ */ =20 /* diff --git a/xen/arch/arm/mpu/mm.c b/xen/arch/arm/mpu/mm.c index ccfb37a67b..15197339b1 100644 --- a/xen/arch/arm/mpu/mm.c +++ b/xen/arch/arm/mpu/mm.c @@ -12,6 +12,18 @@ #include #include =20 +#ifdef NDEBUG +static inline void __attribute__ ((__format__ (__printf__, 1, 2))) +region_printk(const char *fmt, ...) {} +#else /* !NDEBUG */ +#define region_printk(fmt, args...) \ + do \ + { \ + dprintk(XENLOG_ERR, fmt, ## args); \ + WARN(); \ + } while (0) +#endif /* NDEBUG */ + struct page_info *frame_table; =20 /* Maximum number of supported MPU memory regions by the EL2 MPU. */ @@ -110,6 +122,60 @@ pr_t pr_of_addr(paddr_t base, paddr_t limit, unsigned = int flags) return region; } =20 +int mpumap_contain_region(pr_t *table, uint8_t nr_regions, paddr_t base, + paddr_t limit, uint8_t *index) +{ + uint8_t i =3D 0, _index; + + /* Allow index to be NULL */ + index =3D index ? index : &_index; + + /* Inside mpumap_contain_region check for inclusive range */ + limit =3D limit - 1; + + *index =3D INVALID_REGION_IDX; + + if ( limit < base ) + { + region_printk("Base address 0x%"PRIpaddr" must be smaller than lim= it address 0x%"PRIpaddr"\n", + base, limit); + return -EINVAL; + } + + for ( ; i < nr_regions; i++ ) + { + paddr_t iter_base =3D pr_get_base(&table[i]); + paddr_t iter_limit =3D pr_get_limit(&table[i]); + + /* Found an exact valid match */ + if ( (iter_base =3D=3D base) && (iter_limit =3D=3D limit) && + region_is_valid(&table[i]) ) + { + *index =3D i; + return MPUMAP_REGION_FOUND; + } + + /* No overlapping */ + if ( (iter_limit < base) || (iter_base > limit) ) + continue; + + /* Inclusive and valid */ + if ( (base >=3D iter_base) && (limit <=3D iter_limit) && + region_is_valid(&table[i]) ) + { + *index =3D i; + return MPUMAP_REGION_INCLUSIVE; + } + + /* Overlap */ + region_printk("Range 0x%"PRIpaddr" - 0x%"PRIpaddr" overlaps with t= he existing region 0x%"PRIpaddr" - 0x%"PRIpaddr"\n", + base, limit + 1, iter_base, iter_limit + 1); + return MPUMAP_REGION_OVERLAP; + } + + return MPUMAP_REGION_NOTFOUND; +} + void __init setup_mm(void) { BUG_ON("unimplemented"); --=20 2.34.1 From nobody Fri Oct 31 03:47:35 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 175041305780086.03161069224518; Fri, 20 Jun 2025 02:50:57 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1020734.1396865 (Exim 4.92) (envelope-from ) id 1uSYOU-0007LR-RD; Fri, 20 Jun 2025 09:50:46 +0000 Received: by outflank-mailman (output) from mailman id 1020734.1396865; Fri, 20 Jun 2025 09:50:46 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uSYOU-0007LI-OD; Fri, 20 Jun 2025 09:50:46 +0000 Received: by outflank-mailman (input) for mailman id 1020734; Fri, 20 Jun 2025 09:50: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 1uSYOT-0004kQ-AR for xen-devel@lists.xenproject.org; Fri, 20 Jun 2025 09:50:45 +0000 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by se1-gles-flk1.inumbo.com (Halon) with ESMTP id 0823130f-4dbc-11f0-b894-0df219b8e170; Fri, 20 Jun 2025 11:50: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 78CB1176A; Fri, 20 Jun 2025 02:50:23 -0700 (PDT) Received: from PWQ0QT7DJ1.arm.com (unknown [10.57.67.38]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id E96063F673; Fri, 20 Jun 2025 02:50:41 -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: 0823130f-4dbc-11f0-b894-0df219b8e170 From: Hari Limaye To: xen-devel@lists.xenproject.org Cc: luca.fancellu@arm.com, Stefano Stabellini , Julien Grall , Bertrand Marquis , Michal Orzel , Volodymyr Babchuk Subject: [PATCH 2/6] xen/arm: Introduce flags_has_rwx helper Date: Fri, 20 Jun 2025 10:49:20 +0100 Message-ID: X-Mailer: git-send-email 2.42.1 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ZM-MESSAGEID: 1750413058510116600 Content-Type: text/plain; charset="utf-8" From: Luca Fancellu Introduce flags_has_rwx() function that will check if a mapping is both writable and executable when modifying or update the mapping. This check was already present in pt.c but since it will be used also for MPU system, it's wrapped into a function now. Signed-off-by: Luca Fancellu Reviewed-by: Ayan Kumar Halder Reviewed-by: Michal Orzel --- xen/arch/arm/include/asm/mm.h | 2 ++ xen/arch/arm/mm.c | 15 +++++++++++++++ xen/arch/arm/mmu/pt.c | 9 +-------- 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/xen/arch/arm/include/asm/mm.h b/xen/arch/arm/include/asm/mm.h index 011bc1fd30..9daaa96d93 100644 --- a/xen/arch/arm/include/asm/mm.h +++ b/xen/arch/arm/include/asm/mm.h @@ -192,6 +192,8 @@ extern unsigned long frametable_base_pdx; =20 /* Boot-time pagetable setup */ extern void setup_pagetables(void); +/* Check that the mapping flag has no W and X together */ +extern bool flags_has_rwx(unsigned int flags); /* Map FDT in boot pagetable */ extern void *early_fdt_map(paddr_t fdt_paddr); /* Remove early mappings */ diff --git a/xen/arch/arm/mm.c b/xen/arch/arm/mm.c index 0613c19169..c2da1e3a05 100644 --- a/xen/arch/arm/mm.c +++ b/xen/arch/arm/mm.c @@ -24,6 +24,21 @@ =20 unsigned long frametable_base_pdx __read_mostly; =20 +bool flags_has_rwx(unsigned int flags) +{ + /* + * The hardware was configured to forbid mapping both writeable and + * executable. + * When modifying/creating mapping (i.e _PAGE_PRESENT is set), + * prevent any update if this happen. + */ + if ( (flags & _PAGE_PRESENT) && !PAGE_RO_MASK(flags) && + !PAGE_XN_MASK(flags) ) + return true; + else + return false; +} + void flush_page_to_ram(unsigned long mfn, bool sync_icache) { void *v =3D map_domain_page(_mfn(mfn)); diff --git a/xen/arch/arm/mmu/pt.c b/xen/arch/arm/mmu/pt.c index 4726e713ef..621b47dbf5 100644 --- a/xen/arch/arm/mmu/pt.c +++ b/xen/arch/arm/mmu/pt.c @@ -610,14 +610,7 @@ static int xen_pt_update(unsigned long virt, */ const mfn_t root =3D maddr_to_mfn(READ_SYSREG64(TTBR0_EL2)); =20 - /* - * The hardware was configured to forbid mapping both writeable and - * executable. - * When modifying/creating mapping (i.e _PAGE_PRESENT is set), - * prevent any update if this happen. - */ - if ( (flags & _PAGE_PRESENT) && !PAGE_RO_MASK(flags) && - !PAGE_XN_MASK(flags) ) + if ( flags_has_rwx(flags) ) { mm_printk("Mappings should not be both Writeable and Executable.\n= "); return -EINVAL; --=20 2.34.1 From nobody Fri Oct 31 03:47:35 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 1750413076085443.0694443342147; Fri, 20 Jun 2025 02:51:16 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1020737.1396875 (Exim 4.92) (envelope-from ) id 1uSYOl-0007nU-2x; Fri, 20 Jun 2025 09:51:03 +0000 Received: by outflank-mailman (output) from mailman id 1020737.1396875; Fri, 20 Jun 2025 09:51:03 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uSYOk-0007nM-Vz; Fri, 20 Jun 2025 09:51:02 +0000 Received: by outflank-mailman (input) for mailman id 1020737; Fri, 20 Jun 2025 09:51:01 +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 1uSYOj-0004kQ-55 for xen-devel@lists.xenproject.org; Fri, 20 Jun 2025 09:51:01 +0000 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by se1-gles-flk1.inumbo.com (Halon) with ESMTP id 11716f90-4dbc-11f0-b894-0df219b8e170; Fri, 20 Jun 2025 11:50:59 +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 19E34176A; Fri, 20 Jun 2025 02:50:39 -0700 (PDT) Received: from PWQ0QT7DJ1.arm.com (unknown [10.57.67.38]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 2A5FA3F673; Fri, 20 Jun 2025 02:50:57 -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: 11716f90-4dbc-11f0-b894-0df219b8e170 From: Hari Limaye To: xen-devel@lists.xenproject.org Cc: luca.fancellu@arm.com, Penny Zheng , Stefano Stabellini , Julien Grall , Bertrand Marquis , Michal Orzel , Volodymyr Babchuk , Penny Zheng , Wei Chen Subject: [PATCH 3/6] arm/mpu: Populate a new region in Xen MPU mapping table Date: Fri, 20 Jun 2025 10:49:21 +0100 Message-ID: <840ec219278c2fcb4f8592303eb671b5271b0a95.1750411205.git.hari.limaye@arm.com> X-Mailer: git-send-email 2.42.1 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ZM-MESSAGEID: 1750413076829116600 Content-Type: text/plain; charset="utf-8" From: Penny Zheng Introduce map_pages_to_xen() that is implemented using a new helper, xen_mpumap_update(), which is responsible for updating Xen MPU memory mapping table(xen_mpumap), including creating a new entry, updating or destroying an existing one, it is equivalent to xen_pt_update in MMU. This commit only implements populating a new entry in Xen MPU memory mapping table(xen_mpumap). Signed-off-by: Penny Zheng Signed-off-by: Wei Chen Signed-off-by: Luca Fancellu Signed-off-by: Hari Limaye --- xen/arch/arm/include/asm/mpu/mm.h | 12 ++++ xen/arch/arm/mpu/mm.c | 96 +++++++++++++++++++++++++++++++ 2 files changed, 108 insertions(+) diff --git a/xen/arch/arm/include/asm/mpu/mm.h b/xen/arch/arm/include/asm/m= pu/mm.h index a0f0d86d4a..f0f41db210 100644 --- a/xen/arch/arm/include/asm/mpu/mm.h +++ b/xen/arch/arm/include/asm/mpu/mm.h @@ -64,6 +64,7 @@ static inline void context_sync_mpu(void) * The following API requires context_sync_mpu() after being used to modif= y MPU * regions: * - write_protection_region + * - xen_mpumap_update */ =20 /* Reads the MPU region (into @pr_read) with index @sel from the HW */ @@ -72,6 +73,17 @@ void read_protection_region(pr_t *pr_read, uint8_t sel); /* Writes the MPU region (from @pr_write) with index @sel to the HW */ void write_protection_region(const pr_t *pr_write, uint8_t sel); =20 +/* + * Maps an address range into the MPU data structure and updates the HW. + * Equivalent to xen_pt_update in an MMU system. + * + * @param base Base address of the range to map (inclusive). + * @param limit Limit address of the range to map (exclusive). + * @param flags Flags for the memory range to map. + * @return 0 on success, negative on error. + */ +int xen_mpumap_update(paddr_t base, paddr_t limit, unsigned int flags); + /* * Creates a pr_t structure describing a protection region. * diff --git a/xen/arch/arm/mpu/mm.c b/xen/arch/arm/mpu/mm.c index 15197339b1..1de28d2120 100644 --- a/xen/arch/arm/mpu/mm.c +++ b/xen/arch/arm/mpu/mm.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -41,6 +42,8 @@ DECLARE_BITMAP(xen_mpumap_mask, MAX_MPU_REGION_NR) \ /* EL2 Xen MPU memory region mapping table. */ pr_t __cacheline_aligned __section(".data") xen_mpumap[MAX_MPU_REGION_NR]; =20 +static DEFINE_SPINLOCK(xen_mpumap_lock); + static void __init __maybe_unused build_assertions(void) { /* @@ -176,6 +179,99 @@ int mpumap_contain_region(pr_t *table, uint8_t nr_regi= ons, paddr_t base, return MPUMAP_REGION_NOTFOUND; } =20 +/* + * Allocate a new free EL2 MPU memory region, based on bitmap xen_mpumap_m= ask. + * @param idx Set to the index of the allocated EL2 MPU region on succes= s. + * @return 0 on success, otherwise -ENOENT on failure. + */ +static int xen_mpumap_alloc_entry(uint8_t *idx) +{ + ASSERT(spin_is_locked(&xen_mpumap_lock)); + + *idx =3D find_first_zero_bit(xen_mpumap_mask, max_mpu_regions); + if ( *idx =3D=3D max_mpu_regions ) + { + printk(XENLOG_ERR "mpu: EL2 MPU memory region mapping pool exhaust= ed\n"); + return -ENOENT; + } + + set_bit(*idx, xen_mpumap_mask); + return 0; +} + +/* + * Update the entry in the MPU memory region mapping table (xen_mpumap) fo= r the + * given memory range and flags, creating one if none exists. + * + * @param base Base address (inclusive). + * @param limit Limit address (exclusive). + * @param flags Region attributes (a combination of PAGE_HYPERVISOR_XXX) + * @return 0 on success, otherwise negative on error. + */ +static int xen_mpumap_update_entry(paddr_t base, paddr_t limit, + unsigned int flags) +{ + uint8_t idx; + int rc; + + ASSERT(spin_is_locked(&xen_mpumap_lock)); + + rc =3D mpumap_contain_region(xen_mpumap, max_mpu_regions, base, limit,= &idx); + if ( (rc < 0) || (rc > MPUMAP_REGION_NOTFOUND) ) + return -EINVAL; + + /* We are inserting a mapping =3D> Create new region. */ + if ( flags & _PAGE_PRESENT ) + { + rc =3D xen_mpumap_alloc_entry(&idx); + if ( rc ) + return -ENOENT; + + xen_mpumap[idx] =3D pr_of_addr(base, limit, flags); + + write_protection_region(&xen_mpumap[idx], idx); + } + + return 0; +} + +int xen_mpumap_update(paddr_t base, paddr_t limit, unsigned int flags) +{ + int rc; + + if ( flags_has_rwx(flags) ) + { + region_printk("Mappings should not be both Writeable and Executabl= e\n"); + return -EINVAL; + } + + if ( !IS_ALIGNED(base, PAGE_SIZE) || !IS_ALIGNED(limit, PAGE_SIZE) ) + { + region_printk("base address 0x%"PRIpaddr", or limit address 0x%"PR= Ipaddr" is not page aligned\n", + base, limit); + return -EINVAL; + } + + spin_lock(&xen_mpumap_lock); + + rc =3D xen_mpumap_update_entry(base, limit, flags); + + spin_unlock(&xen_mpumap_lock); + + return rc; +} + +int map_pages_to_xen(unsigned long virt, mfn_t mfn, unsigned long nr_mfns, + unsigned int flags) +{ + int rc =3D xen_mpumap_update(mfn_to_maddr(mfn), + mfn_to_maddr(mfn_add(mfn, nr_mfns)), flags); + if ( !rc ) + context_sync_mpu(); + + return rc; +} + void __init setup_mm(void) { BUG_ON("unimplemented"); --=20 2.34.1 From nobody Fri Oct 31 03:47:35 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 175041371535690.69959175932638; Fri, 20 Jun 2025 03:01:55 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1020772.1396916 (Exim 4.92) (envelope-from ) id 1uSYZ0-0002sL-On; Fri, 20 Jun 2025 10:01:38 +0000 Received: by outflank-mailman (output) from mailman id 1020772.1396916; Fri, 20 Jun 2025 10:01:38 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uSYZ0-0002sE-Kx; Fri, 20 Jun 2025 10:01:38 +0000 Received: by outflank-mailman (input) for mailman id 1020772; Fri, 20 Jun 2025 10:01:37 +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 1uSYOn-0004kQ-GN for xen-devel@lists.xenproject.org; Fri, 20 Jun 2025 09:51:05 +0000 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by se1-gles-flk1.inumbo.com (Halon) with ESMTP id 1414d8ae-4dbc-11f0-b894-0df219b8e170; Fri, 20 Jun 2025 11:51:03 +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 81B11176A; Fri, 20 Jun 2025 02:50:43 -0700 (PDT) Received: from PWQ0QT7DJ1.arm.com (unknown [10.57.67.38]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 8FD223F673; Fri, 20 Jun 2025 02:51:01 -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: 1414d8ae-4dbc-11f0-b894-0df219b8e170 From: Hari Limaye To: xen-devel@lists.xenproject.org Cc: luca.fancellu@arm.com, Penny Zheng , Stefano Stabellini , Julien Grall , Bertrand Marquis , Michal Orzel , Volodymyr Babchuk , Penny Zheng , Wei Chen Subject: [PATCH 4/6] arm/mpu: Destroy an existing entry in Xen MPU memory mapping table Date: Fri, 20 Jun 2025 10:49:22 +0100 Message-ID: <95cc28af74339ea617081f3935123e38a53cc657.1750411205.git.hari.limaye@arm.com> X-Mailer: git-send-email 2.42.1 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ZM-MESSAGEID: 1750413717370116600 Content-Type: text/plain; charset="utf-8" From: Penny Zheng This commit expands xen_mpumap_update/xen_mpumap_update_entry to include destroying an existing entry. We define a new helper "disable_mpu_region_from_index" to disable the MPU region based on index. If region is within [0, 31], we could quickly disable the MPU region through PRENR_EL2 which provides direct access to the PRLAR_EL2.EN bits of EL2 MPU regions. Rignt now, we only support destroying a *WHOLE* MPU memory region, part-region removing is not supported, as in worst case, it will leave two fragments behind. Signed-off-by: Penny Zheng Signed-off-by: Wei Chen Signed-off-by: Luca Fancellu Signed-off-by: Hari Limaye --- xen/arch/arm/include/asm/mpu.h | 2 + xen/arch/arm/include/asm/mpu/cpregs.h | 4 ++ xen/arch/arm/mpu/mm.c | 71 ++++++++++++++++++++++++++- 3 files changed, 75 insertions(+), 2 deletions(-) diff --git a/xen/arch/arm/include/asm/mpu.h b/xen/arch/arm/include/asm/mpu.h index 63560c613b..5053edaf63 100644 --- a/xen/arch/arm/include/asm/mpu.h +++ b/xen/arch/arm/include/asm/mpu.h @@ -23,6 +23,8 @@ #define NUM_MPU_REGIONS_MASK (NUM_MPU_REGIONS - 1) #define MAX_MPU_REGION_NR NUM_MPU_REGIONS_MASK =20 +#define PRENR_MASK GENMASK(31, 0) + #ifndef __ASSEMBLY__ =20 /* diff --git a/xen/arch/arm/include/asm/mpu/cpregs.h b/xen/arch/arm/include/a= sm/mpu/cpregs.h index bb15e02df6..9f3b32acd7 100644 --- a/xen/arch/arm/include/asm/mpu/cpregs.h +++ b/xen/arch/arm/include/asm/mpu/cpregs.h @@ -6,6 +6,9 @@ /* CP15 CR0: MPU Type Register */ #define HMPUIR p15,4,c0,c0,4 =20 +/* CP15 CR6: Protection Region Enable Register */ +#define HPRENR p15,4,c6,c1,1 + /* CP15 CR6: MPU Protection Region Base/Limit/Select Address Register */ #define HPRSELR p15,4,c6,c2,1 #define HPRBAR p15,4,c6,c3,0 @@ -82,6 +85,7 @@ /* Alphabetically... */ #define MPUIR_EL2 HMPUIR #define PRBAR_EL2 HPRBAR +#define PRENR_EL2 HPRENR #define PRLAR_EL2 HPRLAR #define PRSELR_EL2 HPRSELR #endif /* CONFIG_ARM_32 */ diff --git a/xen/arch/arm/mpu/mm.c b/xen/arch/arm/mpu/mm.c index 1de28d2120..23230936f7 100644 --- a/xen/arch/arm/mpu/mm.c +++ b/xen/arch/arm/mpu/mm.c @@ -199,6 +199,42 @@ static int xen_mpumap_alloc_entry(uint8_t *idx) return 0; } =20 +/* + * Disable and remove an MPU region from the data structure and MPU regist= ers. + * + * @param index Index of the MPU region to be disabled. + */ +static void disable_mpu_region_from_index(uint8_t index) +{ + ASSERT(spin_is_locked(&xen_mpumap_lock)); + ASSERT(index !=3D INVALID_REGION_IDX); + + if ( !region_is_valid(&xen_mpumap[index]) ) + { + printk(XENLOG_WARNING + "mpu: MPU memory region[%u] is already disabled\n", index); + return; + } + + /* Zeroing the region will also zero the region enable */ + memset(&xen_mpumap[index], 0, sizeof(pr_t)); + clear_bit(index, xen_mpumap_mask); + + /* + * Both Armv8-R AArch64 and AArch32 have direct access to the enable b= it for + * MPU regions numbered from 0 to 31. + */ + if ( (index & PRENR_MASK) !=3D 0 ) + { + /* Clear respective bit */ + uint64_t val =3D READ_SYSREG(PRENR_EL2) & (~(1UL << index)); + + WRITE_SYSREG(val, PRENR_EL2); + } + else + write_protection_region(&xen_mpumap[index], index); +} + /* * Update the entry in the MPU memory region mapping table (xen_mpumap) fo= r the * given memory range and flags, creating one if none exists. @@ -217,11 +253,11 @@ static int xen_mpumap_update_entry(paddr_t base, padd= r_t limit, ASSERT(spin_is_locked(&xen_mpumap_lock)); =20 rc =3D mpumap_contain_region(xen_mpumap, max_mpu_regions, base, limit,= &idx); - if ( (rc < 0) || (rc > MPUMAP_REGION_NOTFOUND) ) + if ( rc < 0 ) return -EINVAL; =20 /* We are inserting a mapping =3D> Create new region. */ - if ( flags & _PAGE_PRESENT ) + if ( (flags & _PAGE_PRESENT) && (MPUMAP_REGION_NOTFOUND =3D=3D rc) ) { rc =3D xen_mpumap_alloc_entry(&idx); if ( rc ) @@ -232,6 +268,22 @@ static int xen_mpumap_update_entry(paddr_t base, paddr= _t limit, write_protection_region(&xen_mpumap[idx], idx); } =20 + if ( !(flags & _PAGE_PRESENT) && (rc >=3D MPUMAP_REGION_FOUND) ) + { + /* + * Currently, we only support destroying a *WHOLE* MPU memory regi= on, + * part-region removing is not supported, as in worst case, it will + * leave two fragments behind. + */ + if ( MPUMAP_REGION_INCLUSIVE =3D=3D rc ) + { + region_printk("mpu: part-region removing is not supported\n"); + return -EINVAL; + } + + disable_mpu_region_from_index(idx); + } + return 0; } =20 @@ -261,6 +313,21 @@ int xen_mpumap_update(paddr_t base, paddr_t limit, uns= igned int flags) return rc; } =20 +int destroy_xen_mappings(unsigned long s, unsigned long e) +{ + int rc; + + ASSERT(IS_ALIGNED(s, PAGE_SIZE)); + ASSERT(IS_ALIGNED(e, PAGE_SIZE)); + ASSERT(s <=3D e); + + rc =3D xen_mpumap_update(virt_to_maddr(s), virt_to_maddr(e), 0); + if ( !rc ) + context_sync_mpu(); + + return rc; +} + int map_pages_to_xen(unsigned long virt, mfn_t mfn, unsigned long nr_mfns, unsigned int flags) { --=20 2.34.1 From nobody Fri Oct 31 03:47:35 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 1750413080864956.6658234103675; Fri, 20 Jun 2025 02:51:20 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1020742.1396885 (Exim 4.92) (envelope-from ) id 1uSYOt-00086l-9J; Fri, 20 Jun 2025 09:51:11 +0000 Received: by outflank-mailman (output) from mailman id 1020742.1396885; Fri, 20 Jun 2025 09:51:11 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uSYOt-00086c-67; Fri, 20 Jun 2025 09:51:11 +0000 Received: by outflank-mailman (input) for mailman id 1020742; Fri, 20 Jun 2025 09:51:10 +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 1uSYOs-00082H-CC for xen-devel@lists.xenproject.org; Fri, 20 Jun 2025 09:51:10 +0000 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by se1-gles-sth1.inumbo.com (Halon) with ESMTP id 165ed3ea-4dbc-11f0-a30e-13f23c93f187; Fri, 20 Jun 2025 11:51:07 +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 4EC0E176A; Fri, 20 Jun 2025 02:50:47 -0700 (PDT) Received: from PWQ0QT7DJ1.arm.com (unknown [10.57.67.38]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id BFE243F673; Fri, 20 Jun 2025 02:51:05 -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: 165ed3ea-4dbc-11f0-a30e-13f23c93f187 From: Hari Limaye To: xen-devel@lists.xenproject.org Cc: luca.fancellu@arm.com, Stefano Stabellini , Julien Grall , Bertrand Marquis , Michal Orzel , Volodymyr Babchuk Subject: [PATCH 5/6] arm/mpu: Implement early_fdt_map support in MPU systems Date: Fri, 20 Jun 2025 10:49:23 +0100 Message-ID: X-Mailer: git-send-email 2.42.1 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ZM-MESSAGEID: 1750413082737116600 Content-Type: text/plain; charset="utf-8" From: Luca Fancellu Implement the function early_fdt_map(), which is responsible for mapping the Device Tree Blob in the early stages of the boot process, for MPU systems. We make use of the map_pages_to_xen() and destroy_xen_mappings() APIs. In particular the latter function is necessary in the case that the initial mapping of the fdt_header is insufficient to cover the entire DTB, as we must destroy and then remap the region due to the APIs no providing support for extending the size of an existing region. Signed-off-by: Luca Fancellu Signed-off-by: Hari Limaye Reviewed-by: Ayan Kumar Halder --- xen/arch/arm/mpu/setup.c | 74 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 72 insertions(+), 2 deletions(-) diff --git a/xen/arch/arm/mpu/setup.c b/xen/arch/arm/mpu/setup.c index b4da77003f..ab00cb944b 100644 --- a/xen/arch/arm/mpu/setup.c +++ b/xen/arch/arm/mpu/setup.c @@ -1,17 +1,87 @@ /* SPDX-License-Identifier: GPL-2.0-only */ =20 +#include #include #include +#include #include +#include #include #include =20 +static paddr_t __initdata mapped_fdt_paddr =3D INVALID_PADDR; +static paddr_t __initdata mapped_fdt_limit =3D INVALID_PADDR; + void __init setup_pagetables(void) {} =20 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 =3D round_pgdown(fdt_paddr); + paddr_t limit =3D round_pgup(fdt_paddr + sizeof(struct fdt_header)); + unsigned int flags =3D PAGE_HYPERVISOR_RO; + void *fdt_virt =3D (void *)fdt_paddr; /* virt =3D=3D paddr for MPU */ + int rc; + unsigned long nr_mfns; + + /* + * 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; + + /* DTB starting at this address has already been mapped. */ + if ( mapped_fdt_paddr =3D=3D fdt_paddr ) + return fdt_virt; + + /* + * DTB starting at a different address has been mapped, so destroy this + * before continuing. + */ + if ( mapped_fdt_paddr !=3D INVALID_PADDR ) + { + rc =3D destroy_xen_mappings(round_pgdown(mapped_fdt_paddr), + mapped_fdt_limit); + if ( rc ) + panic("Unable to unmap existing device-tree.\n"); + } + + nr_mfns =3D (limit - base) >> PAGE_SHIFT; + + rc =3D map_pages_to_xen(base, maddr_to_mfn(base), nr_mfns, flags); + if ( rc ) + panic("Unable to map the device-tree.\n"); + + mapped_fdt_paddr =3D fdt_paddr; + mapped_fdt_limit =3D limit; + + if ( fdt_magic(fdt_virt) !=3D FDT_MAGIC ) + return NULL; + + limit =3D round_pgup(fdt_paddr + fdt_totalsize(fdt_virt)); + + /* If the mapped range is not enough, map the rest of the DTB. */ + if ( limit > mapped_fdt_limit ) + { + rc =3D destroy_xen_mappings(base, mapped_fdt_limit); + if ( rc ) + panic("Unable to unmap the device-tree header.\n"); + + nr_mfns =3D (limit - base) >> PAGE_SHIFT; + + rc =3D map_pages_to_xen(base, maddr_to_mfn(base), nr_mfns, flags); + if ( rc ) + panic("Unable to map the device-tree.\n"); + + mapped_fdt_limit =3D limit; + } + + return fdt_virt; } =20 /* --=20 2.34.1 From nobody Fri Oct 31 03:47:35 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 1750413083422818.5203922991686; Fri, 20 Jun 2025 02:51:23 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1020743.1396895 (Exim 4.92) (envelope-from ) id 1uSYOv-0008NS-G3; Fri, 20 Jun 2025 09:51:13 +0000 Received: by outflank-mailman (output) from mailman id 1020743.1396895; Fri, 20 Jun 2025 09:51:13 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uSYOv-0008NJ-CI; Fri, 20 Jun 2025 09:51:13 +0000 Received: by outflank-mailman (input) for mailman id 1020743; Fri, 20 Jun 2025 09:51: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 1uSYOu-00082H-Ur for xen-devel@lists.xenproject.org; Fri, 20 Jun 2025 09:51:12 +0000 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by se1-gles-sth1.inumbo.com (Halon) with ESMTP id 193fb1e8-4dbc-11f0-a30e-13f23c93f187; Fri, 20 Jun 2025 11:51: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 2D589176A; Fri, 20 Jun 2025 02:50:52 -0700 (PDT) Received: from PWQ0QT7DJ1.arm.com (unknown [10.57.67.38]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 9D68D3F673; Fri, 20 Jun 2025 02:51: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: 193fb1e8-4dbc-11f0-a30e-13f23c93f187 From: Hari Limaye To: xen-devel@lists.xenproject.org Cc: luca.fancellu@arm.com, Stefano Stabellini , Julien Grall , Bertrand Marquis , Michal Orzel , Volodymyr Babchuk Subject: [PATCH 6/6] arm/mpu: Implement remove_early_mappings for MPU systems Date: Fri, 20 Jun 2025 10:49:24 +0100 Message-ID: <9a8b831cc6ff25b03c7ffab6a5c79e653496aa4f.1750411205.git.hari.limaye@arm.com> X-Mailer: git-send-email 2.42.1 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ZM-MESSAGEID: 1750413084680116600 Content-Type: text/plain; charset="utf-8" From: Luca Fancellu Implement remove_early_mappings for MPU systems. Signed-off-by: Luca Fancellu Signed-off-by: Hari Limaye Reviewed-by: Ayan Kumar Halder --- xen/arch/arm/mpu/setup.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/xen/arch/arm/mpu/setup.c b/xen/arch/arm/mpu/setup.c index ab00cb944b..5928b534d5 100644 --- a/xen/arch/arm/mpu/setup.c +++ b/xen/arch/arm/mpu/setup.c @@ -97,7 +97,14 @@ void __init copy_from_paddr(void *dst, paddr_t paddr, un= signed long len) =20 void __init remove_early_mappings(void) { - BUG_ON("unimplemented"); + int rc; + + if ( mapped_fdt_paddr =3D=3D INVALID_PADDR ) + return; + + rc =3D destroy_xen_mappings(round_pgdown(mapped_fdt_paddr), mapped_fdt= _limit); + if ( rc ) + panic("Unable to unmap the device-tree.\n"); } =20 /* --=20 2.34.1