From patchwork Mon Mar 9 10:23:04 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Durrant X-Patchwork-Id: 11426627 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id ED940138D for ; Mon, 9 Mar 2020 10:25:21 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id D393F208C3 for ; Mon, 9 Mar 2020 10:25:21 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org D393F208C3 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=xen.org Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=xen-devel-bounces@lists.xenproject.org Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1jBFZW-0000GR-7q; Mon, 09 Mar 2020 10:23:42 +0000 Received: from all-amaz-eas1.inumbo.com ([34.197.232.57] helo=us1-amaz-eas2.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1jBFZV-0000G1-CP for xen-devel@lists.xenproject.org; Mon, 09 Mar 2020 10:23:41 +0000 X-Inumbo-ID: 0b9e2a34-61f0-11ea-abfc-12813bfff9fa Received: from smtp-fw-6001.amazon.com (unknown [52.95.48.154]) by us1-amaz-eas2.inumbo.com (Halon) with ESMTPS id 0b9e2a34-61f0-11ea-abfc-12813bfff9fa; Mon, 09 Mar 2020 10:23:40 +0000 (UTC) IronPort-SDR: 1JNFNEQy1QS+3A8UqAFLiA2sW6odpkvK8kGpfVBn4Q//1HQtu879gO/lhm/DbShpgK+Rsb20YK 4xfNdQUyWLEA== X-IronPort-AV: E=Sophos;i="5.70,532,1574121600"; d="scan'208";a="21627121" Received: from iad12-co-svc-p1-lb1-vlan3.amazon.com (HELO email-inbound-relay-1e-97fdccfd.us-east-1.amazon.com) ([10.43.8.6]) by smtp-border-fw-out-6001.iad6.amazon.com with ESMTP; 09 Mar 2020 10:23:40 +0000 Received: from EX13MTAUEA002.ant.amazon.com (iad55-ws-svc-p15-lb9-vlan3.iad.amazon.com [10.40.159.166]) by email-inbound-relay-1e-97fdccfd.us-east-1.amazon.com (Postfix) with ESMTPS id 7C266A219B; Mon, 9 Mar 2020 10:23:36 +0000 (UTC) Received: from EX13D32EUC001.ant.amazon.com (10.43.164.159) by EX13MTAUEA002.ant.amazon.com (10.43.61.77) with Microsoft SMTP Server (TLS) id 15.0.1236.3; Mon, 9 Mar 2020 10:23:20 +0000 Received: from EX13MTAUEA002.ant.amazon.com (10.43.61.77) by EX13D32EUC001.ant.amazon.com (10.43.164.159) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Mon, 9 Mar 2020 10:23:19 +0000 Received: from u2f063a87eabd5f.cbg10.amazon.com (10.125.106.135) by mail-relay.amazon.com (10.43.61.169) with Microsoft SMTP Server id 15.0.1236.3 via Frontend Transport; Mon, 9 Mar 2020 10:23:18 +0000 From: To: Date: Mon, 9 Mar 2020 10:23:04 +0000 Message-ID: <20200309102304.1251-7-paul@xen.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20200309102304.1251-1-paul@xen.org> References: <20200309102304.1251-1-paul@xen.org> MIME-Version: 1.0 Precedence: Bulk Subject: [Xen-devel] [PATCH v5 6/6] domain: use PGC_extra domheap page for shared_info X-BeenThere: xen-devel@lists.xenproject.org X-Mailman-Version: 2.1.23 List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Cc: Stefano Stabellini , Julien Grall , Wei Liu , Paul Durrant , Andrew Cooper , Paul Durrant , Konrad Rzeszutek Wilk , Ian Jackson , George Dunlap , Jan Beulich , Volodymyr Babchuk Errors-To: xen-devel-bounces@lists.xenproject.org Sender: "Xen-devel" From: Paul Durrant Currently shared_info is a shared xenheap page but shared xenheap pages complicate future plans for live-update of Xen so it is desirable to, where possible, not use them [1]. This patch therefore converts shared_info into a PGC_extra domheap page. This does entail freeing shared_info during domain_relinquish_resources() rather than domain_destroy() so care is needed to avoid de-referencing a NULL shared_info pointer hence some extra checks of 'is_dying' are needed. Also, because shared_info will no longer be a xenheap page this patch adds an extra dump function to make sure the shared_info MFN is included in the output of dump_pageframe_info(). NOTE: For Arm, the call to free_shared_info() in arch_domain_destroy() is left in place since it is idempotent and called in the error path for arch_domain_create(). [1] See https://lists.xenproject.org/archives/html/xen-devel/2020-02/msg02018.html Signed-off-by: Paul Durrant --- Cc: Stefano Stabellini Cc: Julien Grall Cc: Volodymyr Babchuk Cc: Andrew Cooper Cc: George Dunlap Cc: Ian Jackson Cc: Jan Beulich Cc: Konrad Rzeszutek Wilk Cc: Wei Liu v5: - Incorporate new dump_shared_info() function v2: - Addressed comments from Julien - Expanded the commit comment to explain why this patch is wanted --- xen/arch/arm/domain.c | 2 ++ xen/arch/x86/domain.c | 5 ++++- xen/common/domain.c | 38 ++++++++++++++++++++++++++++++++++---- xen/common/event_channel.c | 3 +++ xen/common/time.c | 15 +++++++++++++++ xen/include/xen/domain.h | 1 + 6 files changed, 59 insertions(+), 5 deletions(-) diff --git a/xen/arch/arm/domain.c b/xen/arch/arm/domain.c index 5298d80bd2..741f6dd444 100644 --- a/xen/arch/arm/domain.c +++ b/xen/arch/arm/domain.c @@ -1005,6 +1005,8 @@ int domain_relinquish_resources(struct domain *d) BUG(); } + free_shared_info(d); + return 0; } diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c index f6ed25e8ee..60623beba1 100644 --- a/xen/arch/x86/domain.c +++ b/xen/arch/x86/domain.c @@ -261,6 +261,8 @@ void dump_pageframe_info(struct domain *d) page->count_info, page->u.inuse.type_info); } spin_unlock(&d->page_alloc_lock); + + dump_shared_info(d); } void update_guest_memory_policy(struct vcpu *v, @@ -693,7 +695,6 @@ void arch_domain_destroy(struct domain *d) pv_domain_destroy(d); free_perdomain_mappings(d); - free_shared_info(d); cleanup_domain_irq_mapping(d); psr_domain_free(d); @@ -2249,6 +2250,8 @@ int domain_relinquish_resources(struct domain *d) if ( is_hvm_domain(d) ) hvm_domain_relinquish_resources(d); + free_shared_info(d); + return 0; } diff --git a/xen/common/domain.c b/xen/common/domain.c index ba7a905258..0b1c722708 100644 --- a/xen/common/domain.c +++ b/xen/common/domain.c @@ -1650,24 +1650,54 @@ int continue_hypercall_on_cpu( int alloc_shared_info(struct domain *d, unsigned int memflags) { - if ( (d->shared_info.virt = alloc_xenheap_pages(0, memflags)) == NULL ) + struct page_info *pg; + + pg = alloc_domheap_page(d, MEMF_no_refcount | memflags); + if ( !pg ) return -ENOMEM; - d->shared_info.mfn = virt_to_mfn(d->shared_info.virt); + if ( !get_page_and_type(pg, d, PGT_writable_page) ) + { + /* + * The domain should not be running at this point so there is + * no way we should reach this error path. + */ + ASSERT_UNREACHABLE(); + return -ENODATA; + } + + d->shared_info.mfn = page_to_mfn(pg); + d->shared_info.virt = __map_domain_page_global(pg); clear_page(d->shared_info.virt); - share_xen_page_with_guest(mfn_to_page(d->shared_info.mfn), d, SHARE_rw); return 0; } void free_shared_info(struct domain *d) { + struct page_info *pg; + if ( !d->shared_info.virt ) return; - free_xenheap_page(d->shared_info.virt); + unmap_domain_page_global(d->shared_info.virt); d->shared_info.virt = NULL; + + pg = mfn_to_page(d->shared_info.mfn); + + put_page_alloc_ref(pg); + put_page_and_type(pg); +} + +void dump_shared_info(struct domain *d) +{ + domain_lock(d); + + if ( d->shared_info.virt ) + printk("Shared Info: %"PRI_mfn"\n", mfn_x(d->shared_info.mfn)); + + domain_unlock(d); } /* diff --git a/xen/common/event_channel.c b/xen/common/event_channel.c index e86e2bfab0..a17422284d 100644 --- a/xen/common/event_channel.c +++ b/xen/common/event_channel.c @@ -1325,6 +1325,9 @@ void evtchn_destroy(struct domain *d) { unsigned int i; + /* This must be done before shared_info is freed */ + BUG_ON(!d->shared_info.virt); + /* After this barrier no new event-channel allocations can occur. */ BUG_ON(!d->is_dying); spin_barrier(&d->event_lock); diff --git a/xen/common/time.c b/xen/common/time.c index 58fa9abc40..ada02faf07 100644 --- a/xen/common/time.c +++ b/xen/common/time.c @@ -99,6 +99,18 @@ void update_domain_wallclock_time(struct domain *d) uint32_t *wc_version; uint64_t sec; + if ( d != current->domain ) + { + /* + * We need to check is_dying here as, if it is set, the + * shared_info may have been freed. To do this safely we need + * hold the domain lock. + */ + domain_lock(d); + if ( d->is_dying ) + goto unlock; + } + spin_lock(&wc_lock); wc_version = &shared_info(d, wc_version); @@ -121,6 +133,9 @@ void update_domain_wallclock_time(struct domain *d) *wc_version = version_update_end(*wc_version); spin_unlock(&wc_lock); + unlock: + if ( d != current->domain ) + domain_unlock(d); } /* Set clock to after 00:00:00 UTC, 1 January, 1970. */ diff --git a/xen/include/xen/domain.h b/xen/include/xen/domain.h index 740e2032ad..740c0537fa 100644 --- a/xen/include/xen/domain.h +++ b/xen/include/xen/domain.h @@ -132,5 +132,6 @@ void vnuma_destroy(struct vnuma_info *vnuma); int alloc_shared_info(struct domain *d, unsigned int memflags); void free_shared_info(struct domain *d); +void dump_shared_info(struct domain *d); #endif /* __XEN_DOMAIN_H__ */