# HG changeset patch
# User kfraser@xxxxxxxxxxxxxxxxxxxxx
# Node ID df5fa63490f4da7b65c56087a68783dbcb7944f8
# Parent 8beecb8c5ae29660b2c6073c25a329cc1d9240f6
[XEN] Implement XENMEM_set_memory_map, which specifies memory map to
be returned by XENMEM_memory_map. Hook this into the domain builder.
Based on a patch by Glauber de Oliveira Costa <gcosta@xxxxxxxxxx>
Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>
---
tools/libxc/xc_domain.c | 46 +++++++++++++++++++++++++++++++++++++
tools/libxc/xenctrl.h | 4 +++
tools/python/xen/lowlevel/xc/xc.c | 23 ++++++++++++++++++
tools/python/xen/xend/image.py | 10 +++++++-
xen/arch/x86/mm.c | 47 +++++++++++++++++++++++++++++++++++++-
xen/include/asm-x86/domain.h | 10 ++++----
xen/include/public/memory.h | 17 ++++++++++++-
7 files changed, 149 insertions(+), 8 deletions(-)
diff -r 8beecb8c5ae2 -r df5fa63490f4 tools/libxc/xc_domain.c
--- a/tools/libxc/xc_domain.c Fri Dec 08 11:08:26 2006 +0000
+++ b/tools/libxc/xc_domain.c Fri Dec 08 11:30:30 2006 +0000
@@ -315,6 +315,52 @@ int xc_domain_setmaxmem(int xc_handle,
domctl.u.max_mem.max_memkb = max_memkb;
return do_domctl(xc_handle, &domctl);
}
+
+#if defined(__i386__) || defined(__x86_64__)
+#include <xen/hvm/e820.h>
+int xc_domain_set_memmap_limit(int xc_handle,
+ uint32_t domid,
+ unsigned long map_limitkb)
+{
+ int rc;
+
+ struct xen_foreign_memory_map fmap = {
+ .domid = domid,
+ .map = { .nr_entries = 1 }
+ };
+
+ struct e820entry e820 = {
+ .addr = 0,
+ .size = (uint64_t)map_limitkb << 10,
+ .type = E820_RAM
+ };
+
+ set_xen_guest_handle(fmap.map.buffer, &e820);
+
+ if ( lock_pages(&fmap, sizeof(fmap)) || lock_pages(&e820, sizeof(e820)) )
+ {
+ PERROR("Could not lock memory for Xen hypercall");
+ rc = -1;
+ goto out;
+ }
+
+ rc = xc_memory_op(xc_handle, XENMEM_set_memory_map, &fmap);
+
+ out:
+ unlock_pages(&fmap, sizeof(fmap));
+ unlock_pages(&e820, sizeof(e820));
+ return rc;
+}
+#else
+int xc_domain_set_memmap_limit(int xc_handle,
+ uint32_t domid,
+ unsigned long map_limitkb)
+{
+ PERROR("Function not implemented");
+ errno = ENOSYS;
+ return -1;
+}
+#endif
int xc_domain_set_time_offset(int xc_handle,
uint32_t domid,
diff -r 8beecb8c5ae2 -r df5fa63490f4 tools/libxc/xenctrl.h
--- a/tools/libxc/xenctrl.h Fri Dec 08 11:08:26 2006 +0000
+++ b/tools/libxc/xenctrl.h Fri Dec 08 11:30:30 2006 +0000
@@ -419,6 +419,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 long map_limitkb);
+
int xc_domain_set_time_offset(int xc_handle,
uint32_t domid,
int32_t time_offset_seconds);
diff -r 8beecb8c5ae2 -r df5fa63490f4 tools/python/xen/lowlevel/xc/xc.c
--- a/tools/python/xen/lowlevel/xc/xc.c Fri Dec 08 11:08:26 2006 +0000
+++ b/tools/python/xen/lowlevel/xc/xc.c Fri Dec 08 11:30:30 2006 +0000
@@ -758,6 +758,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 pyxc_error_to_exception();
+
+ Py_INCREF(zero);
+ return zero;
+}
+
static PyObject *pyxc_domain_memory_increase_reservation(XcObject *self,
PyObject *args,
PyObject *kwds)
@@ -1139,6 +1154,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 8beecb8c5ae2 -r df5fa63490f4 tools/python/xen/xend/image.py
--- a/tools/python/xen/xend/image.py Fri Dec 08 11:08:26 2006 +0000
+++ b/tools/python/xen/xend/image.py Fri Dec 08 11:30:30 2006 +0000
@@ -548,6 +548,14 @@ class X86_HVM_ImageHandler(HVMImageHandl
return max(4 * (256 * self.vm.getVCpuCount() + 2 * (maxmem_kb / 1024)),
shadow_mem_kb)
+class X86_Linux_ImageHandler(LinuxImageHandler):
+
+ def buildDomain(self):
+ # set physical mapping limit
+ # add an 8MB slack to balance backend allocations.
+ mem_kb = self.getRequiredInitialReservation() + (8 * 1024)
+ xc.domain_set_memmap_limit(self.vm.getDomid(), mem_kb)
+ return LinuxImageHandler.buildDomain(self)
_handlers = {
"powerpc": {
@@ -558,7 +566,7 @@ _handlers = {
"hvm": IA64_HVM_ImageHandler,
},
"x86": {
- "linux": LinuxImageHandler,
+ "linux": X86_Linux_ImageHandler,
"hvm": X86_HVM_ImageHandler,
},
}
diff -r 8beecb8c5ae2 -r df5fa63490f4 xen/arch/x86/mm.c
--- a/xen/arch/x86/mm.c Fri Dec 08 11:08:26 2006 +0000
+++ b/xen/arch/x86/mm.c Fri Dec 08 11:30:30 2006 +0000
@@ -2978,9 +2978,54 @@ long arch_memory_op(int op, XEN_GUEST_HA
break;
}
+ case XENMEM_set_memory_map:
+ {
+ struct xen_foreign_memory_map fmap;
+ struct domain *d;
+ int rc;
+
+ if ( copy_from_guest(&fmap, arg, 1) )
+ return -EFAULT;
+
+ if ( fmap.map.nr_entries > ARRAY_SIZE(d->arch.e820) )
+ return -EINVAL;
+
+ if ( fmap.domid == DOMID_SELF )
+ {
+ d = current->domain;
+ get_knownalive_domain(d);
+ }
+ else if ( !IS_PRIV(current->domain) )
+ return -EPERM;
+ else if ( (d = find_domain_by_id(fmap.domid)) == NULL )
+ return -ESRCH;
+
+ rc = copy_from_guest(&d->arch.e820[0], fmap.map.buffer,
+ fmap.map.nr_entries) ? -EFAULT : 0;
+ d->arch.nr_e820 = fmap.map.nr_entries;
+
+ put_domain(d);
+ return rc;
+ }
+
case XENMEM_memory_map:
{
- return -ENOSYS;
+ struct xen_memory_map map;
+ struct domain *d = current->domain;
+
+ /* Backwards compatibility. */
+ if ( d->arch.nr_e820 == 0 )
+ return -ENOSYS;
+
+ if ( copy_from_guest(&map, arg, 1) )
+ return -EFAULT;
+
+ map.nr_entries = min(map.nr_entries, d->arch.nr_e820);
+ if ( copy_to_guest(map.buffer, &d->arch.e820[0], map.nr_entries) ||
+ copy_to_guest(arg, &map, 1) )
+ return -EFAULT;
+
+ return 0;
}
case XENMEM_machine_memory_map:
diff -r 8beecb8c5ae2 -r df5fa63490f4 xen/include/asm-x86/domain.h
--- a/xen/include/asm-x86/domain.h Fri Dec 08 11:08:26 2006 +0000
+++ b/xen/include/asm-x86/domain.h Fri Dec 08 11:30:30 2006 +0000
@@ -5,6 +5,7 @@
#include <xen/mm.h>
#include <asm/hvm/vcpu.h>
#include <asm/hvm/domain.h>
+#include <asm/e820.h>
struct trap_bounce {
unsigned long error_code;
@@ -100,11 +101,7 @@ struct arch_domain
/* I/O-port admin-specified access capabilities. */
struct rangeset *ioport_caps;
- /* HVM stuff */
- struct hvm_domain hvm_domain;
-
- /* Shadow-translated guest: Pseudophys base address of reserved area. */
- unsigned long first_reserved_pfn;
+ struct hvm_domain hvm_domain;
struct shadow_domain shadow;
@@ -113,6 +110,9 @@ struct arch_domain
/* Highest guest frame that's ever been mapped in the p2m */
unsigned long max_mapped_pfn;
+ /* Pseudophysical e820 map (XENMEM_memory_map). */
+ struct e820entry e820[3];
+ unsigned int nr_e820;
} __cacheline_aligned;
#ifdef CONFIG_X86_PAE
diff -r 8beecb8c5ae2 -r df5fa63490f4 xen/include/public/memory.h
--- a/xen/include/public/memory.h Fri Dec 08 11:08:26 2006 +0000
+++ b/xen/include/public/memory.h Fri Dec 08 11:30:30 2006 +0000
@@ -222,7 +222,8 @@ DEFINE_XEN_GUEST_HANDLE(xen_translate_gp
/*
* Returns the pseudo-physical memory map as it was when the domain
- * was started.
+ * was started (specified by XENMEM_set_memory_map).
+ * arg == addr of xen_memory_map_t.
*/
#define XENMEM_memory_map 9
struct xen_memory_map {
@@ -245,8 +246,22 @@ DEFINE_XEN_GUEST_HANDLE(xen_memory_map_t
/*
* Returns the real physical memory map. Passes the same structure as
* XENMEM_memory_map.
+ * arg == addr of xen_memory_map_t.
*/
#define XENMEM_machine_memory_map 10
+
+/*
+ * Set the pseudo-physical memory map of a domain, as returned by
+ * XENMEM_memory_map.
+ * arg == addr of xen_foreign_memory_map_t.
+ */
+#define XENMEM_set_memory_map 13
+struct xen_foreign_memory_map {
+ domid_t domid;
+ struct xen_memory_map map;
+};
+typedef struct xen_foreign_memory_map xen_foreign_memory_map_t;
+DEFINE_XEN_GUEST_HANDLE(xen_foreign_memory_map_t);
#endif /* __XEN_PUBLIC_MEMORY_H__ */
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|