diff --git a/tools/libs/foreignmemory/Makefile b/tools/libs/foreignmemory/Makefile
index 2f2caa1..5e93ee7 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 b79ec1a..5f730ca 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 0ebd429..a6897dc 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 f6cd08c..dec4474 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 d5be648..a780d14 100644
--- a/tools/libs/foreignmemory/include/xenforeignmemory.h
+++ b/tools/libs/foreignmemory/include/xenforeignmemory.h
@@ -108,6 +108,18 @@ void *xenforeignmemory_map(xenforeignmemory_handle *fmem, uint32_t dom,
                            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().
  *
  * Returns 0 on success on failure sets errno and returns -1.
diff --git a/tools/libs/foreignmemory/libxenforeignmemory.map b/tools/libs/foreignmemory/libxenforeignmemory.map
index 41a8899..716ecaf 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 320bb21..374e45a 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 2dd4910..75f3401 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 af3a1a4..9bf95ef 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 ed7ec7a..c5c07cc 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 fe7bb45..a33decb 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;
 
