Keir,
Here follows the hopefully end revision. If you think it needs more
rework, just please warn me ASAP.
--
Glauber de Oliveira Costa
Red Hat Inc.
"Free as in Freedom"
# HG changeset patch
# User gcosta@xxxxxxxxxx
# Date 1164812939 18000
# Node ID 0d6e4c983718a41b651bb8504ff5949a623b4e09
# Parent 71ea8d34e818c7aed76e77edcf7a23a7e6e9e71e
Implement memory_map hypercall + set_memmap_limit domctl and friends
This patch implements two new interfaces:
XENMEM_memory_map hypercall, currently defined, but not implemented.
It provides a way to inform guests about how should their physical
memory mapping look like.
DOMCTL_set_memmap_limit domctl and proper tools, which allows us
to inform the hypervisor about the maximum size guest's physical
mapping can grow to.
Signed-off-by: Glauber de Oliveira Costa <gcosta@xxxxxxxxxx>
diff -r 71ea8d34e818 -r 0d6e4c983718 tools/libxc/xc_domain.c
--- a/tools/libxc/xc_domain.c Wed Nov 29 08:36:41 2006 -0500
+++ b/tools/libxc/xc_domain.c Wed Nov 29 10:08:59 2006 -0500
@@ -313,6 +313,17 @@ int xc_domain_setmaxmem(int xc_handle,
domctl.cmd = XEN_DOMCTL_max_mem;
domctl.domain = (domid_t)domid;
domctl.u.max_mem.max_memkb = max_memkb;
+ return do_domctl(xc_handle, &domctl);
+}
+
+int xc_domain_set_memmap_limit(int xc_handle,
+ uint32_t domid,
+ unsigned int map_limitkb)
+{
+ DECLARE_DOMCTL;
+ domctl.cmd = XEN_DOMCTL_memmap_limit;
+ domctl.domain = (domid_t)domid;
+ domctl.u.memmap_limit.map_limitkb = map_limitkb;
return do_domctl(xc_handle, &domctl);
}
diff -r 71ea8d34e818 -r 0d6e4c983718 tools/libxc/xenctrl.h
--- a/tools/libxc/xenctrl.h Wed Nov 29 08:36:41 2006 -0500
+++ b/tools/libxc/xenctrl.h Wed Nov 29 10:08:59 2006 -0500
@@ -415,6 +415,10 @@ int xc_domain_setmaxmem(int xc_handle,
uint32_t domid,
unsigned int max_memkb);
+int xc_domain_set_memmap_limit(int xc_handle,
+ uint32_t domid,
+ unsigned int map_limitkb);
+
int xc_domain_set_time_offset(int xc_handle,
uint32_t domid,
int32_t time_offset_seconds);
diff -r 71ea8d34e818 -r 0d6e4c983718 tools/python/xen/lowlevel/xc/xc.c
--- a/tools/python/xen/lowlevel/xc/xc.c Wed Nov 29 08:36:41 2006 -0500
+++ b/tools/python/xen/lowlevel/xc/xc.c Wed Nov 29 10:08:59 2006 -0500
@@ -741,6 +741,21 @@ static PyObject *pyxc_domain_setmaxmem(X
return zero;
}
+static PyObject *pyxc_domain_set_memmap_limit(XcObject *self, PyObject *args)
+{
+ uint32_t dom;
+ unsigned int maplimit_kb;
+
+ if (!PyArg_ParseTuple(args, "ii", &dom, &maplimit_kb))
+ return NULL;
+
+ if (xc_domain_set_memmap_limit(self->xc_handle, dom, maplimit_kb) != 0)
+ return PyErr_SetFromErrno(xc_error);
+
+ Py_INCREF(zero);
+ return zero;
+}
+
static PyObject *pyxc_domain_memory_increase_reservation(XcObject *self,
PyObject *args,
PyObject *kwds)
@@ -1122,6 +1137,14 @@ static PyMethodDef pyxc_methods[] = {
"Set a domain's memory limit\n"
" dom [int]: Identifier of domain.\n"
" maxmem_kb [int]: .\n"
+ "Returns: [int] 0 on success; -1 on error.\n" },
+
+ { "domain_set_memmap_limit",
+ (PyCFunction)pyxc_domain_set_memmap_limit,
+ METH_VARARGS, "\n"
+ "Set a domain's physical memory mappping limit\n"
+ " dom [int]: Identifier of domain.\n"
+ " map_limitkb [int]: .\n"
"Returns: [int] 0 on success; -1 on error.\n" },
{ "domain_memory_increase_reservation",
diff -r 71ea8d34e818 -r 0d6e4c983718 tools/python/xen/xend/XendDomainInfo.py
--- a/tools/python/xen/xend/XendDomainInfo.py Wed Nov 29 08:36:41 2006 -0500
+++ b/tools/python/xen/xend/XendDomainInfo.py Wed Nov 29 10:08:59 2006 -0500
@@ -1297,6 +1297,10 @@ class XendDomainInfo:
# set memory limit
xc.domain_setmaxmem(self.domid, maxmem)
+
+ # set physical mapping limit
+ # add an 8MB slack to balance backend allocations.
+ xc.domain_set_memmap_limit(self.domid, maxmem + (8 << 20))
# Make sure there's enough RAM available for the domain
balloon.free(memory + shadow)
diff -r 71ea8d34e818 -r 0d6e4c983718 xen/arch/x86/mm.c
--- a/xen/arch/x86/mm.c Wed Nov 29 08:36:41 2006 -0500
+++ b/xen/arch/x86/mm.c Wed Nov 29 10:08:59 2006 -0500
@@ -2976,7 +2976,40 @@ long arch_memory_op(int op, XEN_GUEST_HA
case XENMEM_memory_map:
{
- return -ENOSYS;
+ struct xen_memory_map memmap;
+ struct domain *d;
+ XEN_GUEST_HANDLE(e820entry_t) buffer;
+ struct e820entry map;
+
+
+ d = current->domain;
+
+ if ( copy_from_guest(&memmap, arg, 1) )
+ return -EFAULT;
+
+ buffer = guest_handle_cast(memmap.buffer, e820entry_t);
+ if ( unlikely(guest_handle_is_null(buffer)) )
+ return -EFAULT;
+
+ memmap.nr_entries = 1;
+
+ if ( d->memmap_limit )
+ map.size = d->memmap_limit;
+ else
+ /* Don know how to implement the mapping. Act as if it
were not
+ * implemented */
+ return -ENOSYS;
+
+ map.addr = 0ULL;
+ map.type = E820_RAM;
+
+ if ( copy_to_guest(arg, &memmap, 1) )
+ return -EFAULT;
+
+ if ( copy_to_guest(buffer, &map, 1) < 0 )
+ return -EFAULT;
+
+ return 0;
}
case XENMEM_machine_memory_map:
diff -r 71ea8d34e818 -r 0d6e4c983718 xen/common/domctl.c
--- a/xen/common/domctl.c Wed Nov 29 08:36:41 2006 -0500
+++ b/xen/common/domctl.c Wed Nov 29 10:08:59 2006 -0500
@@ -552,6 +552,29 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
}
break;
+ case XEN_DOMCTL_memmap_limit:
+ {
+ struct domain *d;
+ unsigned long new_limit;
+
+ ret = -ESRCH;
+ d = find_domain_by_id(op->domain);
+ if ( d == NULL )
+ break;
+
+ ret = -EINVAL;
+ new_limit = op->u.memmap_limit.map_limitkb << 10;
+
+ /* No point in neither calling it more than once, nor
+ * setting physical map limit to zero */
+ if ( (d->memmap_limit == 0) && (new_limit != 0) )
+ {
+ d->memmap_limit = new_limit;
+ ret = 0;
+ }
+
+ put_domain(d);
+ }
case XEN_DOMCTL_setdomainhandle:
{
struct domain *d;
diff -r 71ea8d34e818 -r 0d6e4c983718 xen/include/public/domctl.h
--- a/xen/include/public/domctl.h Wed Nov 29 08:36:41 2006 -0500
+++ b/xen/include/public/domctl.h Wed Nov 29 10:08:59 2006 -0500
@@ -385,6 +385,14 @@ typedef struct xen_domctl_settimeoffset
typedef struct xen_domctl_settimeoffset xen_domctl_settimeoffset_t;
DEFINE_XEN_GUEST_HANDLE(xen_domctl_settimeoffset_t);
+#define XEN_DOMCTL_memmap_limit 26
+struct xen_domctl_memmap_limit {
+ /* IN variables. */
+ uint64_t map_limitkb;
+};
+typedef struct xen_domctl_memory_map_limit xen_domctl_map_limit_t;
+DEFINE_XEN_GUEST_HANDLE(xen_domctl_map_limit_t);
+
struct xen_domctl {
uint32_t cmd;
uint32_t interface_version; /* XEN_DOMCTL_INTERFACE_VERSION */
@@ -410,9 +418,11 @@ struct xen_domctl {
struct xen_domctl_hypercall_init hypercall_init;
struct xen_domctl_arch_setup arch_setup;
struct xen_domctl_settimeoffset settimeoffset;
- uint8_t pad[128];
+ struct xen_domctl_memmap_limit memmap_limit;
+ uint8_t pad[120];
} u;
};
+
typedef struct xen_domctl xen_domctl_t;
DEFINE_XEN_GUEST_HANDLE(xen_domctl_t);
diff -r 71ea8d34e818 -r 0d6e4c983718 xen/include/xen/sched.h
--- a/xen/include/xen/sched.h Wed Nov 29 08:36:41 2006 -0500
+++ b/xen/include/xen/sched.h Wed Nov 29 10:08:59 2006 -0500
@@ -112,6 +112,7 @@ struct domain
struct list_head xenpage_list; /* linked list, of size xenheap_pages */
unsigned int tot_pages; /* number of pages currently possesed */
unsigned int max_pages; /* maximum value for tot_pages */
+ unsigned int memmap_limit; /* the higher our memory map can go */
unsigned int xenheap_pages; /* # pages allocated from Xen heap */
/* Scheduling. */
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
|