[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH v7 04/10] xen: Introduce XEN_DOMCTL_soft_reset
Hi, At 17:25 +0200 on 27 May (1432747540), Vitaly Kuznetsov wrote: > New operation reassigns all memory pages from source domain to the destination > domain mapping them at exactly the same GFNs. Pages mapped more than once > (e.g. > grants) are being copied. > > Signed-off-by: Vitaly Kuznetsov <vkuznets@xxxxxxxxxx> > --- > Changes in v7: > - is_soft_reset flag added to struct domain to preserve destination domain's > paused state across possible hypercall preemption. > [Jan Beulich] > - XENMEM_soft_reset -> XEN_DOMCTL_soft_reset > - domain_soft_reset() returns int > - no locking for is_dying as it is now proteced by domctl_lock > - print a warning on !mfn_valid case > - check PGC_allocated for pages > - no print on assign_pages failure (it prints error messages on both its > failure paths) > - don't re-read page->count_info, use copy_page flag > - minor stucturing change > - pause both source and destination domain while processing the hypercall > - remove nr_transferred from public interface > [Tim Deegan] > - use get_gfn_type_access() in PoD case (x86-only) > --- > xen/common/domain.c | 186 > ++++++++++++++++++++++++++++++++++++++++++++ > xen/common/domctl.c | 72 +++++++++++++++++ > xen/include/public/domctl.h | 28 +++++++ > xen/include/xen/sched.h | 6 ++ > 4 files changed, 292 insertions(+) > > diff --git a/xen/common/domain.c b/xen/common/domain.c > index 7825c56..824f325 100644 > --- a/xen/common/domain.c > +++ b/xen/common/domain.c > @@ -1006,6 +1006,192 @@ int domain_unpause_by_systemcontroller(struct domain > *d) > return 0; > } > > +int domain_soft_reset(struct domain *source_d, struct domain *dest_d, > + xen_pfn_t *gmfn_start) > +{ > + int rc = 0; > + unsigned long mfn, mfn_new, gmfn, last_gmfn, count; > + unsigned int order; > + p2m_type_t p2mt; > + struct page_info *page, *new_page, *next_page; > + int drop_dom_ref, copy_page; > + > + last_gmfn = domain_get_maximum_gpfn(source_d); > + gmfn = *gmfn_start; > + while ( gmfn <= last_gmfn ) > + { > + page = get_page_from_gfn(source_d, gmfn, &p2mt, 0); In order to be safe against p2m changes, you should use get_gfn_type_access() _here_, and put_gfn() when you're finished with the gfn. You'll also need to get_page() the returned MFN, of course, to make sure that it isn't freed before you reassign it. > + if ( unlikely(page == NULL) ) > + { > +#ifdef CONFIG_X86 > + struct p2m_domain *p2m = p2m_get_hostp2m(source_d); > + p2m_access_t p2ma; > + mfn_t mfn_p2m; > + > + order = 0; > + mfn_p2m = get_gfn_type_access(p2m, gmfn, > + &p2mt, &p2ma, 0, &order); > + if ( p2m_is_pod(p2mt) ) > + { > + rc = guest_physmap_mark_populate_on_demand(dest_d, gmfn, > + order); > + if ( unlikely(rc) ) > + { > + printk(XENLOG_G_ERR "Failed to mark Dom%d's GFN %lx" > + " (order: %d) as PoD\n", source_d->domain_id, > + gmfn, order); > + goto fail; > + } > + } > + put_gfn(source_d, gmfn); > + gmfn += 1ul << order; > +#else > + gmfn++; > +#endif > + goto preempt_check; > + } > + > + mfn = page_to_mfn(page); > + if ( unlikely(!mfn_valid(mfn)) ) > + { > + printk(XENLOG_G_WARNING "Dom%d's GFN %lx points to invalid > MFN\n", > + source_d->domain_id, gmfn); > + put_page(page); > + gmfn++; > + goto preempt_check; > + } > + > + next_page = page; > + count = 0; > + copy_page = 0; > + while ( next_page && !is_xen_heap_page(next_page) && > + page_to_mfn(next_page) == mfn + count ) What's the purpose of this second loop? It doesn't seem to be doing anything that the outer loop couldn't. Cheers, Tim. _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |