[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-unstable] [XEN] Implement XENMEM_set_memory_map, which specifies memory map to



# 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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.