From nobody Fri Jan 9 08:37:33 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; 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 1767612974846320.05220835757245; Mon, 5 Jan 2026 03:36:14 -0800 (PST) Received: from list by lists.xenproject.org with outflank-mailman.1195267.1513254 (Exim 4.92) (envelope-from ) id 1vcisN-0004jy-Uv; Mon, 05 Jan 2026 11:35:55 +0000 Received: by outflank-mailman (output) from mailman id 1195267.1513254; Mon, 05 Jan 2026 11:35:55 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1vcisN-0004hj-PI; Mon, 05 Jan 2026 11:35:55 +0000 Received: by outflank-mailman (input) for mailman id 1195267; Mon, 05 Jan 2026 11:35:55 +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 1vcisN-00047I-2K for xen-devel@lists.xenproject.org; Mon, 05 Jan 2026 11:35:55 +0000 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by se1-gles-sth1.inumbo.com (Halon) with ESMTP id b1c18be3-ea2a-11f0-b15e-2bf370ae4941; Mon, 05 Jan 2026 12:35:54 +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 AEF01339; Mon, 5 Jan 2026 03:35:46 -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 68AD63F5A1; Mon, 5 Jan 2026 03:35:52 -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: b1c18be3-ea2a-11f0-b15e-2bf370ae4941 From: Harry Ramsey To: xen-devel@lists.xenproject.org Cc: Luca.Fancellu@arm.com, Luca Fancellu , Stefano Stabellini , Julien Grall , Bertrand Marquis , Michal Orzel , Volodymyr Babchuk , Hari Limaye Subject: [PATCH v2 4/6] arm/mpu: Introduce modify_after_init_mappings Date: Mon, 5 Jan 2026 11:35:01 +0000 Message-ID: <20260105113503.2674777-5-harry.ramsey@arm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260105113503.2674777-1-harry.ramsey@arm.com> References: <20260105113503.2674777-1-harry.ramsey@arm.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ZM-MESSAGEID: 1767612988430154100 Content-Type: text/plain; charset="utf-8" From: Luca Fancellu During `init_done`, Xen sets the permissions of all symbols marked with __ro_after_init to be read-only. This does not work on MPU systems at present because part-region modification is not supported. Therefore introduce the function `modify_after_init_mappings` for MMU and MPU, to handle the divergent approaches to setting permissions of __ro_after_init symbols. For MPU systems `modify_xen_mappings` will shrink the RW mapping on one side and extend the RO mapping on the other. This approach prevents wasting an additional region between RW and RO mappings. As the new function is marked with __init, it needs to be called before `free_init_memory`. Signed-off-by: Luca Fancellu Signed-off-by: Hari Limaye Signed-off-by: Harry Ramsey --- v2: - No changes --- xen/arch/arm/include/asm/setup.h | 3 +++ xen/arch/arm/mmu/setup.c | 15 ++++++++++++ xen/arch/arm/mpu/mm.c | 2 +- xen/arch/arm/mpu/setup.c | 40 ++++++++++++++++++++++++++++++++ xen/arch/arm/setup.c | 15 ++---------- 5 files changed, 61 insertions(+), 14 deletions(-) diff --git a/xen/arch/arm/include/asm/setup.h b/xen/arch/arm/include/asm/se= tup.h index 005cf7be59..899e33925c 100644 --- a/xen/arch/arm/include/asm/setup.h +++ b/xen/arch/arm/include/asm/setup.h @@ -78,6 +78,9 @@ struct init_info paddr_t consider_modules(paddr_t s, paddr_t e, uint32_t size, paddr_t alig= n, int first_mod); =20 +/* Modify some mappings after the init is done */ +void modify_after_init_mappings(void); + #endif /* * Local variables: diff --git a/xen/arch/arm/mmu/setup.c b/xen/arch/arm/mmu/setup.c index 9b874f8ab2..d042f73597 100644 --- a/xen/arch/arm/mmu/setup.c +++ b/xen/arch/arm/mmu/setup.c @@ -213,6 +213,21 @@ void __init remove_early_mappings(void) BUG_ON(rc); } =20 +void __init modify_after_init_mappings(void) +{ + /* + * We have finished booting. Mark the section .data.ro_after_init + * read-only. + */ + int rc =3D modify_xen_mappings((unsigned long)&__ro_after_init_start, + (unsigned long)&__ro_after_init_end, + PAGE_HYPERVISOR_RO); + + if ( rc ) + panic("Unable to mark the .data.ro_after_init section read-only (r= c =3D %d)\n", + rc); +} + /* * After boot, Xen page-tables should not contain mapping that are both * Writable and eXecutables. diff --git a/xen/arch/arm/mpu/mm.c b/xen/arch/arm/mpu/mm.c index 4194d4fefd..7fc1658bb2 100644 --- a/xen/arch/arm/mpu/mm.c +++ b/xen/arch/arm/mpu/mm.c @@ -32,7 +32,7 @@ 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); +DEFINE_SPINLOCK(xen_mpumap_lock); =20 static void __init __maybe_unused build_assertions(void) { diff --git a/xen/arch/arm/mpu/setup.c b/xen/arch/arm/mpu/setup.c index ec264f54f2..55317ee318 100644 --- a/xen/arch/arm/mpu/setup.c +++ b/xen/arch/arm/mpu/setup.c @@ -8,11 +8,14 @@ #include #include #include +#include #include =20 static paddr_t __initdata mapped_fdt_base =3D INVALID_PADDR; static paddr_t __initdata mapped_fdt_limit =3D INVALID_PADDR; =20 +extern spinlock_t xen_mpumap_lock; + void __init setup_pagetables(void) {} =20 void * __init early_fdt_map(paddr_t fdt_paddr) @@ -106,6 +109,43 @@ void __init copy_from_paddr(void *dst, paddr_t paddr, = unsigned long len) panic("Unable to unmap range for copy_from_paddr\n"); } =20 +void __init modify_after_init_mappings(void) +{ + int rc; + uint8_t idx_rodata; + uint8_t idx_rwdata; + + spin_lock(&xen_mpumap_lock); + + rc =3D mpumap_contains_region(xen_mpumap, max_mpu_regions, + (unsigned long)_srodata, + (unsigned long)_erodata, + &idx_rodata); + + if ( rc < MPUMAP_REGION_FOUND ) + panic("Unable to find rodata section (rc =3D %d)\n", rc); + + rc =3D mpumap_contains_region(xen_mpumap, max_mpu_regions, + (unsigned long)__ro_after_init_start, + (unsigned long)__init_begin, + &idx_rwdata); + + if ( rc < MPUMAP_REGION_FOUND ) + panic("Unable to find rwdata section (rc =3D %d)\n", rc); + + /* Shrink rwdata section to begin at __ro_after_init_end */ + pr_set_base(&xen_mpumap[idx_rwdata], (unsigned long)__ro_after_init_en= d); + + /* Extend rodata section to end at __ro_after_init_end */ + pr_set_limit(&xen_mpumap[idx_rodata], (unsigned long)__ro_after_init_e= nd); + + write_protection_region(&xen_mpumap[idx_rwdata], idx_rwdata); + write_protection_region(&xen_mpumap[idx_rodata], idx_rodata); + context_sync_mpu(); + + spin_unlock(&xen_mpumap_lock); +} + void __init remove_early_mappings(void) { int rc =3D destroy_xen_mappings(round_pgdown(mapped_fdt_base), diff --git a/xen/arch/arm/setup.c b/xen/arch/arm/setup.c index 7ad870e382..6310a47d68 100644 --- a/xen/arch/arm/setup.c +++ b/xen/arch/arm/setup.c @@ -66,23 +66,12 @@ domid_t __read_mostly max_init_domid; =20 static __used void noreturn init_done(void) { - int rc; - /* Must be done past setting system_state. */ unregister_init_virtual_region(); =20 - free_init_memory(); + modify_after_init_mappings(); =20 - /* - * We have finished booting. Mark the section .data.ro_after_init - * read-only. - */ - rc =3D modify_xen_mappings((unsigned long)&__ro_after_init_start, - (unsigned long)&__ro_after_init_end, - PAGE_HYPERVISOR_RO); - if ( rc ) - panic("Unable to mark the .data.ro_after_init section read-only (r= c =3D %d)\n", - rc); + free_init_memory(); =20 startup_cpu_idle_loop(); } --=20 2.43.0