From nobody Mon Feb 9 19:47:49 2026 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 1673588174963893.7143328894316; Thu, 12 Jan 2023 21:36:14 -0800 (PST) Received: from list by lists.xenproject.org with outflank-mailman.476589.738958 (Exim 4.92) (envelope-from ) id 1pGCjM-0001nx-IH; Fri, 13 Jan 2023 05:35:56 +0000 Received: by outflank-mailman (output) from mailman id 476589.738958; Fri, 13 Jan 2023 05:35:56 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1pGCjM-0001nk-CM; Fri, 13 Jan 2023 05:35:56 +0000 Received: by outflank-mailman (input) for mailman id 476589; Fri, 13 Jan 2023 05:35:54 +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 1pGCf2-0005sP-AO for xen-devel@lists.xenproject.org; Fri, 13 Jan 2023 05:31:28 +0000 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by se1-gles-flk1.inumbo.com (Halon) with ESMTP id 85e3d938-9303-11ed-b8d0-410ff93cb8f0; Fri, 13 Jan 2023 06:31:26 +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 CE16FFEC; Thu, 12 Jan 2023 21:32:07 -0800 (PST) Received: from a011292.shanghai.arm.com (a011292.shanghai.arm.com [10.169.190.94]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 1BACD3F587; Thu, 12 Jan 2023 21:31:22 -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: 85e3d938-9303-11ed-b8d0-410ff93cb8f0 From: Penny Zheng To: xen-devel@lists.xenproject.org Cc: wei.chen@arm.com, Penny Zheng , Stefano Stabellini , Julien Grall , Bertrand Marquis , Volodymyr Babchuk , Penny Zheng Subject: [PATCH v2 34/40] xen/mpu: free init memory in MPU system Date: Fri, 13 Jan 2023 13:29:07 +0800 Message-Id: <20230113052914.3845596-35-Penny.Zheng@arm.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230113052914.3845596-1-Penny.Zheng@arm.com> References: <20230113052914.3845596-1-Penny.Zheng@arm.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ZM-MESSAGEID: 1673588176136100001 Content-Type: text/plain; charset="utf-8" This commit implements free_init_memory in MPU system, trying to keep the same strategy with MMU system. In order to inserting BRK instruction into init code section, which aims to provok a fault on purpose, we should change init code section permission to RW at first. Function modify_xen_mappings is introduced to modify permission of the existing valid MPU memory region. Then we nuke the instruction cache to remove entries related to init text. At last, we destroy these two MPU memory regions referring init text and init data using destroy_xen_mappings. Signed-off-by: Penny Zheng Signed-off-by: Wei Chen --- xen/arch/arm/mm_mpu.c | 85 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 83 insertions(+), 2 deletions(-) diff --git a/xen/arch/arm/mm_mpu.c b/xen/arch/arm/mm_mpu.c index 0b720004ee..de0c7d919a 100644 --- a/xen/arch/arm/mm_mpu.c +++ b/xen/arch/arm/mm_mpu.c @@ -20,6 +20,7 @@ */ =20 #include +#include #include #include #include @@ -77,6 +78,8 @@ static const unsigned int mpu_section_mattr[MSINFO_MAX] = =3D { REGION_HYPERVISOR_BOOT, }; =20 +extern char __init_data_begin[], __init_end[]; + /* Write a MPU protection region */ #define WRITE_PROTECTION_REGION(sel, pr, prbar_el2, prlar_el2) ({ \ uint64_t _sel =3D sel; \ @@ -443,8 +446,41 @@ static int xen_mpumap_update_entry(paddr_t base, paddr= _t limit, if ( rc =3D=3D MPUMAP_REGION_OVERLAP ) return -EINVAL; =20 + /* We are updating the permission. */ + if ( (flags & _REGION_PRESENT) && (rc =3D=3D MPUMAP_REGION_FOUND || + rc =3D=3D MPUMAP_REGION_INCLUSIVE) ) + { + + /* + * Currently, we only support modifying a *WHOLE* MPU memory regio= n, + * part-region modification is not supported, as in worst case, it= will + * lead to three fragments in result after modification. + * part-region modification will be introduced only when actual us= age + * come + */ + if ( rc =3D=3D MPUMAP_REGION_INCLUSIVE ) + { + region_printk("mpu: part-region modification is not supported\= n"); + return -EINVAL; + } + + /* We don't allow changing memory attributes. */ + if (xen_mpumap[idx].prlar.reg.ai !=3D REGION_AI_MASK(flags) ) + { + region_printk("Modifying memory attributes is not allowed (0x%= x -> 0x%x).\n", + xen_mpumap[idx].prlar.reg.ai, REGION_AI_MASK(fla= gs)); + return -EINVAL; + } + + /* Set new permission */ + xen_mpumap[idx].prbar.reg.ap =3D REGION_AP_MASK(flags); + xen_mpumap[idx].prbar.reg.xn =3D REGION_XN_MASK(flags); + + access_protection_region(false, NULL, (const pr_t*)(&xen_mpumap[id= x]), + idx); + } /* We are inserting a mapping =3D> Create new region. */ - if ( flags & _REGION_PRESENT ) + else if ( flags & _REGION_PRESENT ) { if ( rc !=3D MPUMAP_REGION_FAILED ) return -EINVAL; @@ -831,11 +867,56 @@ void mmu_init_secondary_cpu(void) =20 int modify_xen_mappings(unsigned long s, unsigned long e, unsigned int fla= gs) { - return -ENOSYS; + ASSERT(IS_ALIGNED(s, PAGE_SIZE)); + ASSERT(IS_ALIGNED(e, PAGE_SIZE)); + ASSERT(s <=3D e); + return xen_mpumap_update(s, e, flags); } =20 void free_init_memory(void) { + /* Kernel init text section. */ + paddr_t init_text =3D virt_to_maddr(_sinittext); + paddr_t init_text_end =3D round_pgup(virt_to_maddr(_einittext)); + /* Kernel init data. */ + paddr_t init_data =3D virt_to_maddr(__init_data_begin); + paddr_t init_data_end =3D round_pgup(virt_to_maddr(__init_end)); + unsigned long init_section[4] =3D {(unsigned long)init_text, + (unsigned long)init_text_end, + (unsigned long)init_data, + (unsigned long)init_data_end}; + unsigned int nr_init =3D 2; + uint32_t insn =3D AARCH64_BREAK_FAULT; + unsigned int i =3D 0, j =3D 0; + + /* Change kernel init text section to RW. */ + modify_xen_mappings((unsigned long)init_text, + (unsigned long)init_text_end, REGION_HYPERVISOR_RW= ); + + /* + * 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(); + + /* Destroy two MPU memory regions referring init text and init data. */ + for ( ; i < nr_init; i++ ) + { + uint32_t *p; + unsigned int nr; + int rc; + + i =3D 2 * i; + p =3D (uint32_t *)init_section[i]; + nr =3D (init_section[i + 1] - init_section[i]) / sizeof(uint32_t); + + for ( ; j < nr ; j++ ) + *(p + j) =3D insn; + + rc =3D destroy_xen_mappings(init_section[i], init_section[i + 1]); + if ( rc < 0 ) + panic("Unable to remove the init section (rc =3D %d)\n", rc); + } } =20 int xenmem_add_to_physmap_one( --=20 2.25.1