From mboxrd@z Thu Jan 1 00:00:00 1970 From: Mukesh Rathor Subject: [RFC PATCH] PVH: cleanup of p2m upon p2m destroy Date: Mon, 16 Dec 2013 17:47:28 -0800 Message-ID: <20131216174728.2ba3ad9a@mantra.us.oracle.com> Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Return-path: List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Sender: xen-devel-bounces@lists.xen.org Errors-To: xen-devel-bounces@lists.xen.org To: "Xen-devel@lists.xensource.com" Cc: Tim Deegan , Jan Beulich List-Id: xen-devel@lists.xenproject.org When a controlling domain is destroyed, any p2m_is_foreign pages must release the refcnt gotten when the page was added to the p2m. Signed-off-by: Mukesh Rathor --- xen/arch/x86/domain.c | 3 +++ xen/arch/x86/mm/p2m.c | 30 ++++++++++++++++++++++++++++++ xen/include/asm-x86/p2m.h | 4 +++- 3 files changed, 36 insertions(+), 1 deletions(-) diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c index c0ac5d6..7f15cdd 100644 --- a/xen/arch/x86/domain.c +++ b/xen/arch/x86/domain.c @@ -1872,6 +1872,9 @@ int domain_relinquish_resources(struct domain *d) case RELMEM_not_started: pci_release_devices(d); + if ( (ret = p2m_cleanup(d)) ) + return ret; + /* Tear down paging-assistance stuff. */ paging_teardown(d); diff --git a/xen/arch/x86/mm/p2m.c b/xen/arch/x86/mm/p2m.c index 441d151..a91deb2 100644 --- a/xen/arch/x86/mm/p2m.c +++ b/xen/arch/x86/mm/p2m.c @@ -499,6 +499,36 @@ void p2m_final_teardown(struct domain *d) p2m_teardown_hostp2m(d); } +/* This function to do any cleanup while walking the entire p2m */ +int p2m_cleanup(struct domain *d) +{ + int rc = 0; + unsigned long gfn, count = 0; + struct p2m_domain *p2m = p2m_get_hostp2m(d); + + if ( !is_pvh_domain(d) ) + return 0; + + for ( gfn = p2m->next_foreign_gfn_to_check; + gfn <= p2m->max_mapped_pfn; gfn++, count++ ) + { + p2m_type_t p2mt; + mfn_t mfn = get_gfn_query(d, gfn, &p2mt); + + if ( unlikely(p2m_is_foreign(p2mt)) ) + put_page(mfn_to_page(mfn)); + put_gfn(d, gfn); + + /* Preempt every 10k pages, arbritary */ + if ( count == 10000 && hypercall_preempt_check() ) + { + p2m->next_foreign_gfn_to_check = gfn + 1; + rc = -EAGAIN; + break; + } + } + return rc; +} static void p2m_remove_page(struct p2m_domain *p2m, unsigned long gfn, unsigned long mfn, diff --git a/xen/include/asm-x86/p2m.h b/xen/include/asm-x86/p2m.h index 6371705..d32d103 100644 --- a/xen/include/asm-x86/p2m.h +++ b/xen/include/asm-x86/p2m.h @@ -254,9 +254,10 @@ struct p2m_domain { /* Highest guest frame that's ever been mapped in the p2m */ unsigned long max_mapped_pfn; - /* When releasing shared gfn's in a preemptible manner, recall where + /* When releasing gfn's in a preemptible manner, recall where * to resume the search */ unsigned long next_shared_gfn_to_relinquish; + unsigned long next_foreign_gfn_to_check; /* Populate-on-demand variables * All variables are protected with the pod lock. We cannot rely on @@ -471,6 +472,7 @@ int p2m_alloc_table(struct p2m_domain *p2m); /* Return all the p2m resources to Xen. */ void p2m_teardown(struct p2m_domain *p2m); void p2m_final_teardown(struct domain *d); +int p2m_cleanup(struct domain *d); /* Add a page to a domain's p2m table */ int guest_physmap_add_entry(struct domain *d, unsigned long gfn, -- 1.7.2.3