From nobody Sun Dec 14 11:57:19 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 1764324116155569.7320445021656; Fri, 28 Nov 2025 02:01:56 -0800 (PST) Received: from list by lists.xenproject.org with outflank-mailman.1174650.1499627 (Exim 4.92) (envelope-from ) id 1vOvHw-00014l-95; Fri, 28 Nov 2025 10:01:16 +0000 Received: by outflank-mailman (output) from mailman id 1174650.1499627; Fri, 28 Nov 2025 10:01:16 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1vOvHw-00014b-5c; Fri, 28 Nov 2025 10:01:16 +0000 Received: by outflank-mailman (input) for mailman id 1174650; Fri, 28 Nov 2025 10:01: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 1vOvHv-0000F3-B4 for xen-devel@lists.xenproject.org; Fri, 28 Nov 2025 10:01:15 +0000 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by se1-gles-flk1.inumbo.com (Halon) with ESMTP id e926ac68-cc40-11f0-980a-7dc792cee155; Fri, 28 Nov 2025 11:00:46 +0100 (CET) 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 3B0501A32; Fri, 28 Nov 2025 01:59:13 -0800 (PST) Received: from e134099.cambridge.arm.com (e134099.arm.com [10.1.198.34]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id B686C3F73B; Fri, 28 Nov 2025 01:59:17 -0800 (PST) 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: e926ac68-cc40-11f0-980a-7dc792cee155 From: Harry Ramsey 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 , Luca Fancellu , Hari Limaye Subject: [PATCH 3/6] arm/mpu: Implement free_init_memory for MPU systems Date: Fri, 28 Nov 2025 09:58:56 +0000 Message-ID: <20251128095859.11264-4-harry.ramsey@arm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20251128095859.11264-1-harry.ramsey@arm.com> References: <20251128095859.11264-1-harry.ramsey@arm.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ZM-MESSAGEID: 1764324118383019200 Content-Type: text/plain; charset="utf-8" From: Penny Zheng Implement the function `free_init_memory` for MPU systems. In order to support this, the function `modify_xen_mappings` is implemented. On MPU systems, we map the init text and init data sections using separate MPU memory regions. Therefore these are removed separately in `free_init_memory`. Additionally remove warning messages from `is_mm_attr_match` as some permissions can now be updated by `xen_mpumap_update_entry`. Signed-off-by: Penny Zheng Signed-off-by: Wei Chen Signed-off-by: Luca Fancellu Signed-off-by: Hari Limaye Signed-off-by: Harry Ramsey --- xen/arch/arm/include/asm/setup.h | 2 + xen/arch/arm/mpu/mm.c | 91 +++++++++++++++++++++++++------- 2 files changed, 73 insertions(+), 20 deletions(-) diff --git a/xen/arch/arm/include/asm/setup.h b/xen/arch/arm/include/asm/se= tup.h index 1eaf13bd66..005cf7be59 100644 --- a/xen/arch/arm/include/asm/setup.h +++ b/xen/arch/arm/include/asm/setup.h @@ -65,6 +65,8 @@ int map_irq_to_domain(struct domain *d, unsigned int irq, int map_range_to_domain(const struct dt_device_node *dev, uint64_t addr, uint64_t len, void *data); =20 +extern const char __init_data_begin[], __bss_start[], __bss_end[]; + struct init_info { /* Pointer to the stack, used by head.S when entering in C */ diff --git a/xen/arch/arm/mpu/mm.c b/xen/arch/arm/mpu/mm.c index 29d8e7ff11..8446dddde8 100644 --- a/xen/arch/arm/mpu/mm.c +++ b/xen/arch/arm/mpu/mm.c @@ -174,28 +174,13 @@ int mpumap_contains_region(pr_t *table, uint8_t nr_re= gions, paddr_t base, static bool is_mm_attr_match(pr_t *region, unsigned int attributes) { if ( region->prbar.reg.ro !=3D PAGE_RO_MASK(attributes) ) - { - printk(XENLOG_WARNING - "Mismatched Access Permission attributes (%#x instead of %#= x)\n", - region->prbar.reg.ro, PAGE_RO_MASK(attributes)); return false; - } =20 if ( region->prbar.reg.xn !=3D PAGE_XN_MASK(attributes) ) - { - printk(XENLOG_WARNING - "Mismatched Execute Never attributes (%#x instead of %#x)\n= ", - region->prbar.reg.xn, PAGE_XN_MASK(attributes)); return false; - } =20 if ( region->prlar.reg.ai !=3D PAGE_AI_MASK(attributes) ) - { - printk(XENLOG_WARNING - "Mismatched Memory Attribute Index (%#x instead of %#x)\n", - region->prlar.reg.ai, PAGE_AI_MASK(attributes)); return false; - } =20 return true; } @@ -352,8 +337,33 @@ static int xen_mpumap_update_entry(paddr_t base, paddr= _t limit, { if ( !is_mm_attr_match(&xen_mpumap[idx], flags) ) { - printk("Modifying an existing entry is not supported\n"); - return -EINVAL; + if ( rc =3D=3D MPUMAP_REGION_INCLUSIVE ) + { + printk(XENLOG_ERR + "Cannot modify partial region permissions\n"); + return -EINVAL; + } + + if ( xen_mpumap[idx].prlar.reg.ai !=3D PAGE_AI_MASK(flags) ) + { + printk(XENLOG_ERR + "Modifying memory attribute is not supported\n"); + return -EINVAL; + } + + if ( xen_mpumap[idx].refcount !=3D 0 ) + { + printk(XENLOG_ERR + "Cannot modify memory permissions for a region mapp= ed multiple time\n"); + return -EINVAL; + } + + /* Set new permission */ + xen_mpumap[idx].prbar.reg.ro =3D PAGE_RO_MASK(flags); + xen_mpumap[idx].prbar.reg.xn =3D PAGE_XN_MASK(flags); + + write_protection_region(&xen_mpumap[idx], idx); + return 0; } =20 /* Check for overflow of refcount before incrementing. */ @@ -499,8 +509,7 @@ void __init setup_mm_helper(void) =20 int modify_xen_mappings(unsigned long s, unsigned long e, unsigned int nf) { - BUG_ON("unimplemented"); - return -EINVAL; + return xen_mpumap_update(s, e, nf); } =20 void dump_hyp_walk(vaddr_t addr) @@ -511,7 +520,49 @@ void dump_hyp_walk(vaddr_t addr) /* Release all __init and __initdata ranges to be reused */ void free_init_memory(void) { - BUG_ON("unimplemented"); + unsigned long inittext_end =3D round_pgup((unsigned long)__init_data_b= egin); + unsigned long len =3D __init_end - __init_begin; + uint8_t idx; + int rc; + + rc =3D modify_xen_mappings((unsigned long)__init_begin, inittext_end, + PAGE_HYPERVISOR_RW); + if ( rc ) + panic("Unable to map RW the init text section (rc =3D %d)\n", rc); + + /* + * From now on, init will not be used for execution anymore, + * so nuke the instruction cache to remove entries related to init. + */ + invalidate_icache_local(); + + /* Zeroing the memory before returning it */ + memset(__init_begin, 0, len); + + rc =3D destroy_xen_mappings((unsigned long)__init_begin, inittext_end); + if ( rc ) + panic("Unable to remove init text section (rc =3D %d)\n", rc); + + /* + * The initdata and bss sections are mapped using a single MPU region,= so + * modify the start of this region to remove the initdata section. + */ + spin_lock(&xen_mpumap_lock); + + rc =3D mpumap_contains_region(xen_mpumap, max_mpu_regions, + (unsigned long)__init_data_begin, + (unsigned long)__bss_end, + &idx); + if ( rc < MPUMAP_REGION_FOUND ) + panic("Unable to find bss data section (rc =3D %d)\n", rc); + + /* bss data section is shrunk and now starts from __bss_start */ + pr_set_base(&xen_mpumap[idx], (unsigned long)__bss_start); + + write_protection_region(&xen_mpumap[idx], idx); + context_sync_mpu(); + + spin_unlock(&xen_mpumap_lock); } =20 void __iomem *ioremap_attr(paddr_t start, size_t len, unsigned int flags) --=20 2.43.0