Jiang, Yunhong
2009-May-31 11:12 UTC
[Xen-devel] [PATCH 5/6] Extend XENMEM_exchange to support exchange memory for foreign domain
Currently XENMEM_exchange only support exchange memory for current domain, This patch extend it to foreign domain once the target domain is in suspended state. Signed-off-by: Jiang, Yunhogn <yunhong.jiang@intel.com>Now comes changes to hypervisor diff -r 1fe86c971a36 xen/common/memory.c --- a/xen/common/memory.c Wed May 27 03:22:43 2009 +0800 +++ b/xen/common/memory.c Wed May 27 03:42:29 2009 +0800 @@ -23,6 +23,7 @@ #include <asm/hardirq.h> #include <xen/numa.h> #include <public/memory.h> +#include <public/sched.h> #include <xsm/xsm.h> struct memop_args { @@ -225,7 +226,7 @@ static long memory_exchange(XEN_GUEST_HA unsigned long i, j, k; unsigned int node, memflags = 0; long rc = 0; - struct domain *d; + struct domain *d = NULL; struct page_info *page; if ( copy_from_guest(&exch, arg, 1) ) @@ -266,15 +267,28 @@ static long memory_exchange(XEN_GUEST_HA } /* - * Only support exchange on calling domain right now. Otherwise there are - * tricky corner cases to consider (e.g., dying domain). + * Mostly support exchange on calling domain right now. Otherwise the + * target domain should be in suspended state */ if ( unlikely(exch.in.domid != DOMID_SELF) ) { - rc = IS_PRIV(current->domain) ? -EINVAL : -EPERM; - goto fail_early; - } - d = current->domain; + d = rcu_lock_domain_by_id(exch.in.domid); + if (!d) + { + rc = -EINVAL; + goto fail_early; + } + spin_lock(&d->shutdown_lock); + + if ( (!d->is_shut_down) || (d->shutdown_code != SHUTDOWN_suspend) ) + { + rc = -EPERM; + spin_unlock(&d->shutdown_lock); + goto fail_early; + } + } + else + d = rcu_lock_current_domain(); memflags |= MEMF_bits(domain_clamp_alloc_bitsize( d, @@ -292,6 +306,9 @@ static long memory_exchange(XEN_GUEST_HA if ( hypercall_preempt_check() ) { exch.nr_exchanged = i << in_chunk_order; + + if (unlikely (d != current->domain)) + spin_unlock(&d->shutdown_lock); if ( copy_field_to_guest(arg, &exch, nr_exchanged) ) return -EFAULT; return hypercall_create_continuation( @@ -387,6 +404,10 @@ static long memory_exchange(XEN_GUEST_HA exch.nr_exchanged = exch.in.nr_extents; if ( copy_field_to_guest(arg, &exch, nr_exchanged) ) rc = -EFAULT; + + if (d != current->domain) + spin_unlock(&d->shutdown_lock); + rcu_unlock_domain(d); return rc; /* @@ -399,6 +420,10 @@ static long memory_exchange(XEN_GUEST_HA if ( assign_pages(d, page, 0, MEMF_no_refcount) ) BUG(); + if (d != current->domain) + spin_unlock(&d->shutdown_lock); + rcu_unlock_domain(d); + /* Free any output pages we managed to allocate. */ while ( (page = page_list_remove_head(&out_chunk_list)) ) free_domheap_pages(page, exch.out.extent_order); _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel