From 81960d0698de363aba5f4e2deff46bbcb7fc0a56 Mon Sep 17 00:00:00 2001 From: Ian Campbell Date: Tue, 2 Feb 2016 16:50:47 +0000 Subject: [PATCH] libxendevicemodel: add ability to populate guest RAM regions XXX behaviour on partial success needs to be better defined (and/or sane) Signed-off-by: Ian Campbell --- tools/libs/devicemodel/core.c | 54 +++++++++++++++++++ .../libs/devicemodel/include/xendevicemodel.h | 24 +++++++++ tools/libs/devicemodel/libxendevicemodel.map | 2 + tools/libs/devicemodel/private.h | 1 + 4 files changed, 81 insertions(+) diff --git a/tools/libs/devicemodel/core.c b/tools/libs/devicemodel/core.c index 361ea96604..5ac15d7094 100644 --- a/tools/libs/devicemodel/core.c +++ b/tools/libs/devicemodel/core.c @@ -162,6 +162,60 @@ int xendevicemodel_s3_awaken(xendevicemodel_handle *dm) return set_s3_state(dm, 0, "s3 awaken"); } +int xendevicemodel_populate_ram(xendevicemodel_handle *dm, + xen_pfn_t start_gpfn, size_t nr_pages) +{ + xen_memory_reservation_t *arg = NULL; + xen_pfn_t *pfns = NULL; + size_t i, ret = -1; + + arg = xencall_alloc_buffer(dm->call, sizeof(*arg)); + if ( arg == NULL ) + { + LOGE(ERROR, "unable to allocate memory for populate ram hypercall"); + goto err; + } + + pfns = xencall_alloc_buffer(dm->call, sizeof(*pfns) * nr_pages); + if ( pfns == NULL ) + { + LOGE(ERROR, "unable to allocate memory for populate ram hypercall pfns"); + goto err; + } + + for (i = 0; i < nr_pages; i++) + pfns[i] = start_gpfn + i; + + arg->domid = dm->domid; + arg->nr_extents = nr_pages; + arg->extent_order = 0; + arg->mem_flags = 0; + set_xen_guest_handle(arg->extent_start, pfns); + + ret = xencall2(dm->call, __HYPERVISOR_memory_op, + XENMEM_populate_physmap, + (uintptr_t)arg); + + if ( ret == nr_pages ) + ret = 0; /* success */ + else if ( ret >= 0 ) + { + LOG(ERROR, "populate ram partial success %zd/%zd pages", ret, nr_pages); + ret = -1; + errno = -EBUSY; + } + else + { + LOGE(ERROR, "populate ram hypercall failed"); + ret = -1; + } + + err: + xencall_free_buffer(dm->call, pfns); + xencall_free_buffer(dm->call, arg); + + return ret; +} /* * Local variables: diff --git a/tools/libs/devicemodel/include/xendevicemodel.h b/tools/libs/devicemodel/include/xendevicemodel.h index 991ea63279..fde7b8d942 100644 --- a/tools/libs/devicemodel/include/xendevicemodel.h +++ b/tools/libs/devicemodel/include/xendevicemodel.h @@ -137,6 +137,30 @@ int xendevicemodel_route_pci_intx_to_isa_irq(xendevicemodel_handle *dm, int xendevicemodel_set_isa_irq_level(xendevicemodel_handle *dm, uint8_t isa_irq, bool assert); +/* + * Memory handling + * =============== + */ + +/* + * Populate a region of guest physical address space with normal + * RAM. On success the entire region will have been populated and zero + * is returned. + * + * On failure -1 is returned and errno is set. The contents of the + * memory region is undefined and may contain partial success. + * + * Always logs on failure. + * + * XXX on partial failure xc_domain_populate_physmap_exact would + * return -1/EBUSY without undoing the partial success. This seems + * like a poor model to follow, note however that options for undoing + * are limited to de-populating the underlying area, which may not + * have been the initial state. + */ +int xendevicemodel_populate_ram(xendevicemodel_handle *dm, + xen_pfn_t start_gpfn, size_t nr_pages); + #endif /* * Local variables: diff --git a/tools/libs/devicemodel/libxendevicemodel.map b/tools/libs/devicemodel/libxendevicemodel.map index 085a189bca..2ac9bfb1a9 100644 --- a/tools/libs/devicemodel/libxendevicemodel.map +++ b/tools/libs/devicemodel/libxendevicemodel.map @@ -12,5 +12,7 @@ VERS_1.0 { xendevicemodel_route_pci_intx_to_isa_irq; xendevicemodel_set_isa_irq_level; + xendevicemodel_populate_ram; + local: *; /* Do not expose anything by default */ }; diff --git a/tools/libs/devicemodel/private.h b/tools/libs/devicemodel/private.h index 93cf2ed48d..b6b09dfdbf 100644 --- a/tools/libs/devicemodel/private.h +++ b/tools/libs/devicemodel/private.h @@ -7,6 +7,7 @@ #include #include +#include #include struct xendevicemodel_handle { -- 2.39.5