# HG changeset patch # Parent 476b0d68e7d5405babc1182da3b345b1e4cc1bca libxc: xc_domain_set_memory_map, xc_get_machine_memory_map (x86, amd64 only) The later retrieves the E820 as seen by the hypervisor (completely unchanged) and the second call sets the E820 for the specified guest. [backport of c/s 23412] Signed-off-by: Konrad Rzeszutek Wilk diff -r 476b0d68e7d5 tools/libxc/xc_domain.c --- a/tools/libxc/xc_domain.c Sat Apr 30 09:48:16 2011 +0100 +++ b/tools/libxc/xc_domain.c Wed May 04 08:57:40 2011 -0400 @@ -478,37 +478,64 @@ int xc_domain_pin_memory_cacheattr(xc_in } #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 rc; + struct xen_foreign_memory_map fmap = { + .domid = domid, + .map = { .nr_entries = nr_entries } + }; + DECLARE_HYPERCALL_BOUNCE(entries, nr_entries * sizeof(struct e820entry), + XC_HYPERCALL_BUFFER_BOUNCE_IN); + + if ( !entries || xc_hypercall_bounce_pre(xch, entries) ) + return -1; + + set_xen_guest_handle(fmap.map.buffer, entries); + + rc = do_memory_op(xch, XENMEM_set_memory_map, &fmap, sizeof(fmap)); + + 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) { - int rc; - struct xen_foreign_memory_map fmap = { - .domid = domid, - .map = { .nr_entries = 1 } - }; - DECLARE_HYPERCALL_BUFFER(struct e820entry, e820); + struct e820entry e820; - e820 = xc_hypercall_buffer_alloc(xch, e820, sizeof(*e820)); + e820.addr = 0; + e820.size = (uint64_t)map_limitkb << 10; + e820.type = E820_RAM; - if ( e820 == NULL ) - { - PERROR("Could not allocate memory for xc_domain_set_memmap_limit hypercall"); - return -1; - } - - e820->addr = 0; - e820->size = (uint64_t)map_limitkb << 10; - e820->type = E820_RAM; - - set_xen_guest_handle(fmap.map.buffer, e820); - - rc = do_memory_op(xch, XENMEM_set_memory_map, &fmap, sizeof(fmap)); - - xc_hypercall_buffer_free(xch, e820); - - return rc; + return xc_domain_set_memory_map(xch, domid, &e820, 1); } #else int xc_domain_set_memmap_limit(xc_interface *xch, diff -r 476b0d68e7d5 tools/libxc/xc_e820.h --- a/tools/libxc/xc_e820.h Sat Apr 30 09:48:16 2011 +0100 +++ b/tools/libxc/xc_e820.h Wed May 04 08:57:40 2011 -0400 @@ -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; diff -r 476b0d68e7d5 tools/libxc/xenctrl.h --- a/tools/libxc/xenctrl.h Sat Apr 30 09:48:16 2011 +0100 +++ b/tools/libxc/xenctrl.h Wed May 04 08:57:40 2011 -0400 @@ -966,6 +966,17 @@ int xc_domain_set_memmap_limit(xc_interf 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);