[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH RFCv3 3/8] xen: introduce XEN_DOMCTL_set_recipient
New operation sets the 'recipient' domain which will recieve all memory pages from a particular domain when these pages are freed. Signed-off-by: Vitaly Kuznetsov <vkuznets@xxxxxxxxxx> --- xen/common/domain.c | 3 +++ xen/common/domctl.c | 27 +++++++++++++++++++++++++++ xen/common/page_alloc.c | 26 ++++++++++++++++++++++---- xen/include/public/domctl.h | 19 +++++++++++++++++++ xen/include/xen/sched.h | 1 + 5 files changed, 72 insertions(+), 4 deletions(-) diff --git a/xen/common/domain.c b/xen/common/domain.c index 62514b0..6bceb64 100644 --- a/xen/common/domain.c +++ b/xen/common/domain.c @@ -822,6 +822,9 @@ static void complete_domain_destroy(struct rcu_head *head) if ( d->target != NULL ) put_domain(d->target); + if ( d->recipient != NULL ) + put_domain(d->recipient); + evtchn_destroy_final(d); radix_tree_destroy(&d->pirq_tree, free_pirq_struct); diff --git a/xen/common/domctl.c b/xen/common/domctl.c index 1ad0729..38cd10a 100644 --- a/xen/common/domctl.c +++ b/xen/common/domctl.c @@ -1152,6 +1152,33 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl) } break; + case XEN_DOMCTL_set_recipient: + { + struct domain *recipient_dom; + + if ( op->u.recipient.recipient == DOMID_INVALID ) + { + if ( d->recipient ) + { + put_domain(d->recipient); + } + d->recipient = NULL; + break; + } + + recipient_dom = get_domain_by_id(op->u.recipient.recipient); + if ( recipient_dom == NULL ) + { + ret = -ESRCH; + break; + } + else + { + d->recipient = recipient_dom; + } + } + break; + default: ret = arch_do_domctl(op, d, u_domctl); break; diff --git a/xen/common/page_alloc.c b/xen/common/page_alloc.c index 7b4092d..abb2ef3 100644 --- a/xen/common/page_alloc.c +++ b/xen/common/page_alloc.c @@ -1707,6 +1707,7 @@ void free_domheap_pages(struct page_info *pg, unsigned int order) { struct domain *d = page_get_owner(pg); unsigned int i; + unsigned long mfn, gmfn; bool_t drop_dom_ref; ASSERT(!in_irq()); @@ -1764,11 +1765,28 @@ void free_domheap_pages(struct page_info *pg, unsigned int order) scrub = 1; } - if ( unlikely(scrub) ) - for ( i = 0; i < (1 << order); i++ ) - scrub_one_page(&pg[i]); + if ( !d || !d->recipient || d->recipient->is_dying ) + { + if ( unlikely(scrub) ) + for ( i = 0; i < (1 << order); i++ ) + scrub_one_page(&pg[i]); - free_heap_pages(pg, order); + free_heap_pages(pg, order); + } + else + { + mfn = page_to_mfn(pg); + gmfn = mfn_to_gmfn(d, mfn); + + page_set_owner(pg, NULL); + assign_pages(d->recipient, pg, order, 0); + + if ( guest_physmap_add_page(d->recipient, gmfn, mfn, order) ) + { + gdprintk(XENLOG_INFO, "Failed to add page to domain's physmap" + " mfn: %lx\n", mfn); + } + } } if ( drop_dom_ref ) diff --git a/xen/include/public/domctl.h b/xen/include/public/domctl.h index cfa39b3..7fcb6db 100644 --- a/xen/include/public/domctl.h +++ b/xen/include/public/domctl.h @@ -965,6 +965,23 @@ struct xen_domctl_vnuma { typedef struct xen_domctl_vnuma xen_domctl_vnuma_t; DEFINE_XEN_GUEST_HANDLE(xen_domctl_vnuma_t); +/* + * XEN_DOMCTL_set_recipient - sets the 'recipient' domain which will recieve + * all the domain's memory after its death or when and memory page from + * domain's heap is being freed. Pages from xen heap belonging to the domain + * are not copied. An additional reference link to the destination domain is + * being taken to prevent it from dying. + * When DOMID_INVALID is supplied as a recipient the source domain returns to + * its original state when memory pages are freed normally, reference link to + * the destination domain is being dropped. + */ +struct xen_domctl_set_recipient { + domid_t recipient; +}; +typedef struct xen_domctl_set_recipient xen_domctl_set_recipient_t; +DEFINE_XEN_GUEST_HANDLE(xen_domctl_set_recipient_t); + + struct xen_domctl { uint32_t cmd; #define XEN_DOMCTL_createdomain 1 @@ -1038,6 +1055,7 @@ struct xen_domctl { #define XEN_DOMCTL_get_vcpu_msrs 72 #define XEN_DOMCTL_set_vcpu_msrs 73 #define XEN_DOMCTL_setvnumainfo 74 +#define XEN_DOMCTL_set_recipient 75 #define XEN_DOMCTL_gdbsx_guestmemio 1000 #define XEN_DOMCTL_gdbsx_pausevcpu 1001 #define XEN_DOMCTL_gdbsx_unpausevcpu 1002 @@ -1099,6 +1117,7 @@ struct xen_domctl { struct xen_domctl_gdbsx_pauseunp_vcpu gdbsx_pauseunp_vcpu; struct xen_domctl_gdbsx_domstatus gdbsx_domstatus; struct xen_domctl_vnuma vnuma; + struct xen_domctl_set_recipient recipient; uint8_t pad[128]; } u; }; diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h index c5157e6..d00d655 100644 --- a/xen/include/xen/sched.h +++ b/xen/include/xen/sched.h @@ -366,6 +366,7 @@ struct domain bool_t is_privileged; /* Which guest this guest has privileges on */ struct domain *target; + struct domain *recipient; /* Is this guest being debugged by dom0? */ bool_t debugger_attached; /* Is this guest dying (i.e., a zombie)? */ -- 1.9.3 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |