diff options
author | Keir Fraser <keir.fraser@citrix.com> | 2009-03-06 19:18:39 +0000 |
---|---|---|
committer | Keir Fraser <keir.fraser@citrix.com> | 2009-03-06 19:18:39 +0000 |
commit | e4865c23155b05278f31be537764e760cd2d9b7e (patch) | |
tree | e020f0021a3939aef936a38ee4322f58df27efbd /xen/common/sysctl.c | |
parent | 3c6846fa3462faadbe7b34255cb18009a751cd48 (diff) | |
download | xen-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.c | 55 |
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; |