From patchwork Tue Mar 28 07:13:31 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Henry Wang X-Patchwork-Id: 13190606 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id E0006C76195 for ; Tue, 28 Mar 2023 07:14:10 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.515549.798538 (Exim 4.92) (envelope-from ) id 1ph3Wu-0001oe-7i; Tue, 28 Mar 2023 07:14:04 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 515549.798538; Tue, 28 Mar 2023 07:14:04 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1ph3Wu-0001oV-43; Tue, 28 Mar 2023 07:14:04 +0000 Received: by outflank-mailman (input) for mailman id 515549; Tue, 28 Mar 2023 07:14:02 +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 1ph3Ws-0001nm-Kh for xen-devel@lists.xenproject.org; Tue, 28 Mar 2023 07:14:02 +0000 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by se1-gles-sth1.inumbo.com (Halon) with ESMTP id 1c47d8be-cd38-11ed-85db-49a42c6b2330; Tue, 28 Mar 2023 09:14:01 +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 42A54C14; Tue, 28 Mar 2023 00:14:43 -0700 (PDT) Received: from a015966.shanghai.arm.com (a015966.shanghai.arm.com [10.169.190.5]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 904453F73F; Tue, 28 Mar 2023 00:13:55 -0700 (PDT) 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: 1c47d8be-cd38-11ed-85db-49a42c6b2330 From: Henry Wang To: xen-devel@lists.xenproject.org Cc: Henry Wang , Stefano Stabellini , Julien Grall , Bertrand Marquis , Wei Chen , Volodymyr Babchuk , Michal Orzel , Julien Grall Subject: [PATCH v3 1/4] xen/arm: Reduce redundant clear root pages when teardown p2m Date: Tue, 28 Mar 2023 15:13:31 +0800 Message-Id: <20230328071334.2098429-2-Henry.Wang@arm.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230328071334.2098429-1-Henry.Wang@arm.com> References: <20230328071334.2098429-1-Henry.Wang@arm.com> MIME-Version: 1.0 Currently, p2m for a domain will be teardown from two paths: (1) The normal path when a domain is destroyed. (2) The arch_domain_destroy() in the failure path of domain creation. When tearing down p2m from (1), the part to clear and clean the root is only needed to do once rather than for every call of p2m_teardown(). If the p2m teardown is from (2), the clear and clean of the root is unnecessary because the domain is not scheduled. Therefore, this patch introduces a helper `p2m_clear_root_pages()` to do the clear and clean of the root, and move this logic outside of p2m_teardown(). With this movement, the `page_list_empty(&p2m->pages)` check can be dropped. Signed-off-by: Henry Wang Reviewed-by: Michal Orzel Acked-by: Julien Grall --- v2 -> v3: 1. No change. v1 -> v2: 1. Move in-code comment for p2m_force_tlb_flush_sync() on top of p2m_clear_root_pages(). 2. Add Reviewed-by tag from Michal and Acked-by tag from Julien. --- xen/arch/arm/domain.c | 8 +++++++ xen/arch/arm/include/asm/p2m.h | 1 + xen/arch/arm/p2m.c | 40 +++++++++++++++++----------------- 3 files changed, 29 insertions(+), 20 deletions(-) diff --git a/xen/arch/arm/domain.c b/xen/arch/arm/domain.c index 99577adb6c..b8a4a60570 100644 --- a/xen/arch/arm/domain.c +++ b/xen/arch/arm/domain.c @@ -959,6 +959,7 @@ enum { PROG_xen, PROG_page, PROG_mapping, + PROG_p2m_root, PROG_p2m, PROG_p2m_pool, PROG_done, @@ -1021,6 +1022,13 @@ int domain_relinquish_resources(struct domain *d) if ( ret ) return ret; + PROGRESS(p2m_root): + /* + * We are about to free the intermediate page-tables, so clear the + * root to prevent any walk to use them. + */ + p2m_clear_root_pages(&d->arch.p2m); + PROGRESS(p2m): ret = p2m_teardown(d, true); if ( ret ) diff --git a/xen/arch/arm/include/asm/p2m.h b/xen/arch/arm/include/asm/p2m.h index 91df922e1c..bf5183e53a 100644 --- a/xen/arch/arm/include/asm/p2m.h +++ b/xen/arch/arm/include/asm/p2m.h @@ -281,6 +281,7 @@ int p2m_set_entry(struct p2m_domain *p2m, bool p2m_resolve_translation_fault(struct domain *d, gfn_t gfn); +void p2m_clear_root_pages(struct p2m_domain *p2m); void p2m_invalidate_root(struct p2m_domain *p2m); /* diff --git a/xen/arch/arm/p2m.c b/xen/arch/arm/p2m.c index 948f199d84..f1ccd7efbd 100644 --- a/xen/arch/arm/p2m.c +++ b/xen/arch/arm/p2m.c @@ -1314,6 +1314,26 @@ static void p2m_invalidate_table(struct p2m_domain *p2m, mfn_t mfn) p2m->need_flush = true; } +/* + * The domain will not be scheduled anymore, so in theory we should + * not need to flush the TLBs. Do it for safety purpose. + * Note that all the devices have already been de-assigned. So we don't + * need to flush the IOMMU TLB here. + */ +void p2m_clear_root_pages(struct p2m_domain *p2m) +{ + unsigned int i; + + p2m_write_lock(p2m); + + for ( i = 0; i < P2M_ROOT_PAGES; i++ ) + clear_and_clean_page(p2m->root + i); + + p2m_force_tlb_flush_sync(p2m); + + p2m_write_unlock(p2m); +} + /* * Invalidate all entries in the root page-tables. This is * useful to get fault on entry and do an action. @@ -1698,30 +1718,10 @@ int p2m_teardown(struct domain *d, bool allow_preemption) struct p2m_domain *p2m = p2m_get_hostp2m(d); unsigned long count = 0; struct page_info *pg; - unsigned int i; int rc = 0; - if ( page_list_empty(&p2m->pages) ) - return 0; - p2m_write_lock(p2m); - /* - * We are about to free the intermediate page-tables, so clear the - * root to prevent any walk to use them. - */ - for ( i = 0; i < P2M_ROOT_PAGES; i++ ) - clear_and_clean_page(p2m->root + i); - - /* - * The domain will not be scheduled anymore, so in theory we should - * not need to flush the TLBs. Do it for safety purpose. - * - * Note that all the devices have already been de-assigned. So we don't - * need to flush the IOMMU TLB here. - */ - p2m_force_tlb_flush_sync(p2m); - while ( (pg = page_list_remove_head(&p2m->pages)) ) { p2m_free_page(p2m->domain, pg); From patchwork Tue Mar 28 07:13:32 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Henry Wang X-Patchwork-Id: 13190607 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 25314C76196 for ; Tue, 28 Mar 2023 07:14:18 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.515550.798548 (Exim 4.92) (envelope-from ) id 1ph3Wy-00026Z-HA; Tue, 28 Mar 2023 07:14:08 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 515550.798548; Tue, 28 Mar 2023 07:14:08 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1ph3Wy-00026Q-EF; Tue, 28 Mar 2023 07:14:08 +0000 Received: by outflank-mailman (input) for mailman id 515550; Tue, 28 Mar 2023 07:14:06 +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 1ph3Ww-0001We-O8 for xen-devel@lists.xenproject.org; Tue, 28 Mar 2023 07:14:06 +0000 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by se1-gles-flk1.inumbo.com (Halon) with ESMTP id 1f4f535e-cd38-11ed-b464-930f4c7d94ae; Tue, 28 Mar 2023 09:14:04 +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 6B702C14; Tue, 28 Mar 2023 00:14:48 -0700 (PDT) Received: from a015966.shanghai.arm.com (a015966.shanghai.arm.com [10.169.190.5]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 7D6E73F73F; Tue, 28 Mar 2023 00:14:01 -0700 (PDT) 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: 1f4f535e-cd38-11ed-b464-930f4c7d94ae From: Henry Wang To: xen-devel@lists.xenproject.org Cc: Henry Wang , Stefano Stabellini , Julien Grall , Bertrand Marquis , Wei Chen , Volodymyr Babchuk , Julien Grall Subject: [PATCH v3 2/4] xen/arm: Rename vgic_cpu_base and vgic_dist_base for new vGIC Date: Tue, 28 Mar 2023 15:13:32 +0800 Message-Id: <20230328071334.2098429-3-Henry.Wang@arm.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230328071334.2098429-1-Henry.Wang@arm.com> References: <20230328071334.2098429-1-Henry.Wang@arm.com> MIME-Version: 1.0 In the follow-up patch from this series, the GICv2 CPU interface mapping will be deferred until the first access in the stage-2 data abort trap handling code. Since the data abort trap handling code is common for the current and the new vGIC implementation, it is necessary to unify the variable names in struct vgic_dist for these two implementations. Therefore, this commit renames the vgic_cpu_base and vgic_dist_base for new vGIC to cbase and dbase. So we can use the same code in the data abort trap handling code for both vGIC implementations. Signed-off-by: Henry Wang Acked-by: Julien Grall --- v2 -> v3: 1. Add Julien's acked-by tag. v1 -> v2: 1. New patch. --- xen/arch/arm/include/asm/new_vgic.h | 8 ++++---- xen/arch/arm/vgic/vgic-init.c | 4 ++-- xen/arch/arm/vgic/vgic-v2.c | 17 ++++++++--------- 3 files changed, 14 insertions(+), 15 deletions(-) diff --git a/xen/arch/arm/include/asm/new_vgic.h b/xen/arch/arm/include/asm/new_vgic.h index b7fa9ab11a..18ed3f754a 100644 --- a/xen/arch/arm/include/asm/new_vgic.h +++ b/xen/arch/arm/include/asm/new_vgic.h @@ -115,11 +115,11 @@ struct vgic_dist { unsigned int nr_spis; /* base addresses in guest physical address space: */ - paddr_t vgic_dist_base; /* distributor */ + paddr_t dbase; /* distributor */ union { /* either a GICv2 CPU interface */ - paddr_t vgic_cpu_base; + paddr_t cbase; /* or a number of GICv3 redistributor regions */ struct { @@ -188,12 +188,12 @@ struct vgic_cpu { static inline paddr_t vgic_cpu_base(const struct vgic_dist *vgic) { - return vgic->vgic_cpu_base; + return vgic->cbase; } static inline paddr_t vgic_dist_base(const struct vgic_dist *vgic) { - return vgic->vgic_dist_base; + return vgic->dbase; } #endif /* __ASM_ARM_NEW_VGIC_H */ diff --git a/xen/arch/arm/vgic/vgic-init.c b/xen/arch/arm/vgic/vgic-init.c index 62ae553699..ea739d081e 100644 --- a/xen/arch/arm/vgic/vgic-init.c +++ b/xen/arch/arm/vgic/vgic-init.c @@ -112,8 +112,8 @@ int domain_vgic_register(struct domain *d, int *mmio_count) BUG(); } - d->arch.vgic.vgic_dist_base = VGIC_ADDR_UNDEF; - d->arch.vgic.vgic_cpu_base = VGIC_ADDR_UNDEF; + d->arch.vgic.dbase = VGIC_ADDR_UNDEF; + d->arch.vgic.cbase = VGIC_ADDR_UNDEF; d->arch.vgic.vgic_redist_base = VGIC_ADDR_UNDEF; return 0; diff --git a/xen/arch/arm/vgic/vgic-v2.c b/xen/arch/arm/vgic/vgic-v2.c index 1a99d3a8b4..07c8f8a005 100644 --- a/xen/arch/arm/vgic/vgic-v2.c +++ b/xen/arch/arm/vgic/vgic-v2.c @@ -272,7 +272,7 @@ int vgic_v2_map_resources(struct domain *d) */ if ( is_hardware_domain(d) ) { - d->arch.vgic.vgic_dist_base = gic_v2_hw_data.dbase; + d->arch.vgic.dbase = gic_v2_hw_data.dbase; /* * For the hardware domain, we always map the whole HW CPU * interface region in order to match the device tree (the "reg" @@ -280,13 +280,13 @@ int vgic_v2_map_resources(struct domain *d) * Note that we assume the size of the CPU interface is always * aligned to PAGE_SIZE. */ - d->arch.vgic.vgic_cpu_base = gic_v2_hw_data.cbase; + d->arch.vgic.cbase = gic_v2_hw_data.cbase; csize = gic_v2_hw_data.csize; vbase = gic_v2_hw_data.vbase; } else if ( is_domain_direct_mapped(d) ) { - d->arch.vgic.vgic_dist_base = gic_v2_hw_data.dbase; + d->arch.vgic.dbase = gic_v2_hw_data.dbase; /* * For all the direct-mapped domain other than the hardware domain, * we only map a 8kB CPU interface but we make sure it is at a location @@ -296,13 +296,13 @@ int vgic_v2_map_resources(struct domain *d) * address when the GIC is aliased to get a 8kB contiguous * region. */ - d->arch.vgic.vgic_cpu_base = gic_v2_hw_data.cbase; + d->arch.vgic.cbase = gic_v2_hw_data.cbase; csize = GUEST_GICC_SIZE; vbase = gic_v2_hw_data.vbase + gic_v2_hw_data.aliased_offset; } else { - d->arch.vgic.vgic_dist_base = GUEST_GICD_BASE; + d->arch.vgic.dbase = GUEST_GICD_BASE; /* * The CPU interface exposed to the guest is always 8kB. We may * need to add an offset to the virtual CPU interface base @@ -310,14 +310,13 @@ int vgic_v2_map_resources(struct domain *d) * region. */ BUILD_BUG_ON(GUEST_GICC_SIZE != SZ_8K); - d->arch.vgic.vgic_cpu_base = GUEST_GICC_BASE; + d->arch.vgic.cbase = GUEST_GICC_BASE; csize = GUEST_GICC_SIZE; vbase = gic_v2_hw_data.vbase + gic_v2_hw_data.aliased_offset; } - ret = vgic_register_dist_iodev(d, gaddr_to_gfn(dist->vgic_dist_base), - VGIC_V2); + ret = vgic_register_dist_iodev(d, gaddr_to_gfn(dist->dbase), VGIC_V2); if ( ret ) { gdprintk(XENLOG_ERR, "Unable to register VGIC MMIO regions\n"); @@ -328,7 +327,7 @@ int vgic_v2_map_resources(struct domain *d) * Map the gic virtual cpu interface in the gic cpu interface * region of the guest. */ - ret = map_mmio_regions(d, gaddr_to_gfn(d->arch.vgic.vgic_cpu_base), + ret = map_mmio_regions(d, gaddr_to_gfn(d->arch.vgic.cbase), csize / PAGE_SIZE, maddr_to_mfn(vbase)); if ( ret ) { From patchwork Tue Mar 28 07:13:33 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Henry Wang X-Patchwork-Id: 13190608 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id DC11CC76195 for ; Tue, 28 Mar 2023 07:14:20 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.515552.798557 (Exim 4.92) (envelope-from ) id 1ph3X3-0002UY-Oi; Tue, 28 Mar 2023 07:14:13 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 515552.798557; Tue, 28 Mar 2023 07:14:13 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1ph3X3-0002UR-Lo; Tue, 28 Mar 2023 07:14:13 +0000 Received: by outflank-mailman (input) for mailman id 515552; Tue, 28 Mar 2023 07:14:11 +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 1ph3X1-0001We-Gw for xen-devel@lists.xenproject.org; Tue, 28 Mar 2023 07:14:11 +0000 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by se1-gles-flk1.inumbo.com (Halon) with ESMTP id 2203c1f5-cd38-11ed-b464-930f4c7d94ae; Tue, 28 Mar 2023 09:14:09 +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 F03A7C14; Tue, 28 Mar 2023 00:14:52 -0700 (PDT) Received: from a015966.shanghai.arm.com (a015966.shanghai.arm.com [10.169.190.5]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 4FE413F73F; Tue, 28 Mar 2023 00:14:06 -0700 (PDT) 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: 2203c1f5-cd38-11ed-b464-930f4c7d94ae From: Henry Wang To: xen-devel@lists.xenproject.org Cc: Henry Wang , Stefano Stabellini , Julien Grall , Bertrand Marquis , Wei Chen , Volodymyr Babchuk Subject: [PATCH v3 3/4] xen/arm: Defer GICv2 CPU interface mapping until the first access Date: Tue, 28 Mar 2023 15:13:33 +0800 Message-Id: <20230328071334.2098429-4-Henry.Wang@arm.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230328071334.2098429-1-Henry.Wang@arm.com> References: <20230328071334.2098429-1-Henry.Wang@arm.com> MIME-Version: 1.0 Currently, the mapping of the GICv2 CPU interface is created in arch_domain_create(). This causes some troubles in populating and freeing of the domain P2M pages pool. For example, a default 16 P2M pages are required in p2m_init() to cope with the P2M mapping of 8KB GICv2 CPU interface area, and these 16 P2M pages would cause the complexity of P2M destroy in the failure path of arch_domain_create(). As per discussion in [1], similarly as the MMIO access for ACPI, this patch defers the GICv2 CPU interface mapping until the first MMIO access. This is achieved by moving the GICv2 CPU interface mapping code from vgic_v2_domain_init()/vgic_v2_map_resources() to the stage-2 data abort trap handling code. The original CPU interface size and virtual CPU interface base address is now saved in `struct vgic_dist` instead of the local variable of vgic_v2_domain_init()/vgic_v2_map_resources(). Take the opportunity to unify the way of data access using the existing pointer to struct vgic_dist in vgic_v2_map_resources() for new GICv2. Since gicv2_map_hwdom_extra_mappings() happens after domain_create(), so there is no need to map the extra mappings on-demand, and therefore keep the hwdom extra mappings as untouched. [1] https://lore.kernel.org/xen-devel/e6643bfc-5bdf-f685-1b68-b28d341071c1@xen.org/ Signed-off-by: Henry Wang Reviewed-by: Julien Grall --- v2 -> v3: 1. Reword the reason why hwdom extra mappings are not touched by this patch in the commit message. 2. Rework the address check in stage-2 data abort trap so that larger CPU interface size can work fine. v1 -> v2: 1. Correct style in in-code comment. 2. Avoid open-coding gfn_eq() and gaddr_to_gfn(d->arch.vgic.cbase). 3. Apply same changes for the new vGICv2 implementation, update the commit message accordingly. 4. Add in-code comment in old GICv2's vgic_v2_domain_init() and new GICv2's vgic_v2_map_resources() to mention the mapping of the virtual CPU interface is deferred until first access. --- xen/arch/arm/include/asm/new_vgic.h | 2 ++ xen/arch/arm/include/asm/vgic.h | 2 ++ xen/arch/arm/traps.c | 19 ++++++++++++--- xen/arch/arm/vgic-v2.c | 25 ++++++------------- xen/arch/arm/vgic/vgic-v2.c | 38 ++++++++++------------------- 5 files changed, 40 insertions(+), 46 deletions(-) diff --git a/xen/arch/arm/include/asm/new_vgic.h b/xen/arch/arm/include/asm/new_vgic.h index 18ed3f754a..1e76213893 100644 --- a/xen/arch/arm/include/asm/new_vgic.h +++ b/xen/arch/arm/include/asm/new_vgic.h @@ -127,6 +127,8 @@ struct vgic_dist { paddr_t vgic_redist_free_offset; }; }; + paddr_t csize; /* CPU interface size */ + paddr_t vbase; /* virtual CPU interface base address */ /* distributor enabled */ bool enabled; diff --git a/xen/arch/arm/include/asm/vgic.h b/xen/arch/arm/include/asm/vgic.h index 3d44868039..328fd46d1b 100644 --- a/xen/arch/arm/include/asm/vgic.h +++ b/xen/arch/arm/include/asm/vgic.h @@ -153,6 +153,8 @@ struct vgic_dist { /* Base address for guest GIC */ paddr_t dbase; /* Distributor base address */ paddr_t cbase; /* CPU interface base address */ + paddr_t csize; /* CPU interface size */ + paddr_t vbase; /* Virtual CPU interface base address */ #ifdef CONFIG_GICV3 /* GIC V3 addressing */ /* List of contiguous occupied by the redistributors */ diff --git a/xen/arch/arm/traps.c b/xen/arch/arm/traps.c index 061c92acbd..d40c331a4e 100644 --- a/xen/arch/arm/traps.c +++ b/xen/arch/arm/traps.c @@ -1787,9 +1787,12 @@ static inline bool hpfar_is_valid(bool s1ptw, uint8_t fsc) } /* - * When using ACPI, most of the MMIO regions will be mapped on-demand - * in stage-2 page tables for the hardware domain because Xen is not - * able to know from the EFI memory map the MMIO regions. + * Try to map the MMIO regions for some special cases: + * 1. When using ACPI, most of the MMIO regions will be mapped on-demand + * in stage-2 page tables for the hardware domain because Xen is not + * able to know from the EFI memory map the MMIO regions. + * 2. For guests using GICv2, the GICv2 CPU interface mapping is created + * on the first access of the MMIO region. */ static bool try_map_mmio(gfn_t gfn) { @@ -1798,6 +1801,16 @@ static bool try_map_mmio(gfn_t gfn) /* For the hardware domain, all MMIOs are mapped with GFN == MFN */ mfn_t mfn = _mfn(gfn_x(gfn)); + /* + * Map the GICv2 virtual CPU interface in the GIC CPU interface + * region of the guest on the first access of the MMIO region. + */ + if ( d->arch.vgic.version == GIC_V2 && + gfn_to_gaddr(gfn) >= d->arch.vgic.cbase && + (gfn_to_gaddr(gfn) - d->arch.vgic.cbase) < d->arch.vgic.csize ) + return !map_mmio_regions(d, gfn, d->arch.vgic.csize / PAGE_SIZE, + maddr_to_mfn(d->arch.vgic.vbase)); + /* * Device-Tree should already have everything mapped when building * the hardware domain. diff --git a/xen/arch/arm/vgic-v2.c b/xen/arch/arm/vgic-v2.c index 0026cb4360..0b083c33e6 100644 --- a/xen/arch/arm/vgic-v2.c +++ b/xen/arch/arm/vgic-v2.c @@ -644,10 +644,6 @@ static int vgic_v2_vcpu_init(struct vcpu *v) static int vgic_v2_domain_init(struct domain *d) { - int ret; - paddr_t csize; - paddr_t vbase; - /* * The hardware domain and direct-mapped domain both get the hardware * address. @@ -667,8 +663,8 @@ static int vgic_v2_domain_init(struct domain *d) * aligned to PAGE_SIZE. */ d->arch.vgic.cbase = vgic_v2_hw.cbase; - csize = vgic_v2_hw.csize; - vbase = vgic_v2_hw.vbase; + d->arch.vgic.csize = vgic_v2_hw.csize; + d->arch.vgic.vbase = vgic_v2_hw.vbase; } else if ( is_domain_direct_mapped(d) ) { @@ -683,8 +679,8 @@ static int vgic_v2_domain_init(struct domain *d) */ d->arch.vgic.dbase = vgic_v2_hw.dbase; d->arch.vgic.cbase = vgic_v2_hw.cbase; - csize = GUEST_GICC_SIZE; - vbase = vgic_v2_hw.vbase + vgic_v2_hw.aliased_offset; + d->arch.vgic.csize = GUEST_GICC_SIZE; + d->arch.vgic.vbase = vgic_v2_hw.vbase + vgic_v2_hw.aliased_offset; } else { @@ -697,18 +693,11 @@ static int vgic_v2_domain_init(struct domain *d) */ BUILD_BUG_ON(GUEST_GICC_SIZE != SZ_8K); d->arch.vgic.cbase = GUEST_GICC_BASE; - csize = GUEST_GICC_SIZE; - vbase = vgic_v2_hw.vbase + vgic_v2_hw.aliased_offset; + d->arch.vgic.csize = GUEST_GICC_SIZE; + d->arch.vgic.vbase = vgic_v2_hw.vbase + vgic_v2_hw.aliased_offset; } - /* - * Map the gic virtual cpu interface in the gic cpu interface - * region of the guest. - */ - ret = map_mmio_regions(d, gaddr_to_gfn(d->arch.vgic.cbase), - csize / PAGE_SIZE, maddr_to_mfn(vbase)); - if ( ret ) - return ret; + /* Mapping of the virtual CPU interface is deferred until first access */ register_mmio_handler(d, &vgic_v2_distr_mmio_handler, d->arch.vgic.dbase, PAGE_SIZE, NULL); diff --git a/xen/arch/arm/vgic/vgic-v2.c b/xen/arch/arm/vgic/vgic-v2.c index 07c8f8a005..1308948eec 100644 --- a/xen/arch/arm/vgic/vgic-v2.c +++ b/xen/arch/arm/vgic/vgic-v2.c @@ -258,8 +258,6 @@ void vgic_v2_enable(struct vcpu *vcpu) int vgic_v2_map_resources(struct domain *d) { struct vgic_dist *dist = &d->arch.vgic; - paddr_t csize; - paddr_t vbase; int ret; /* @@ -272,7 +270,7 @@ int vgic_v2_map_resources(struct domain *d) */ if ( is_hardware_domain(d) ) { - d->arch.vgic.dbase = gic_v2_hw_data.dbase; + dist->dbase = gic_v2_hw_data.dbase; /* * For the hardware domain, we always map the whole HW CPU * interface region in order to match the device tree (the "reg" @@ -280,13 +278,13 @@ int vgic_v2_map_resources(struct domain *d) * Note that we assume the size of the CPU interface is always * aligned to PAGE_SIZE. */ - d->arch.vgic.cbase = gic_v2_hw_data.cbase; - csize = gic_v2_hw_data.csize; - vbase = gic_v2_hw_data.vbase; + dist->cbase = gic_v2_hw_data.cbase; + dist->csize = gic_v2_hw_data.csize; + dist->vbase = gic_v2_hw_data.vbase; } else if ( is_domain_direct_mapped(d) ) { - d->arch.vgic.dbase = gic_v2_hw_data.dbase; + dist->dbase = gic_v2_hw_data.dbase; /* * For all the direct-mapped domain other than the hardware domain, * we only map a 8kB CPU interface but we make sure it is at a location @@ -296,13 +294,13 @@ int vgic_v2_map_resources(struct domain *d) * address when the GIC is aliased to get a 8kB contiguous * region. */ - d->arch.vgic.cbase = gic_v2_hw_data.cbase; - csize = GUEST_GICC_SIZE; - vbase = gic_v2_hw_data.vbase + gic_v2_hw_data.aliased_offset; + dist->cbase = gic_v2_hw_data.cbase; + dist->csize = GUEST_GICC_SIZE; + dist->vbase = gic_v2_hw_data.vbase + gic_v2_hw_data.aliased_offset; } else { - d->arch.vgic.dbase = GUEST_GICD_BASE; + dist->dbase = GUEST_GICD_BASE; /* * The CPU interface exposed to the guest is always 8kB. We may * need to add an offset to the virtual CPU interface base @@ -310,9 +308,9 @@ int vgic_v2_map_resources(struct domain *d) * region. */ BUILD_BUG_ON(GUEST_GICC_SIZE != SZ_8K); - d->arch.vgic.cbase = GUEST_GICC_BASE; - csize = GUEST_GICC_SIZE; - vbase = gic_v2_hw_data.vbase + gic_v2_hw_data.aliased_offset; + dist->cbase = GUEST_GICC_BASE; + dist->csize = GUEST_GICC_SIZE; + dist->vbase = gic_v2_hw_data.vbase + gic_v2_hw_data.aliased_offset; } @@ -323,17 +321,7 @@ int vgic_v2_map_resources(struct domain *d) return ret; } - /* - * Map the gic virtual cpu interface in the gic cpu interface - * region of the guest. - */ - ret = map_mmio_regions(d, gaddr_to_gfn(d->arch.vgic.cbase), - csize / PAGE_SIZE, maddr_to_mfn(vbase)); - if ( ret ) - { - gdprintk(XENLOG_ERR, "Unable to remap VGIC CPU to VCPU\n"); - return ret; - } + /* Mapping of the virtual CPU interface is deferred until first access */ dist->ready = true; From patchwork Tue Mar 28 07:13:34 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Henry Wang X-Patchwork-Id: 13190609 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id F15F3C76195 for ; Tue, 28 Mar 2023 07:14:23 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.515555.798568 (Exim 4.92) (envelope-from ) id 1ph3X7-0002qg-7H; Tue, 28 Mar 2023 07:14:17 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 515555.798568; Tue, 28 Mar 2023 07:14:17 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1ph3X7-0002qX-3I; Tue, 28 Mar 2023 07:14:17 +0000 Received: by outflank-mailman (input) for mailman id 515555; Tue, 28 Mar 2023 07:14:16 +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 1ph3X5-0001nm-VL for xen-devel@lists.xenproject.org; Tue, 28 Mar 2023 07:14:16 +0000 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by se1-gles-sth1.inumbo.com (Halon) with ESMTP id 255b2265-cd38-11ed-85db-49a42c6b2330; Tue, 28 Mar 2023 09:14:14 +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 869AEC14; Tue, 28 Mar 2023 00:14:58 -0700 (PDT) Received: from a015966.shanghai.arm.com (a015966.shanghai.arm.com [10.169.190.5]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 970303F73F; Tue, 28 Mar 2023 00:14:11 -0700 (PDT) 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: 255b2265-cd38-11ed-85db-49a42c6b2330 From: Henry Wang To: xen-devel@lists.xenproject.org Cc: Henry Wang , Stefano Stabellini , Julien Grall , Bertrand Marquis , Wei Chen , Volodymyr Babchuk , Michal Orzel Subject: [PATCH v3 4/4] xen/arm: Clean-up in p2m_init() and p2m_final_teardown() Date: Tue, 28 Mar 2023 15:13:34 +0800 Message-Id: <20230328071334.2098429-5-Henry.Wang@arm.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230328071334.2098429-1-Henry.Wang@arm.com> References: <20230328071334.2098429-1-Henry.Wang@arm.com> MIME-Version: 1.0 With the change in previous patch, the initial 16 pages in the P2M pool is not necessary anymore. Drop them for code simplification. Also the call to p2m_teardown() from arch_domain_destroy() is not necessary anymore since the movement of the P2M allocation out of arch_domain_create(). Drop the code and the above in-code comment mentioning it. Take the opportunity to fix a typo in the original in-code comment. With above clean-up, the second parameter of p2m_teardown() is also not needed anymore. Drop this parameter and the logic related to this parameter. Signed-off-by: Henry Wang Reviewed-by: Michal Orzel Acked-by: Julien Grall --- v2 -> v3: 1. Correct a typo in original in-code comment, slightly modify the wording to avoid the presence of preemptive/non-preemptive p2m_teardown() call assumption. 2. Drop the (now) unnecessary second parameter of p2m_teardown(). 3. Update the commit message. v1 -> v2: 1. Add Reviewed-by tag from Michal. --- xen/arch/arm/domain.c | 2 +- xen/arch/arm/include/asm/p2m.h | 14 +++++--------- xen/arch/arm/p2m.c | 24 +++--------------------- 3 files changed, 9 insertions(+), 31 deletions(-) diff --git a/xen/arch/arm/domain.c b/xen/arch/arm/domain.c index b8a4a60570..d8ef6501ff 100644 --- a/xen/arch/arm/domain.c +++ b/xen/arch/arm/domain.c @@ -1030,7 +1030,7 @@ int domain_relinquish_resources(struct domain *d) p2m_clear_root_pages(&d->arch.p2m); PROGRESS(p2m): - ret = p2m_teardown(d, true); + ret = p2m_teardown(d); if ( ret ) return ret; diff --git a/xen/arch/arm/include/asm/p2m.h b/xen/arch/arm/include/asm/p2m.h index bf5183e53a..f67e9ddc72 100644 --- a/xen/arch/arm/include/asm/p2m.h +++ b/xen/arch/arm/include/asm/p2m.h @@ -194,18 +194,14 @@ int p2m_init(struct domain *d); /* * The P2M resources are freed in two parts: - * - p2m_teardown() will be called preemptively when relinquish the - * resources, in which case it will free large resources (e.g. intermediate - * page-tables) that requires preemption. + * - p2m_teardown() will be called when relinquish the resources. It + * will free large resources (e.g. intermediate 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 + * freed. This *cannot* be preempted and therefore only small * resources should be freed here. - * Note that p2m_final_teardown() will also call p2m_teardown(), to properly - * 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, bool allow_preemption); +int p2m_teardown(struct domain *d); void p2m_final_teardown(struct domain *d); /* diff --git a/xen/arch/arm/p2m.c b/xen/arch/arm/p2m.c index f1ccd7efbd..418997843d 100644 --- a/xen/arch/arm/p2m.c +++ b/xen/arch/arm/p2m.c @@ -1713,7 +1713,7 @@ static void p2m_free_vmid(struct domain *d) spin_unlock(&vmid_alloc_lock); } -int p2m_teardown(struct domain *d, bool allow_preemption) +int p2m_teardown(struct domain *d) { struct p2m_domain *p2m = p2m_get_hostp2m(d); unsigned long count = 0; @@ -1727,7 +1727,7 @@ int p2m_teardown(struct domain *d, bool allow_preemption) p2m_free_page(p2m->domain, pg); count++; /* Arbitrarily preempt every 512 iterations */ - if ( allow_preemption && !(count % 512) && hypercall_preempt_check() ) + if ( !(count % 512) && hypercall_preempt_check() ) { rc = -ERESTART; break; @@ -1750,13 +1750,9 @@ void p2m_final_teardown(struct domain *d) /* * No need to call relinquish_p2m_mapping() here because * 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. For the latter case, also see - * comment on top of the p2m_set_entry() for more info. + * where relinquish_p2m_mapping() has been called. */ - BUG_ON(p2m_teardown(d, false)); ASSERT(page_list_empty(&p2m->pages)); while ( p2m_teardown_allocation(d) == -ERESTART ) @@ -1827,20 +1823,6 @@ int p2m_init(struct domain *d) if ( rc ) return rc; - /* - * 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 here. - * 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. - */ - spin_lock(&d->arch.paging.lock); - rc = p2m_set_allocation(d, 16, NULL); - spin_unlock(&d->arch.paging.lock); - if ( rc ) - return rc; - return 0; }