From nobody Sat May 18 14:54:07 2024 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 1666689713752712.7095393468256; Tue, 25 Oct 2022 02:21:53 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.429682.680829 (Exim 4.92) (envelope-from ) id 1onG7n-0004ru-GO; Tue, 25 Oct 2022 09:21:31 +0000 Received: by outflank-mailman (output) from mailman id 429682.680829; Tue, 25 Oct 2022 09:21:31 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1onG7n-0004rj-DQ; Tue, 25 Oct 2022 09:21:31 +0000 Received: by outflank-mailman (input) for mailman id 429682; Tue, 25 Oct 2022 09:21:30 +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 1onG7m-0004qz-PD for xen-devel@lists.xenproject.org; Tue, 25 Oct 2022 09:21:30 +0000 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by se1-gles-flk1.inumbo.com (Halon) with ESMTP id 66dcda20-5446-11ed-8fd0-01056ac49cbb; Tue, 25 Oct 2022 11:21:27 +0200 (CEST) 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 45ED6D6E; Tue, 25 Oct 2022 02:21:35 -0700 (PDT) Received: from entos-skylake.shanghai.arm.com (entos-skylake.shanghai.arm.com [10.169.212.207]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id E9DD23F792; Tue, 25 Oct 2022 02:21:26 -0700 (PDT) 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: 66dcda20-5446-11ed-8fd0-01056ac49cbb From: Henry Wang To: xen-devel@lists.xenproject.org Cc: Andrew Cooper , Stefano Stabellini , Julien Grall , Bertrand Marquis , Volodymyr Babchuk Subject: [PATCH for-4.14-to-4.16 1/2] arm/p2m: Rework p2m_init() Date: Tue, 25 Oct 2022 09:21:11 +0000 Message-Id: <20221025092112.50168-2-Henry.Wang@arm.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20221025092112.50168-1-Henry.Wang@arm.com> References: <20221025092112.50168-1-Henry.Wang@arm.com> X-ZM-MESSAGEID: 1666689715013100001 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" From: Andrew Cooper p2m_init() is mostly trivial initialisation, but has two fallible operations which are on either side of the backpointer trigger for teardown to take actions. p2m_free_vmid() is idempotent with a failed p2m_alloc_vmid(), so rearrange p2m_init() to perform all trivial setup, then set the backpointer, then perform all fallible setup. This will simplify a future bugfix which needs to add a third fallible operation. No practical change. Signed-off-by: Andrew Cooper Reviewed-by: Julien Grall Reviewed-by: Bertrand Marquis (cherry picked from commit: 3783e583319fa1ce75e414d851f0fde191a14753) --- xen/arch/arm/p2m.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/xen/arch/arm/p2m.c b/xen/arch/arm/p2m.c index 13b06c0fe4..2642d2748c 100644 --- a/xen/arch/arm/p2m.c +++ b/xen/arch/arm/p2m.c @@ -1699,7 +1699,7 @@ void p2m_final_teardown(struct domain *d) int p2m_init(struct domain *d) { struct p2m_domain *p2m =3D p2m_get_hostp2m(d); - int rc =3D 0; + int rc; unsigned int cpu; =20 rwlock_init(&p2m->lock); @@ -1708,11 +1708,6 @@ int p2m_init(struct domain *d) INIT_PAGE_LIST_HEAD(&d->arch.paging.p2m_freelist); =20 p2m->vmid =3D INVALID_VMID; - - rc =3D p2m_alloc_vmid(d); - if ( rc !=3D 0 ) - return rc; - p2m->max_mapped_gfn =3D _gfn(0); p2m->lowest_mapped_gfn =3D _gfn(ULONG_MAX); =20 @@ -1728,8 +1723,6 @@ int p2m_init(struct domain *d) p2m->clean_pte =3D is_iommu_enabled(d) && !iommu_has_feature(d, IOMMU_FEAT_COHERENT_WALK); =20 - rc =3D p2m_alloc_table(d); - /* * Make sure that the type chosen to is able to store the an vCPU ID * between 0 and the maximum of virtual CPUS supported as long as @@ -1742,13 +1735,20 @@ int p2m_init(struct domain *d) p2m->last_vcpu_ran[cpu] =3D INVALID_VCPU_ID; =20 /* - * Besides getting a domain when we only have the p2m in hand, - * the back pointer to domain is also used in p2m_teardown() - * as an end-of-initialization indicator. + * "Trivial" initialisation is now complete. Set the backpointer so + * p2m_teardown() and friends know to do something. */ p2m->domain =3D d; =20 - return rc; + rc =3D p2m_alloc_vmid(d); + if ( rc ) + return rc; + + rc =3D p2m_alloc_table(d); + if ( rc ) + return rc; + + return 0; } =20 /* --=20 2.17.1 From nobody Sat May 18 14:54:07 2024 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 1666689714882473.00872008907754; Tue, 25 Oct 2022 02:21:54 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.429683.680840 (Exim 4.92) (envelope-from ) id 1onG7r-0005Bd-Q6; Tue, 25 Oct 2022 09:21:35 +0000 Received: by outflank-mailman (output) from mailman id 429683.680840; Tue, 25 Oct 2022 09:21:35 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1onG7r-0005BU-N8; Tue, 25 Oct 2022 09:21:35 +0000 Received: by outflank-mailman (input) for mailman id 429683; Tue, 25 Oct 2022 09:21:34 +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 1onG7q-0004ZS-2G for xen-devel@lists.xenproject.org; Tue, 25 Oct 2022 09:21:34 +0000 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by se1-gles-sth1.inumbo.com (Halon) with ESMTP id 6a4f42fc-5446-11ed-91b5-6bf2151ebd3b; Tue, 25 Oct 2022 11:21:32 +0200 (CEST) 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 8A7DFD6E; Tue, 25 Oct 2022 02:21:38 -0700 (PDT) Received: from entos-skylake.shanghai.arm.com (entos-skylake.shanghai.arm.com [10.169.212.207]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 3CBD13F792; Tue, 25 Oct 2022 02:21:29 -0700 (PDT) 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: 6a4f42fc-5446-11ed-91b5-6bf2151ebd3b From: Henry Wang To: xen-devel@lists.xenproject.org Cc: Henry Wang , Stefano Stabellini , Julien Grall , Bertrand Marquis , Volodymyr Babchuk Subject: [PATCH for-4.14-to-4.16 2/2] xen/arm: p2m: Populate pages for GICv2 mapping in p2m_init() Date: Tue, 25 Oct 2022 09:21:12 +0000 Message-Id: <20221025092112.50168-3-Henry.Wang@arm.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20221025092112.50168-1-Henry.Wang@arm.com> References: <20221025092112.50168-1-Henry.Wang@arm.com> X-ZM-MESSAGEID: 1666689716979100003 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Hardware using GICv2 needs to create a P2M mapping of 8KB GICv2 area when the domain is created. Considering the worst case of page tables which requires 6 P2M pages as the two pages will be consecutive but not necessarily in the same L3 page table and keep a buffer, populate 16 pages as the default value to the P2M pages pool in p2m_init() at the domain creation stage to satisfy the GICv2 requirement. For GICv3, the above-mentioned P2M mapping is not necessary, but since the allocated 16 pages here would not be lost, hence populate these pages unconditionally. With the default 16 P2M pages populated, there would be a case that failures would happen in the domain creation with P2M pages already in use. To properly free the P2M for this case, firstly support the optionally preemption of p2m_teardown(), then call p2m_teardown() and p2m_set_allocation(d, 0, NULL) non-preemptively in p2m_final_teardown(). As non-preemptive p2m_teardown() should only return 0, use a BUG_ON to confirm that. Since p2m_final_teardown() is called either after domain_relinquish_resources() where relinquish_p2m_mapping() has been called, or from failure path of domain_create()/arch_domain_create() where mappings that require p2m_put_l3_page() should never be created, relinquish_p2m_mapping() is not added in p2m_final_teardown(), add in-code comments to refer this. Fixes: cbea5a1149ca ("xen/arm: Allocate and free P2M pages from the P2M poo= l") Suggested-by: Julien Grall Signed-off-by: Henry Wang Reviewed-by: Julien Grall Reviewed-by: Bertrand Marquis (cherry picked from commit: c7cff1188802646eaa38e918e5738da0e84949be) --- xen/arch/arm/domain.c | 2 +- xen/arch/arm/p2m.c | 34 ++++++++++++++++++++++++++++++++-- xen/include/asm-arm/p2m.h | 14 ++++++++++---- 3 files changed, 43 insertions(+), 7 deletions(-) diff --git a/xen/arch/arm/domain.c b/xen/arch/arm/domain.c index aae615f7d6..0fa1c0cb80 100644 --- a/xen/arch/arm/domain.c +++ b/xen/arch/arm/domain.c @@ -1032,7 +1032,7 @@ int domain_relinquish_resources(struct domain *d) return ret; =20 PROGRESS(p2m): - ret =3D p2m_teardown(d); + ret =3D p2m_teardown(d, true); if ( ret ) return ret; =20 diff --git a/xen/arch/arm/p2m.c b/xen/arch/arm/p2m.c index 2642d2748c..3eb6f16b30 100644 --- a/xen/arch/arm/p2m.c +++ b/xen/arch/arm/p2m.c @@ -1630,7 +1630,7 @@ static void p2m_free_vmid(struct domain *d) spin_unlock(&vmid_alloc_lock); } =20 -int p2m_teardown(struct domain *d) +int p2m_teardown(struct domain *d, bool allow_preemption) { struct p2m_domain *p2m =3D p2m_get_hostp2m(d); unsigned long count =3D 0; @@ -1638,6 +1638,9 @@ int p2m_teardown(struct domain *d) unsigned int i; int rc =3D 0; =20 + if ( page_list_empty(&p2m->pages) ) + return 0; + p2m_write_lock(p2m); =20 /* @@ -1661,7 +1664,7 @@ int p2m_teardown(struct domain *d) p2m_free_page(p2m->domain, pg); count++; /* Arbitrarily preempt every 512 iterations */ - if ( !(count % 512) && hypercall_preempt_check() ) + if ( allow_preemption && !(count % 512) && hypercall_preempt_check= () ) { rc =3D -ERESTART; break; @@ -1681,7 +1684,20 @@ void p2m_final_teardown(struct domain *d) if ( !p2m->domain ) return; =20 + /* + * No need to call relinquish_p2m_mapping() here because + * p2m_final_teardown() is called either after domain_relinquish_resou= rces() + * where relinquish_p2m_mapping() has been called, or from failure pat= h of + * domain_create()/arch_domain_create() where mappings that require + * p2m_put_l3_page() should never be created. For the latter case, als= o see + * comment on top of the p2m_set_entry() for more info. + */ + + BUG_ON(p2m_teardown(d, false)); ASSERT(page_list_empty(&p2m->pages)); + + while ( p2m_teardown_allocation(d) =3D=3D -ERESTART ) + continue; /* No preemption support here */ ASSERT(page_list_empty(&d->arch.paging.p2m_freelist)); =20 if ( p2m->root ) @@ -1748,6 +1764,20 @@ int p2m_init(struct domain *d) if ( rc ) return rc; =20 + /* + * Hardware using GICv2 needs to create a P2M mapping of 8KB GICv2 area + * when the domain is created. Considering the worst case for page + * tables and keep a buffer, populate 16 pages to the P2M pages pool h= ere. + * For GICv3, the above-mentioned P2M mapping is not necessary, but si= nce + * the allocated 16 pages here would not be lost, hence populate these + * pages unconditionally. + */ + spin_lock(&d->arch.paging.lock); + rc =3D p2m_set_allocation(d, 16, NULL); + spin_unlock(&d->arch.paging.lock); + if ( rc ) + return rc; + return 0; } =20 diff --git a/xen/include/asm-arm/p2m.h b/xen/include/asm-arm/p2m.h index b733f55d48..ac4edb95ce 100644 --- a/xen/include/asm-arm/p2m.h +++ b/xen/include/asm-arm/p2m.h @@ -185,14 +185,18 @@ int p2m_init(struct domain *d); =20 /* * The P2M resources are freed in two parts: - * - p2m_teardown() will be called when relinquish the resources. It - * will free large resources (e.g. intermediate page-tables) that - * requires preemption. + * - p2m_teardown() will be called preemptively when relinquish the + * resources, in which case it will free large resources (e.g. intermed= iate + * page-tables) that requires preemption. * - p2m_final_teardown() will be called when domain struct is been * freed. This *cannot* be preempted and therefore one small * resources should be freed here. + * Note that p2m_final_teardown() will also call p2m_teardown(), to prope= rly + * free the P2M when failures happen in the domain creation with P2M pages + * already in use. In this case p2m_teardown() is called non-preemptively= and + * p2m_teardown() will always return 0. */ -int p2m_teardown(struct domain *d); +int p2m_teardown(struct domain *d, bool allow_preemption); void p2m_final_teardown(struct domain *d); =20 /* @@ -257,6 +261,8 @@ mfn_t p2m_get_entry(struct p2m_domain *p2m, gfn_t gfn, /* * Direct set a p2m entry: only for use by the P2M code. * The P2M write lock should be taken. + * TODO: Add a check in __p2m_set_entry() to avoid creating a mapping in + * arch_domain_create() that requires p2m_put_l3_page() to be called. */ int p2m_set_entry(struct p2m_domain *p2m, gfn_t sgfn, --=20 2.17.1