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@xxxxxxxxx>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);
mem_exchange.patch
Description: mem_exchange.patch
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
|