libxc: xc_domain_set_memory_map, xc_get_machine_memory_map (x86, amd64 only)
authorKonrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Thu, 26 May 2011 13:49:50 +0000 (14:49 +0100)
committerKonrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Thu, 26 May 2011 13:49:50 +0000 (14:49 +0100)
Add these two functions.

The later retrieves the E820 as seen by the hypervisor (completely
unchanged) and the second call sets the E820 for the specified guest.

Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Committed-by: Ian Jackson <ian.jackson@eu.citrix.com>
tools/libxc/xc_domain.c
tools/libxc/xc_e820.h
tools/libxc/xenctrl.h

index 98ca5ed49e8cc26bab2565cbf72acfca83d56a7c..a9c5cff6facd1ac1a55e19c0d0cf0ab9442f6a3c 100644 (file)
@@ -478,38 +478,65 @@ int xc_domain_pin_memory_cacheattr(xc_interface *xch,
 }
 
 #if defined(__i386__) || defined(__x86_64__)
-#include "xc_e820.h"
-int xc_domain_set_memmap_limit(xc_interface *xch,
+int xc_domain_set_memory_map(xc_interface *xch,
                                uint32_t domid,
-                               unsigned long map_limitkb)
+                               struct e820entry entries[],
+                               uint32_t nr_entries)
 {
     int rc;
     struct xen_foreign_memory_map fmap = {
         .domid = domid,
-        .map = { .nr_entries = 1 }
+        .map = { .nr_entries = nr_entries }
     };
-    DECLARE_HYPERCALL_BUFFER(struct e820entry, e820);
-
-    e820 = xc_hypercall_buffer_alloc(xch, e820, sizeof(*e820));
+    DECLARE_HYPERCALL_BOUNCE(entries, nr_entries * sizeof(struct e820entry),
+                             XC_HYPERCALL_BUFFER_BOUNCE_IN);
 
-    if ( e820 == NULL )
-    {
-        PERROR("Could not allocate memory for xc_domain_set_memmap_limit hypercall");
+    if ( !entries || xc_hypercall_bounce_pre(xch, entries) )
         return -1;
-    }
-
-    e820->addr = 0;
-    e820->size = (uint64_t)map_limitkb << 10;
-    e820->type = E820_RAM;
 
-    set_xen_guest_handle(fmap.map.buffer, e820);
+    set_xen_guest_handle(fmap.map.buffer, entries);
 
     rc = do_memory_op(xch, XENMEM_set_memory_map, &fmap, sizeof(fmap));
 
-    xc_hypercall_buffer_free(xch, e820);
+    xc_hypercall_bounce_post(xch, entries);
 
     return rc;
 }
+int xc_get_machine_memory_map(xc_interface *xch,
+                              struct e820entry entries[],
+                              uint32_t max_entries)
+{
+    int rc;
+    struct xen_memory_map memmap = {
+        .nr_entries = max_entries
+    };
+    DECLARE_HYPERCALL_BOUNCE(entries, sizeof(struct e820entry) * max_entries,
+                             XC_HYPERCALL_BUFFER_BOUNCE_OUT);
+
+    if ( !entries || xc_hypercall_bounce_pre(xch, entries) || max_entries <= 1)
+        return -1;
+
+
+    set_xen_guest_handle(memmap.buffer, entries);
+
+    rc = do_memory_op(xch, XENMEM_machine_memory_map, &memmap, sizeof(memmap));
+
+    xc_hypercall_bounce_post(xch, entries);
+
+    return rc ? rc : memmap.nr_entries;
+}
+int xc_domain_set_memmap_limit(xc_interface *xch,
+                               uint32_t domid,
+                               unsigned long map_limitkb)
+{
+    struct e820entry e820;
+
+    e820.addr = 0;
+    e820.size = (uint64_t)map_limitkb << 10;
+    e820.type = E820_RAM;
+
+    return xc_domain_set_memory_map(xch, domid, &e820, 1);
+}
 #else
 int xc_domain_set_memmap_limit(xc_interface *xch,
                                uint32_t domid,
index 5207a9da43ef41fc66cba02868e0a5ebe929e3cb..fadfe73f2a3f3572a96e5a46b666192b3a79525a 100644 (file)
@@ -26,6 +26,9 @@
 #define E820_RESERVED     2
 #define E820_ACPI         3
 #define E820_NVS          4
+#define E820_UNUSABLE     5
+
+#define E820MAX           (128)
 
 struct e820entry {
     uint64_t addr;
index 9a4355f79ce7d27f378faaffb5e3d8b44103f207..0c4c6fb3997daea88e9c68fed2032a2bf7d115fb 100644 (file)
@@ -966,6 +966,17 @@ int xc_domain_set_memmap_limit(xc_interface *xch,
                                uint32_t domid,
                                unsigned long map_limitkb);
 
+#if defined(__i386__) || defined(__x86_64__)
+#include "xc_e820.h"
+int xc_domain_set_memory_map(xc_interface *xch,
+                               uint32_t domid,
+                               struct e820entry entries[],
+                               uint32_t nr_entries);
+
+int xc_get_machine_memory_map(xc_interface *xch,
+                              struct e820entry entries[],
+                              uint32_t max_entries);
+#endif
 int xc_domain_set_time_offset(xc_interface *xch,
                               uint32_t domid,
                               int32_t time_offset_seconds);