From nobody Tue Feb 10 02:55:09 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 1673588209466385.254829066472; Thu, 12 Jan 2023 21:36:49 -0800 (PST) Received: from list by lists.xenproject.org with outflank-mailman.476642.739116 (Exim 4.92) (envelope-from ) id 1pGCjy-0000ed-83; Fri, 13 Jan 2023 05:36:34 +0000 Received: by outflank-mailman (output) from mailman id 476642.739116; Fri, 13 Jan 2023 05:36:34 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1pGCjy-0000dE-2Q; Fri, 13 Jan 2023 05:36:34 +0000 Received: by outflank-mailman (input) for mailman id 476642; Fri, 13 Jan 2023 05:36:31 +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 1pGCeX-0005sP-BN for xen-devel@lists.xenproject.org; Fri, 13 Jan 2023 05:30:57 +0000 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by se1-gles-flk1.inumbo.com (Halon) with ESMTP id 73673be4-9303-11ed-b8d0-410ff93cb8f0; Fri, 13 Jan 2023 06:30:55 +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 C178BFEC; Thu, 12 Jan 2023 21:31:36 -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 0F3863F587; Thu, 12 Jan 2023 21:30:51 -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: 73673be4-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 25/40] xen/mpu: map MPU guest memory section before static memory initialization Date: Fri, 13 Jan 2023 13:28:58 +0800 Message-Id: <20230113052914.3845596-26-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: 1673588210330100005 Content-Type: text/plain; charset="utf-8" Previous commit introduces a new device tree property "mpu,guest-memory-section" to define MPU guest memory section, which will mitigate the scattering of statically-configured guest RAM. We only need to set up MPU memory region mapping for MPU guest memory secti= on to have access to all guest RAM. And this should happen before static memory initialization(init_staticmem_p= ages()) MPU memory region for MPU guest memory secction gets switched out when idle vcpu leaving, to avoid region overlapping if the vcpu enters into guest mode later. On the contrary, it gets switched in when idle vcpu entering. We introduce a bit in region "region.prlar.sw"(struct pr_t region) to indicate this kind of feature. Signed-off-by: Penny Zheng Signed-off-by: Wei Chen --- xen/arch/arm/include/asm/arm64/mpu.h | 14 ++++++--- xen/arch/arm/mm_mpu.c | 47 +++++++++++++++++++++++++--- 2 files changed, 53 insertions(+), 8 deletions(-) diff --git a/xen/arch/arm/include/asm/arm64/mpu.h b/xen/arch/arm/include/as= m/arm64/mpu.h index b85e420a90..0044bbf05d 100644 --- a/xen/arch/arm/include/asm/arm64/mpu.h +++ b/xen/arch/arm/include/asm/arm64/mpu.h @@ -45,22 +45,26 @@ * [3:4] Execute Never * [5:6] Access Permission * [7] Region Present - * [8] Boot-only Region + * [8:9] 0b00: Fixed Region; 0b01: Boot-only Region; + * 0b10: Region needs switching out/in during vcpu context switch; */ #define _REGION_AI_BIT 0 #define _REGION_XN_BIT 3 #define _REGION_AP_BIT 5 #define _REGION_PRESENT_BIT 7 -#define _REGION_BOOTONLY_BIT 8 +#define _REGION_TRANSIENT_BIT 8 #define _REGION_XN (2U << _REGION_XN_BIT) #define _REGION_RO (2U << _REGION_AP_BIT) #define _REGION_PRESENT (1U << _REGION_PRESENT_BIT) -#define _REGION_BOOTONLY (1U << _REGION_BOOTONLY_BIT) +#define _REGION_BOOTONLY (1U << _REGION_TRANSIENT_BIT) +#define _REGION_SWITCH (2U << _REGION_TRANSIENT_BIT) #define REGION_AI_MASK(x) (((x) >> _REGION_AI_BIT) & 0x7U) #define REGION_XN_MASK(x) (((x) >> _REGION_XN_BIT) & 0x3U) #define REGION_AP_MASK(x) (((x) >> _REGION_AP_BIT) & 0x3U) #define REGION_RO_MASK(x) (((x) >> _REGION_AP_BIT) & 0x2U) #define REGION_BOOTONLY_MASK(x) (((x) >> _REGION_BOOTONLY_BIT) & 0x1U) +#define REGION_SWITCH_MASK(x) (((x) >> _REGION_TRANSIENT_BIT) & 0x2U) +#define REGION_TRANSIENT_MASK(x) (((x) >> _REGION_TRANSIENT_BIT) & 0x3U) =20 /* * _REGION_NORMAL is convenience define. It is not meant to be used @@ -73,6 +77,7 @@ =20 #define REGION_HYPERVISOR REGION_HYPERVISOR_RW #define REGION_HYPERVISOR_BOOT (REGION_HYPERVISOR_RW|_REGION_BOOTONLY) +#define REGION_HYPERVISOR_SWITCH (REGION_HYPERVISOR_RW|_REGION_SWITCH) =20 #define INVALID_REGION (~0UL) =20 @@ -98,7 +103,8 @@ typedef union { unsigned long ns:1; /* Not-Secure */ unsigned long res:1; /* Reserved 0 by hardware */ unsigned long limit:42; /* Limit Address */ - unsigned long pad:16; + unsigned long pad:15; + unsigned long sw:1; /* Region gets switched out/in during vcpu= context switch? */ } reg; uint64_t bits; } prlar_t; diff --git a/xen/arch/arm/mm_mpu.c b/xen/arch/arm/mm_mpu.c index 7b282be4fb..d2e19e836c 100644 --- a/xen/arch/arm/mm_mpu.c +++ b/xen/arch/arm/mm_mpu.c @@ -71,6 +71,10 @@ static paddr_t dtb_paddr; =20 struct page_info *frame_table; =20 +static const unsigned int mpu_section_mattr[MSINFO_MAX] =3D { + REGION_HYPERVISOR_SWITCH, +}; + /* Write a MPU protection region */ #define WRITE_PROTECTION_REGION(sel, pr, prbar_el2, prlar_el2) ({ \ uint64_t _sel =3D sel; \ @@ -414,10 +418,13 @@ static int xen_mpumap_update_entry(paddr_t base, padd= r_t limit, if ( system_state <=3D SYS_STATE_active ) { /* - * If it is a boot-only region (i.e. region for early FDT), - * it shall be added from the tail for late init re-organizing + * If it is a transient region, including boot-only region + * (i.e. region for early FDT), and region which needs switchi= ng + * in/out during vcpu context switch(i.e. region for guest mem= ory + * section), it shall be added from the tail for late init + * re-organizing */ - if ( REGION_BOOTONLY_MASK(flags) ) + if ( REGION_TRANSIENT_MASK(flags) ) idx =3D next_transient_region_idx; else idx =3D next_fixed_region_idx; @@ -427,6 +434,13 @@ static int xen_mpumap_update_entry(paddr_t base, paddr= _t limit, /* Set permission */ xen_mpumap[idx].prbar.reg.ap =3D REGION_AP_MASK(flags); xen_mpumap[idx].prbar.reg.xn =3D REGION_XN_MASK(flags); + /* + * Bit sw indicates that region gets switched out when idle vcpu + * leaving hypervisor mode, and region gets switched in when idle = vcpu + * entering hypervisor mode. + */ + if ( REGION_SWITCH_MASK(flags) ) + xen_mpumap[idx].prlar.reg.sw =3D 1; =20 /* Update and enable the region */ access_protection_region(false, NULL, (const pr_t*)(&xen_mpumap[id= x]), @@ -552,6 +566,29 @@ static void __init setup_staticheap_mappings(void) } } =20 +static void __init map_mpu_memory_section_on_boot(enum mpu_section_info ty= pe, + unsigned int flags) +{ + unsigned int i =3D 0; + + for ( ; i < mpuinfo.sections[type].nr_banks; i++ ) + { + paddr_t start =3D round_pgup( + mpuinfo.sections[type].bank[i].start); + paddr_t size =3D round_pgdown(mpuinfo.sections[type].bank[i].size); + + /* + * Map MPU memory section with transient MPU memory region, + * as they are either boot-only, or will be switched out/in + * during vcpu context switch(i.e. guest memory section). + */ + if ( map_pages_to_xen(start, maddr_to_mfn(start), size >> PAGE_SHI= FT, + flags) ) + panic("mpu: failed to map MPU memory section %s\n", + mpu_section_info_str[type]); + } +} + /* * System RAM is statically partitioned into different functionality * section in Device Tree, including static xenheap, guest memory @@ -563,7 +600,9 @@ void __init setup_static_mappings(void) { setup_staticheap_mappings(); =20 - /* TODO: guest memory section, device memory section, boot-module sect= ion, etc */ + for ( uint8_t i =3D MSINFO_GUEST; i < MSINFO_MAX; i++ ) + map_mpu_memory_section_on_boot(i, mpu_section_mattr[i]); + /* TODO: device memory section, boot-module section, etc */ } =20 /* Map a frame table to cover physical addresses ps through pe */ --=20 2.25.1