diff options
-rw-r--r-- | tools/libxc/xc_hcall_buf.c | 47 | ||||
-rw-r--r-- | tools/libxc/xc_linux_osdep.c | 27 | ||||
-rw-r--r-- | tools/libxc/xc_minios.c | 14 | ||||
-rw-r--r-- | tools/libxc/xc_netbsd.c | 27 | ||||
-rw-r--r-- | tools/libxc/xc_solaris.c | 14 | ||||
-rw-r--r-- | tools/libxc/xenctrlosdep.h | 3 |
6 files changed, 95 insertions, 37 deletions
diff --git a/tools/libxc/xc_hcall_buf.c b/tools/libxc/xc_hcall_buf.c index d817d90ca1..ced9abd0e2 100644 --- a/tools/libxc/xc_hcall_buf.c +++ b/tools/libxc/xc_hcall_buf.c @@ -17,7 +17,7 @@ */ #include <stdlib.h> -#include <malloc.h> +#include <string.h> #include <pthread.h> #include "xc_private.h" @@ -95,15 +95,6 @@ static int hypercall_buffer_cache_free(xc_interface *xch, void *p, int nr_pages) return rc; } -static void do_hypercall_buffer_free_pages(void *ptr, int nr_pages) -{ -#ifndef __sun__ - (void) munlock(ptr, nr_pages * PAGE_SIZE); -#endif - - free(ptr); -} - void xc__hypercall_buffer_cache_release(xc_interface *xch) { void *p; @@ -126,7 +117,7 @@ void xc__hypercall_buffer_cache_release(xc_interface *xch) while ( xch->hypercall_buffer_cache_nr > 0 ) { p = xch->hypercall_buffer_cache[--xch->hypercall_buffer_cache_nr]; - do_hypercall_buffer_free_pages(p, 1); + xch->ops->u.privcmd.free_hypercall_buffer(xch, xch->ops_handle, p, 1); } hypercall_buffer_cache_unlock(xch); @@ -134,36 +125,18 @@ void xc__hypercall_buffer_cache_release(xc_interface *xch) void *xc__hypercall_buffer_alloc_pages(xc_interface *xch, xc_hypercall_buffer_t *b, int nr_pages) { - size_t size = nr_pages * PAGE_SIZE; void *p = hypercall_buffer_cache_alloc(xch, nr_pages); - if ( !p ) { -#if defined(_POSIX_C_SOURCE) && !defined(__sun__) - int ret; - ret = posix_memalign(&p, PAGE_SIZE, size); - if (ret != 0) - return NULL; -#elif defined(__NetBSD__) || defined(__OpenBSD__) - p = valloc(size); -#else - p = memalign(PAGE_SIZE, size); -#endif - - if (!p) - return NULL; - -#ifndef __sun__ - if ( mlock(p, size) < 0 ) - { - free(p); - return NULL; - } -#endif - } + if ( !p ) + p = xch->ops->u.privcmd.alloc_hypercall_buffer(xch, xch->ops_handle, nr_pages); + + if (!p) + return NULL; b->hbuf = p; - memset(p, 0, size); + memset(p, 0, nr_pages * PAGE_SIZE); + return b->hbuf; } @@ -173,7 +146,7 @@ void xc__hypercall_buffer_free_pages(xc_interface *xch, xc_hypercall_buffer_t *b return; if ( !hypercall_buffer_cache_free(xch, b->hbuf, nr_pages) ) - do_hypercall_buffer_free_pages(b->hbuf, nr_pages); + xch->ops->u.privcmd.free_hypercall_buffer(xch, xch->ops_handle, b->hbuf, nr_pages); } struct allocation_header { diff --git a/tools/libxc/xc_linux_osdep.c b/tools/libxc/xc_linux_osdep.c index 377c93867a..dca6718370 100644 --- a/tools/libxc/xc_linux_osdep.c +++ b/tools/libxc/xc_linux_osdep.c @@ -86,6 +86,30 @@ static int linux_privcmd_close(xc_interface *xch, xc_osdep_handle h) return close(fd); } +static void *linux_privcmd_alloc_hypercall_buffer(xc_interface *xch, xc_osdep_handle h, int npages) +{ + size_t size = npages * XC_PAGE_SIZE; + void *p; + int ret; + + ret = posix_memalign(&p, XC_PAGE_SIZE, size); + if (ret != 0 || !p) + return NULL; + + if ( mlock(p, size) < 0 ) + { + free(p); + return NULL; + } + return p; +} + +static void linux_privcmd_free_hypercall_buffer(xc_interface *xch, xc_osdep_handle h, void *ptr, int npages) +{ + (void) munlock(ptr, npages * XC_PAGE_SIZE); + free(ptr); +} + static int linux_privcmd_hypercall(xc_interface *xch, xc_osdep_handle h, privcmd_hypercall_t *hypercall) { int fd = (int)h; @@ -344,6 +368,9 @@ static struct xc_osdep_ops linux_privcmd_ops = { .close = &linux_privcmd_close, .u.privcmd = { + .alloc_hypercall_buffer = &linux_privcmd_alloc_hypercall_buffer, + .free_hypercall_buffer = &linux_privcmd_free_hypercall_buffer, + .hypercall = &linux_privcmd_hypercall, .map_foreign_batch = &linux_privcmd_map_foreign_batch, diff --git a/tools/libxc/xc_minios.c b/tools/libxc/xc_minios.c index db8d3b8810..3b366eb824 100644 --- a/tools/libxc/xc_minios.c +++ b/tools/libxc/xc_minios.c @@ -37,6 +37,7 @@ #include <assert.h> #include <stdint.h> #include <inttypes.h> +#include <malloc.h> #include "xc_private.h" @@ -70,6 +71,16 @@ void minios_interface_close_fd(int fd) files[fd].type = FTYPE_NONE; } +static void *minios_privcmd_alloc_hypercall_buffer(xc_interface *xch, xc_osdep_handle h, int npages) +{ + return memalign(PAGE_SIZE, npages * PAGE_SIZE); +} + +static void minios_privcmd_free_hypercall_buffer(xc_interface *xch, xc_osdep_handle h, void *ptr, int npages) +{ + free(ptr); +} + static int minios_privcmd_hypercall(xc_interface *xch, xc_osdep_handle h, privcmd_hypercall_t *hypercall) { multicall_entry_t call; @@ -187,6 +198,9 @@ static struct xc_osdep_ops minios_privcmd_ops = { .close = &minios_privcmd_close, .u.privcmd = { + .alloc_hypercall_buffer = &minios_privcmd_alloc_hypercall_buffer, + .free_hypercall_buffer = &minios_privcmd_free_hypercall_buffer, + .hypercall = &minios_privcmd_hypercall, .map_foreign_batch = &minios_privcmd_map_foreign_batch, diff --git a/tools/libxc/xc_netbsd.c b/tools/libxc/xc_netbsd.c index 8c82e36645..72e1c28517 100644 --- a/tools/libxc/xc_netbsd.c +++ b/tools/libxc/xc_netbsd.c @@ -23,6 +23,8 @@ #include <xen/sys/evtchn.h> #include <unistd.h> #include <fcntl.h> +#include <malloc.h> +#include <sys/mman.h> static xc_osdep_handle netbsd_privcmd_open(xc_interface *xch) { @@ -66,6 +68,28 @@ static int netbsd_privcmd_close(xc_interface *xch, xc_osdep_handle h) return close(fd); } +static void *netbsd_privcmd_alloc_hypercall_buffer(xc_interface *xch, xc_osdep_handle h, int npages) +{ + size_t size = npages * XC_PAGE_SIZE; + void *p = valloc(size); + + if (!p) + return NULL; + + if ( mlock(p, size) < 0 ) + { + free(p); + return NULL; + } + return p; +} + +static void netbsd_privcmd_free_hypercall_buffer(xc_interface *xch, xc_osdep_handle h, void *ptr, int npages) +{ + (void) munlock(ptr, npages * XC_PAGE_SIZE); + free(ptr); +} + static int netbsd_privcmd_hypercall(xc_interface *xch, xc_osdep_handle h, privcmd_hypercall_t *hypercall) { int fd = (int)h; @@ -181,6 +205,9 @@ static struct xc_osdep_ops netbsd_privcmd_ops = { .close = &netbsd_privcmd_close, .u.privcmd = { + .alloc_hypercall_buffer = &netbsd_privcmd_alloc_hypercall_buffer, + .free_hypercall_buffer = &netbsd_privcmd_free_hypercall_buffer, + .hypercall = &netbsd_privcmd_hypercall, .map_foreign_batch = &netbsd_privcmd_map_foreign_batch, diff --git a/tools/libxc/xc_solaris.c b/tools/libxc/xc_solaris.c index 981c272951..9de8505bb6 100644 --- a/tools/libxc/xc_solaris.c +++ b/tools/libxc/xc_solaris.c @@ -24,6 +24,7 @@ #include <xen/sys/evtchn.h> #include <unistd.h> #include <fcntl.h> +#include <malloc.h> static xc_osdep_handle solaris_privcmd_open(xc_interface *xch) { @@ -67,6 +68,16 @@ static int solaris_privcmd_close(xc_interface *xch, xc_osdep_handle h) return close(fd); } +static void *solaris_privcmd_alloc_hypercall_buffer(xc_interface *xch, xc_osdep_handle h, int npages) +{ + return memalign(XC_PAGE_SIZE, npages * XC_PAGE_SIZE); +} + +static void solaris_privcmd_free_hypercall_buffer(xc_interface *xch, xc_osdep_handle h, void *ptr, int npages) +{ + free(ptr); +} + static int solaris_privcmd_hypercall(xc_interface *xch, xc_osdep_handle h, privcmd_hypercall_t *hypercall) { int fd = (int)h; @@ -172,6 +183,9 @@ static struct xc_osdep_ops solaris_privcmd_ops = { .close = &solaris_privcmd_close, .u.privcmd = { + .alloc_hypercall_buffer = &solaris_privcmd_alloc_hypercall_buffer, + .free_hypercall_buffer = &solaris_privcmd_free_hypercall_buffer, + .hypercall = &solaris_privcmd_hypercall; .map_foreign_batch = &solaris_privcmd_map_foreign_batch, diff --git a/tools/libxc/xenctrlosdep.h b/tools/libxc/xenctrlosdep.h index efdc3b37de..bfe46e02fc 100644 --- a/tools/libxc/xenctrlosdep.h +++ b/tools/libxc/xenctrlosdep.h @@ -74,6 +74,9 @@ struct xc_osdep_ops union { struct { + void *(*alloc_hypercall_buffer)(xc_interface *xch, xc_osdep_handle h, int npages); + void (*free_hypercall_buffer)(xc_interface *xch, xc_osdep_handle h, void *ptr, int npages); + int (*hypercall)(xc_interface *xch, xc_osdep_handle h, privcmd_hypercall_t *hypercall); void *(*map_foreign_batch)(xc_interface *xch, xc_osdep_handle h, uint32_t dom, int prot, |