diff --git a/tools/libs/foreignmemory/Makefile b/tools/libs/foreignmemory/Makefile index 2f2caa1f5c..5e93ee7d95 100644 --- a/tools/libs/foreignmemory/Makefile +++ b/tools/libs/foreignmemory/Makefile @@ -2,7 +2,7 @@ XEN_ROOT = $(CURDIR)/../../.. include $(XEN_ROOT)/tools/Rules.mk MAJOR = 1 -MINOR = 1 +MINOR = 2 SHLIB_LDFLAGS += -Wl,--version-script=libxenforeignmemory.map CFLAGS += -Werror -Wmissing-prototypes diff --git a/tools/libs/foreignmemory/compat.c b/tools/libs/foreignmemory/compat.c index b79ec1a9e7..5f730ca919 100644 --- a/tools/libs/foreignmemory/compat.c +++ b/tools/libs/foreignmemory/compat.c @@ -21,8 +21,8 @@ #include "private.h" -void *osdep_xenforeignmemory_map(xenforeignmemory_handle *fmem, - uint32_t dom, int prot, size_t num, +void *osdep_xenforeignmemory_map(xenforeignmemory_handle *fmem, uint32_t dom, + void *addr, int prot, int flags, size_t num, const xen_pfn_t arr[/*num*/], int err[/*num*/]) { xen_pfn_t *pfn; @@ -41,7 +41,7 @@ void *osdep_xenforeignmemory_map(xenforeignmemory_handle *fmem, } memcpy(pfn, arr, num * sizeof(*arr)); - ret = osdep_map_foreign_batch(fmem, dom, prot, pfn, num); + ret = osdep_map_foreign_batch(fmem, dom, addr, prot, flags, pfn, num); if (ret) { for (i = 0; i < num; ++i) diff --git a/tools/libs/foreignmemory/core.c b/tools/libs/foreignmemory/core.c index 0ebd4293b1..a6897dc561 100644 --- a/tools/libs/foreignmemory/core.c +++ b/tools/libs/foreignmemory/core.c @@ -63,10 +63,10 @@ int xenforeignmemory_close(xenforeignmemory_handle *fmem) return rc; } -void *xenforeignmemory_map(xenforeignmemory_handle *fmem, - uint32_t dom, int prot, - size_t num, - const xen_pfn_t arr[/*num*/], int err[/*num*/]) +void *xenforeignmemory_map2(xenforeignmemory_handle *fmem, + uint32_t dom, void *addr, + int prot, int flags, size_t num, + const xen_pfn_t arr[/*num*/], int err[/*num*/]) { void *ret; int *err_to_free = NULL; @@ -77,7 +77,7 @@ void *xenforeignmemory_map(xenforeignmemory_handle *fmem, if ( err == NULL ) return NULL; - ret = osdep_xenforeignmemory_map(fmem, dom, prot, num, arr, err); + ret = osdep_xenforeignmemory_map(fmem, dom, addr, prot, flags, num, arr, err); if ( ret && err_to_free ) { @@ -100,6 +100,14 @@ void *xenforeignmemory_map(xenforeignmemory_handle *fmem, return ret; } +void *xenforeignmemory_map(xenforeignmemory_handle *fmem, + uint32_t dom, int prot, + size_t num, + const xen_pfn_t arr[/*num*/], int err[/*num*/]) +{ + return xenforeignmemory_map2(fmem, dom, NULL, prot, 0, num, arr, err); +} + int xenforeignmemory_unmap(xenforeignmemory_handle *fmem, void *addr, size_t num) { diff --git a/tools/libs/foreignmemory/freebsd.c b/tools/libs/foreignmemory/freebsd.c index f6cd08c4c0..dec447485a 100644 --- a/tools/libs/foreignmemory/freebsd.c +++ b/tools/libs/foreignmemory/freebsd.c @@ -55,16 +55,15 @@ int osdep_xenforeignmemory_close(xenforeignmemory_handle *fmem) } void *osdep_xenforeignmemory_map(xenforeignmemory_handle *fmem, - uint32_t dom, int prot, - size_t num, + uint32_t dom, void *addr, + int prot, int flags, size_t num, const xen_pfn_t arr[/*num*/], int err[/*num*/]) { int fd = fmem->fd; privcmd_mmapbatch_t ioctlx; - void *addr; int rc; - addr = mmap(NULL, num << PAGE_SHIFT, prot, MAP_SHARED, fd, 0); + addr = mmap(addr, num << PAGE_SHIFT, prot, flags | MAP_SHARED, fd, 0); if ( addr == MAP_FAILED ) { PERROR("xc_map_foreign_bulk: mmap failed"); diff --git a/tools/libs/foreignmemory/include/xenforeignmemory.h b/tools/libs/foreignmemory/include/xenforeignmemory.h index d5be6481de..f4814c390f 100644 --- a/tools/libs/foreignmemory/include/xenforeignmemory.h +++ b/tools/libs/foreignmemory/include/xenforeignmemory.h @@ -107,6 +107,18 @@ void *xenforeignmemory_map(xenforeignmemory_handle *fmem, uint32_t dom, int prot, size_t pages, const xen_pfn_t arr[/*pages*/], int err[/*pages*/]); +/* + * Almost like the previous one but also accepts two additional parameters: + * + * @addr is used as a hint address for foreign map placement (see mmap(2)). + * @flags is a set of additional flags as for mmap(2). Not all of the flag + * combinations are possible due to implementation details on different + * platforms. + */ +void *xenforeignmemory_map2(xenforeignmemory_handle *fmem, uint32_t dom, + void *addr, int prot, int flags, size_t pages, + const xen_pfn_t arr[/*pages*/], int err[/*pages*/]); + /* * Unmap a mapping previous created with xenforeignmemory_map(). * diff --git a/tools/libs/foreignmemory/libxenforeignmemory.map b/tools/libs/foreignmemory/libxenforeignmemory.map index 41a88998e3..716ecaf15c 100644 --- a/tools/libs/foreignmemory/libxenforeignmemory.map +++ b/tools/libs/foreignmemory/libxenforeignmemory.map @@ -10,3 +10,7 @@ VERS_1.1 { global: xenforeignmemory_restrict; } VERS_1.0; +VERS_1.2 { + global: + xenforeignmemory_map2; +} VERS_1.1; diff --git a/tools/libs/foreignmemory/linux.c b/tools/libs/foreignmemory/linux.c index 320bb212fd..374e45aed5 100644 --- a/tools/libs/foreignmemory/linux.c +++ b/tools/libs/foreignmemory/linux.c @@ -142,17 +142,16 @@ out: } void *osdep_xenforeignmemory_map(xenforeignmemory_handle *fmem, - uint32_t dom, int prot, - size_t num, + uint32_t dom, void *addr, + int prot, int flags, size_t num, const xen_pfn_t arr[/*num*/], int err[/*num*/]) { int fd = fmem->fd; privcmd_mmapbatch_v2_t ioctlx; - void *addr; size_t i; int rc; - addr = mmap(NULL, num << PAGE_SHIFT, prot, MAP_SHARED, + addr = mmap(addr, num << PAGE_SHIFT, prot, flags | MAP_SHARED, fd, 0); if ( addr == MAP_FAILED ) { diff --git a/tools/libs/foreignmemory/minios.c b/tools/libs/foreignmemory/minios.c index 2dd4910663..75f340122e 100644 --- a/tools/libs/foreignmemory/minios.c +++ b/tools/libs/foreignmemory/minios.c @@ -40,8 +40,8 @@ int osdep_xenforeignmemory_close(xenforeignmemory_handle *fmem) } void *osdep_xenforeignmemory_map(xenforeignmemory_handle *fmem, - uint32_t dom, int prot, - size_t num, + uint32_t dom, void *addr, + int prot, int flags, size_t num, const xen_pfn_t arr[/*num*/], int err[/*num*/]) { unsigned long pt_prot = 0; diff --git a/tools/libs/foreignmemory/netbsd.c b/tools/libs/foreignmemory/netbsd.c index af3a1a4a0d..9bf95ef4f0 100644 --- a/tools/libs/foreignmemory/netbsd.c +++ b/tools/libs/foreignmemory/netbsd.c @@ -67,12 +67,12 @@ int osdep_xenforeignmemory_close(xenforeignmemory_handle *fmem) } void *osdep_map_foreign_batch(xenforeignmem_handle *fmem, uint32_t dom, - int prot, xen_pfn_t *arr, int num) + void *addr, int prot, int flags, + xen_pfn_t *arr, int num) { int fd = fmem->fd; privcmd_mmapbatch_t ioctlx; - void *addr; - addr = mmap(NULL, num*XC_PAGE_SIZE, prot, MAP_ANON | MAP_SHARED, -1, 0); + addr = mmap(addr, num*XC_PAGE_SIZE, prot, flags | MAP_ANON | MAP_SHARED, -1, 0); if ( addr == MAP_FAILED ) { PERROR("osdep_map_foreign_batch: mmap failed"); return NULL; diff --git a/tools/libs/foreignmemory/private.h b/tools/libs/foreignmemory/private.h index ed7ec7a43f..c5c07cc4c4 100644 --- a/tools/libs/foreignmemory/private.h +++ b/tools/libs/foreignmemory/private.h @@ -26,8 +26,8 @@ int osdep_xenforeignmemory_open(xenforeignmemory_handle *fmem); int osdep_xenforeignmemory_close(xenforeignmemory_handle *fmem); void *osdep_xenforeignmemory_map(xenforeignmemory_handle *fmem, - uint32_t dom, int prot, - size_t num, + uint32_t dom, void *addr, + int prot, int flags, size_t num, const xen_pfn_t arr[num], int err[num]); int osdep_xenforeignmemory_unmap(xenforeignmemory_handle *fmem, void *addr, size_t num); @@ -38,7 +38,8 @@ int osdep_xenforeignmemory_restrict(xenforeignmemory_handle *fmem, #if defined(__NetBSD__) || defined(__sun__) /* Strictly compat for those two only only */ void *compat_mapforeign_batch(xenforeignmem_handle *fmem, uint32_t dom, - int prot, xen_pfn_t *arr, int num); + void *addr, int prot, int flags, + xen_pfn_t *arr, int num); #endif #define PERROR(_f...) \ diff --git a/tools/libs/foreignmemory/solaris.c b/tools/libs/foreignmemory/solaris.c index fe7bb45e9e..a33decb4ae 100644 --- a/tools/libs/foreignmemory/solaris.c +++ b/tools/libs/foreignmemory/solaris.c @@ -68,12 +68,11 @@ int osdep_xenforeignmemory_close(xenforeignmemory_handle *fmem) } void *osdep_map_foreign_batch(xenforeignmem_handle *fmem, uint32_t dom, - int prot, xen_pfn_t *arr, int num) + void *addr, int prot, int flags, xen_pfn_t *arr, int num) { int fd = fmem->fd; privcmd_mmapbatch_t ioctlx; - void *addr; - addr = mmap(NULL, num*XC_PAGE_SIZE, prot, MAP_SHARED, fd, 0); + addr = mmap(addr, num*XC_PAGE_SIZE, prot, flags | MAP_SHARED, fd, 0); if ( addr == MAP_FAILED ) return NULL;