From nobody Tue Feb 10 03:40:22 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 1701853639703272.98951527036604; Wed, 6 Dec 2023 01:07:19 -0800 (PST) Received: from list by lists.xenproject.org with outflank-mailman.649010.1013263 (Exim 4.92) (envelope-from ) id 1rAnro-00040b-E7; Wed, 06 Dec 2023 09:06:52 +0000 Received: by outflank-mailman (output) from mailman id 649010.1013263; Wed, 06 Dec 2023 09:06:52 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1rAnro-00040G-9F; Wed, 06 Dec 2023 09:06:52 +0000 Received: by outflank-mailman (input) for mailman id 649010; Wed, 06 Dec 2023 09:06:51 +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 1rAnrm-0002Yw-VM for xen-devel@lists.xenproject.org; Wed, 06 Dec 2023 09:06:50 +0000 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by se1-gles-sth1.inumbo.com (Halon) with ESMTP id ca2f57a6-9416-11ee-98e5-6d05b1d4d9a1; Wed, 06 Dec 2023 10:06:50 +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 834FD139F; Wed, 6 Dec 2023 01:07:35 -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 8B32A3F762; Wed, 6 Dec 2023 01:06:46 -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: ca2f57a6-9416-11ee-98e5-6d05b1d4d9a1 From: Penny Zheng To: xen-devel@lists.xenproject.org, michal.orzel@amd.com Cc: wei.chen@arm.com, Penny Zheng , Stefano Stabellini , Julien Grall , Bertrand Marquis , Volodymyr Babchuk , Penny Zheng Subject: [PATCH v5 04/11] xen/arm: introduce allocate_domheap_memory and guest_physmap_memory Date: Wed, 6 Dec 2023 17:06:16 +0800 Message-Id: <20231206090623.1932275-5-Penny.Zheng@arm.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20231206090623.1932275-1-Penny.Zheng@arm.com> References: <20231206090623.1932275-1-Penny.Zheng@arm.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ZM-MESSAGEID: 1701853641440100001 Content-Type: text/plain; charset="utf-8" We split the code of allocate_bank_memory into two parts, allocate_domheap_memory and guest_physmap_memory. One is about allocating guest RAM from heap, which could be re-used later f= or allocating static shared memory from heap when host address is not provided. The other is building up guest P2M mapping. We also define a set of MACRO helpers to access common fields in data structure of "meminfo" type, e.g. "struct meminfo" is one of them, and later new "struct shm_meminfo" is also one of them. This kind of structures must have the following characteristics: - an array of "struct membank" - a member called "nr_banks" indicating current array size - a field indicating the maximum array size When introducing a new data structure, according callbacks with function ty= pe "retrieve_fn" shall be defined for using MACRO helpers. This commit defines callback "retrieve_meminfo" for data structure "struct meminfo". Signed-off-by: Penny Zheng --- v1 -> v2: - define a set of MACRO helpers to access common fields in data structure = of "meminfo" type. "struct meminfo" is one of them, and according callback "retrieve_meminfo" is also introduced here. - typo of changing 1ULL to 1UL --- v2 -> v3 - rebase and no changes --- v3 -> v4: rebase and no change --- v4 -> v5: rebase and no change --- xen/arch/arm/domain_build.c | 119 +++++++++++++++++++++++++------ xen/arch/arm/include/asm/setup.h | 33 +++++++++ 2 files changed, 129 insertions(+), 23 deletions(-) diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c index 64ae944431..a8bc78baa5 100644 --- a/xen/arch/arm/domain_build.c +++ b/xen/arch/arm/domain_build.c @@ -51,6 +51,28 @@ boolean_param("ext_regions", opt_ext_regions); static u64 __initdata dom0_mem; static bool __initdata dom0_mem_set; =20 +#ifdef CONFIG_DOM0LESS_BOOT +static void __init retrieve_meminfo(void *mem, unsigned int *max_mem_banks, + struct membank **bank, + unsigned int **nr_banks) +{ + struct meminfo *meminfo =3D (struct meminfo *)mem; + + if ( max_mem_banks ) + *max_mem_banks =3D NR_MEM_BANKS; + + if ( nr_banks ) + *nr_banks =3D &(meminfo->nr_banks); + + if ( bank ) + *bank =3D meminfo->bank; +} + +retrieve_fn __initdata retrievers[MAX_MEMINFO_TYPE] =3D { + [NORMAL_MEMINFO] =3D retrieve_meminfo, +}; +#endif + static int __init parse_dom0_mem(const char *s) { dom0_mem_set =3D true; @@ -415,32 +437,20 @@ static void __init allocate_memory_11(struct domain *= d, } =20 #ifdef CONFIG_DOM0LESS_BOOT -bool __init allocate_bank_memory(struct domain *d, struct kernel_info *kin= fo, - gfn_t sgfn, paddr_t tot_size) +static bool __init allocate_domheap_memory(struct domain *d, + paddr_t tot_size, + void *mem, enum meminfo_type ty= pe) { - int res; struct page_info *pg; - struct membank *bank; unsigned int max_order =3D ~0; - - /* - * allocate_bank_memory can be called with a tot_size of zero for - * the second memory bank. It is not an error and we can safely - * avoid creating a zero-size memory bank. - */ - if ( tot_size =3D=3D 0 ) - return true; - - bank =3D &kinfo->mem.bank[kinfo->mem.nr_banks]; - bank->start =3D gfn_to_gaddr(sgfn); - bank->size =3D tot_size; + unsigned int *nr_banks =3D GET_NR_BANKS(mem, type); =20 while ( tot_size > 0 ) { unsigned int order =3D get_allocation_size(tot_size); + struct membank *membank; =20 order =3D min(max_order, order); - pg =3D alloc_domheap_pages(d, order, 0); if ( !pg ) { @@ -460,15 +470,78 @@ bool __init allocate_bank_memory(struct domain *d, st= ruct kernel_info *kinfo, continue; } =20 - res =3D guest_physmap_add_page(d, sgfn, page_to_mfn(pg), order); - if ( res ) - { - dprintk(XENLOG_ERR, "Failed map pages to DOMU: %d", res); + if ( *nr_banks =3D=3D MAX_MEM_BANKS(type) ) return false; - } + + membank =3D GET_MEMBANK(mem, type, *nr_banks); + membank->start =3D mfn_to_maddr(page_to_mfn(pg)); + membank->size =3D 1ULL << (PAGE_SHIFT + order); + (*nr_banks)++; + tot_size -=3D membank->size; + } + + return true; +} + +static int __init guest_physmap_memory(struct domain *d, + void *mem, enum meminfo_type type, + gfn_t sgfn) +{ + unsigned int i; + int res; + unsigned int *nr_banks =3D GET_NR_BANKS(mem, type); + + for ( i =3D 0; i < *nr_banks; i++ ) + { + struct membank *membank =3D GET_MEMBANK(mem, type, i); + paddr_t start =3D membank->start; + paddr_t size =3D membank->size; + unsigned int order =3D get_order_from_bytes(size); + + /* Size must be power of two */ + BUG_ON(!size || (size & (size - 1))); + res =3D guest_physmap_add_page(d, sgfn, maddr_to_mfn(start), order= ); + if ( res ) + return res; =20 sgfn =3D gfn_add(sgfn, 1UL << order); - tot_size -=3D (1ULL << (PAGE_SHIFT + order)); + } + + return 0; +} + +bool __init allocate_bank_memory(struct domain *d, + struct kernel_info *kinfo, + gfn_t sgfn, + paddr_t total_size) +{ + struct membank *bank; + struct meminfo host =3D { 0 }; + + /* + * allocate_bank_memory can be called with a total_size of zero for + * the second memory bank. It is not an error and we can safely + * avoid creating a zero-size memory bank. + */ + if ( total_size =3D=3D 0 ) + return true; + + bank =3D &kinfo->mem.bank[kinfo->mem.nr_banks]; + bank->start =3D gfn_to_gaddr(sgfn); + bank->size =3D total_size; + + if ( !allocate_domheap_memory(d, total_size, (void *)&host, NORMAL_MEM= INFO) ) + { + printk(XENLOG_ERR "Failed to allocate (%"PRIpaddr"MB) pages to %pd= \n", + total_size >> 20, d); + return false; + } + + if ( guest_physmap_memory(d, (void *)&host, NORMAL_MEMINFO, sgfn) ) + { + printk(XENLOG_ERR "Failed to map (%"PRIpaddr"MB) pages to %pd\n", + total_size >> 20, d); + return false; } =20 kinfo->mem.nr_banks++; diff --git a/xen/arch/arm/include/asm/setup.h b/xen/arch/arm/include/asm/se= tup.h index 3a2b35ea46..bc5f08be97 100644 --- a/xen/arch/arm/include/asm/setup.h +++ b/xen/arch/arm/include/asm/setup.h @@ -57,6 +57,39 @@ struct meminfo { struct membank bank[NR_MEM_BANKS]; }; =20 +enum meminfo_type { + NORMAL_MEMINFO, + MAX_MEMINFO_TYPE, +}; + +/* + * Define a set of MACRO helpers to access meminfo_type, like "struct memi= nfo" + * as type of NORMAL_MEMINFO, etc. + * This kind of structure must have a array of "struct membank", + * a member called nr_banks indicating the current array size, and also a = field + * indicating the maximum array size. + */ +typedef void (*retrieve_fn)(void *, unsigned int *, struct membank **, + unsigned int **); + +#define MAX_MEM_BANKS(type) ({ \ + unsigned int _max_mem_banks; \ + retrievers[type](NULL, &_max_mem_banks, NULL, NULL); \ + _max_mem_banks; \ +}) + +#define GET_MEMBANK(mem, type, index) ({ \ + struct membank *_bank; \ + retrievers[type]((void *)(mem), NULL, &_bank, NULL); \ + &(_bank[index]); \ +}) + +#define GET_NR_BANKS(mem, type) ({ \ + unsigned int *_nr_banks; \ + retrievers[type]((void *)mem, NULL, NULL, &_nr_banks); \ + _nr_banks; \ +}) + /* * The domU flag is set for kernels and ramdisks of "xen,domain" nodes. * The purpose of the domU flag is to avoid getting confused in --=20 2.25.1