aboutsummaryrefslogtreecommitdiffstats
path: root/xen/common/sysctl.c
diff options
context:
space:
mode:
authorKeir Fraser <keir.fraser@citrix.com>2009-03-06 19:18:39 +0000
committerKeir Fraser <keir.fraser@citrix.com>2009-03-06 19:18:39 +0000
commite4865c23155b05278f31be537764e760cd2d9b7e (patch)
treee020f0021a3939aef936a38ee4322f58df27efbd /xen/common/sysctl.c
parent3c6846fa3462faadbe7b34255cb18009a751cd48 (diff)
downloadxen-e4865c23155b05278f31be537764e760cd2d9b7e.tar.gz
xen-e4865c23155b05278f31be537764e760cd2d9b7e.tar.bz2
xen-e4865c23155b05278f31be537764e760cd2d9b7e.zip
Page offline support in Xen side
This patch add support to offline a page. The basical idea is, when a page is assigned, it will be marked offline pending and be moved out of buddy when freed, when a page is free, it will be moved out of buddy directly. One notice after this change is, now the page->count_info is not always 0, especially for shadow page, since the PGC_offlining bit may be set. Signed-off-by: Wang, Shane <shane.wang@intel.com> Signed-off-by: Jiang, Yunhong <yunhong.jiang@intel.com>
Diffstat (limited to 'xen/common/sysctl.c')
-rw-r--r--xen/common/sysctl.c55
1 files changed, 55 insertions, 0 deletions
diff --git a/xen/common/sysctl.c b/xen/common/sysctl.c
index 93dd2ffe58..7ff4f5d8a5 100644
--- a/xen/common/sysctl.c
+++ b/xen/common/sysctl.c
@@ -233,6 +233,61 @@ long do_sysctl(XEN_GUEST_HANDLE(xen_sysctl_t) u_sysctl)
}
break;
+ case XEN_SYSCTL_page_offline_op:
+ {
+ uint32_t *status, *ptr;
+ unsigned long pfn;
+
+ ptr = status = xmalloc_bytes( sizeof(uint32_t) *
+ (op->u.page_offline.end -
+ op->u.page_offline.start + 1));
+ if (!status)
+ {
+ dprintk(XENLOG_WARNING, "Out of memory for page offline op\n");
+ ret = -ENOMEM;
+ break;
+ }
+
+ memset(status, PG_OFFLINE_INVALID, sizeof(uint32_t) *
+ (op->u.page_offline.end - op->u.page_offline.start + 1));
+
+ for ( pfn = op->u.page_offline.start;
+ pfn <= op->u.page_offline.end;
+ pfn ++ )
+ {
+ switch (op->u.page_offline.cmd)
+ {
+ /* Shall revert her if failed, or leave caller do it? */
+ case sysctl_page_offline:
+ ret = offline_page(pfn, 0, ptr++);
+ break;
+ case sysctl_page_online:
+ ret = online_page(pfn, ptr++);
+ break;
+ case sysctl_query_page_offline:
+ ret = query_page_offline(pfn, ptr++);
+ break;
+ default:
+ gdprintk(XENLOG_WARNING, "invalid page offline op %x\n",
+ op->u.page_offline.cmd);
+ ret = -EINVAL;
+ break;
+ }
+
+ if (ret)
+ break;
+ }
+
+ if (copy_to_guest(op->u.page_offline.status, status,
+ op->u.page_offline.end - op->u.page_offline.start + 1))
+ {
+ ret = -EFAULT;
+ break;
+ }
+ xfree(status);
+ }
+ break;
+
default:
ret = arch_do_sysctl(op, u_sysctl);
break;