|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen master] tools/libxenforeignmemory: add support for resource mapping
commit 3ae275169e58d6485d6ae55e4a6f0205771a536b
Author: Paul Durrant <paul.durrant@xxxxxxxxxx>
AuthorDate: Mon Jul 31 16:28:39 2017 +0100
Commit: Wei Liu <wei.liu2@xxxxxxxxxx>
CommitDate: Tue Apr 3 17:05:12 2018 +0100
tools/libxenforeignmemory: add support for resource mapping
A previous patch introduced a new HYPERVISOR_memory_op to acquire guest
resources for direct priv-mapping.
This patch adds new functionality into libxenforeignmemory to make use
of a new privcmd ioctl [1] that uses the new memory op to make such
resources available via mmap(2).
[1]
http://xenbits.xen.org/gitweb/?p=people/pauldu/linux.git;a=commit;h=ce59a05e6712
Signed-off-by: Paul Durrant <paul.durrant@xxxxxxxxxx>
Reviewed-by: Roger Pau Monné <roger.pau@xxxxxxxxxx>
Reviewed-by: Wei Liu <wei.liu2@xxxxxxxxxx>
---
tools/include/xen-sys/Linux/privcmd.h | 11 +++++
tools/libs/foreignmemory/Makefile | 2 +-
tools/libs/foreignmemory/core.c | 53 ++++++++++++++++++++++
.../libs/foreignmemory/include/xenforeignmemory.h | 41 +++++++++++++++++
tools/libs/foreignmemory/libxenforeignmemory.map | 5 ++
tools/libs/foreignmemory/linux.c | 45 ++++++++++++++++++
tools/libs/foreignmemory/private.h | 31 +++++++++++++
7 files changed, 187 insertions(+), 1 deletion(-)
diff --git a/tools/include/xen-sys/Linux/privcmd.h
b/tools/include/xen-sys/Linux/privcmd.h
index 732ff7c15a..9531b728f9 100644
--- a/tools/include/xen-sys/Linux/privcmd.h
+++ b/tools/include/xen-sys/Linux/privcmd.h
@@ -86,6 +86,15 @@ typedef struct privcmd_dm_op {
const privcmd_dm_op_buf_t __user *ubufs;
} privcmd_dm_op_t;
+typedef struct privcmd_mmap_resource {
+ domid_t dom;
+ __u32 type;
+ __u32 id;
+ __u32 idx;
+ __u64 num;
+ __u64 addr;
+} privcmd_mmap_resource_t;
+
/*
* @cmd: IOCTL_PRIVCMD_HYPERCALL
* @arg: &privcmd_hypercall_t
@@ -103,5 +112,7 @@ typedef struct privcmd_dm_op {
_IOC(_IOC_NONE, 'P', 5, sizeof(privcmd_dm_op_t))
#define IOCTL_PRIVCMD_RESTRICT \
_IOC(_IOC_NONE, 'P', 6, sizeof(domid_t))
+#define IOCTL_PRIVCMD_MMAP_RESOURCE \
+ _IOC(_IOC_NONE, 'P', 7, sizeof(privcmd_mmap_resource_t))
#endif /* __LINUX_PUBLIC_PRIVCMD_H__ */
diff --git a/tools/libs/foreignmemory/Makefile
b/tools/libs/foreignmemory/Makefile
index cbe815fce8..ee5c3fd67e 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 = 2
+MINOR = 3
SHLIB_LDFLAGS += -Wl,--version-script=libxenforeignmemory.map
CFLAGS += -Werror -Wmissing-prototypes
diff --git a/tools/libs/foreignmemory/core.c b/tools/libs/foreignmemory/core.c
index 7c8562ae74..63f12e2450 100644
--- a/tools/libs/foreignmemory/core.c
+++ b/tools/libs/foreignmemory/core.c
@@ -17,6 +17,8 @@
#include <assert.h>
#include <errno.h>
+#include <sys/mman.h>
+
#include "private.h"
static int all_restrict_cb(Xentoolcore__Active_Handle *ah, domid_t domid) {
@@ -135,6 +137,57 @@ int xenforeignmemory_restrict(xenforeignmemory_handle
*fmem,
return osdep_xenforeignmemory_restrict(fmem, domid);
}
+xenforeignmemory_resource_handle *xenforeignmemory_map_resource(
+ xenforeignmemory_handle *fmem, domid_t domid, unsigned int type,
+ unsigned int id, unsigned long frame, unsigned long nr_frames,
+ void **paddr, int prot, int flags)
+{
+ xenforeignmemory_resource_handle *fres;
+ int rc;
+
+ /* Check flags only contains POSIX defined values */
+ if ( flags & ~(MAP_SHARED | MAP_PRIVATE) )
+ {
+ errno = EINVAL;
+ return NULL;
+ }
+
+ fres = calloc(1, sizeof(*fres));
+ if ( !fres )
+ {
+ errno = ENOMEM;
+ return NULL;
+ }
+
+ fres->domid = domid;
+ fres->type = type;
+ fres->id = id;
+ fres->frame = frame;
+ fres->nr_frames = nr_frames;
+ fres->addr = *paddr;
+ fres->prot = prot;
+ fres->flags = flags;
+
+ rc = osdep_xenforeignmemory_map_resource(fmem, fres);
+ if ( rc )
+ {
+ free(fres);
+ fres = NULL;
+ } else
+ *paddr = fres->addr;
+
+ return fres;
+}
+
+int xenforeignmemory_unmap_resource(
+ xenforeignmemory_handle *fmem, xenforeignmemory_resource_handle *fres)
+{
+ int rc = osdep_xenforeignmemory_unmap_resource(fmem, fres);
+
+ free(fres);
+ return rc;
+}
+
/*
* Local variables:
* mode: C
diff --git a/tools/libs/foreignmemory/include/xenforeignmemory.h
b/tools/libs/foreignmemory/include/xenforeignmemory.h
index f4814c390f..d594be8df0 100644
--- a/tools/libs/foreignmemory/include/xenforeignmemory.h
+++ b/tools/libs/foreignmemory/include/xenforeignmemory.h
@@ -138,6 +138,47 @@ int xenforeignmemory_unmap(xenforeignmemory_handle *fmem,
int xenforeignmemory_restrict(xenforeignmemory_handle *fmem,
domid_t domid);
+typedef struct xenforeignmemory_resource_handle
xenforeignmemory_resource_handle;
+
+/**
+ * This function maps a guest resource.
+ *
+ * @parm fmem handle to the open foreignmemory interface
+ * @parm domid the domain id
+ * @parm type the resource type
+ * @parm id the type-specific resource identifier
+ * @parm frame base frame index within the resource
+ * @parm nr_frames number of frames to map
+ * @parm paddr pointer to an address passed through to mmap(2)
+ * @parm prot passed through to mmap(2)
+ * @parm POSIX-only flags passed through to mmap(2)
+ * @return pointer to foreignmemory resource handle on success, NULL on
+ * failure
+ *
+ * *paddr is used, on entry, as a hint address for foreign map placement
+ * (see mmap(2)) so should be set to NULL if no specific placement is
+ * required. On return *paddr contains the address where the resource is
+ * mapped.
+ * As for xenforeignmemory_map2() flags is a set of additional flags
+ * for mmap(2). Not all of the flag combinations are possible due to
+ * implementation details on different platforms.
+ */
+xenforeignmemory_resource_handle *xenforeignmemory_map_resource(
+ xenforeignmemory_handle *fmem, domid_t domid, unsigned int type,
+ unsigned int id, unsigned long frame, unsigned long nr_frames,
+ void **paddr, int prot, int flags);
+
+/**
+ * This function releases a previously acquired resource.
+ *
+ * @parm fmem handle to the open foreignmemory interface
+ * @parm fres handle to the acquired resource
+ *
+ * Returns 0 on success on failure sets errno and returns -1.
+ */
+int xenforeignmemory_unmap_resource(
+ xenforeignmemory_handle *fmem, xenforeignmemory_resource_handle *fres);
+
#endif
/*
diff --git a/tools/libs/foreignmemory/libxenforeignmemory.map
b/tools/libs/foreignmemory/libxenforeignmemory.map
index 716ecaf15c..d5323c87d9 100644
--- a/tools/libs/foreignmemory/libxenforeignmemory.map
+++ b/tools/libs/foreignmemory/libxenforeignmemory.map
@@ -14,3 +14,8 @@ VERS_1.2 {
global:
xenforeignmemory_map2;
} VERS_1.1;
+VERS_1.3 {
+ global:
+ xenforeignmemory_map_resource;
+ xenforeignmemory_unmap_resource;
+} VERS_1.2;
diff --git a/tools/libs/foreignmemory/linux.c b/tools/libs/foreignmemory/linux.c
index 374e45aed5..a6b41b0b7f 100644
--- a/tools/libs/foreignmemory/linux.c
+++ b/tools/libs/foreignmemory/linux.c
@@ -277,6 +277,51 @@ int
osdep_xenforeignmemory_restrict(xenforeignmemory_handle *fmem,
return ioctl(fmem->fd, IOCTL_PRIVCMD_RESTRICT, &domid);
}
+int osdep_xenforeignmemory_unmap_resource(
+ xenforeignmemory_handle *fmem, xenforeignmemory_resource_handle *fres)
+{
+ return munmap(fres->addr, fres->nr_frames << PAGE_SHIFT);
+}
+
+int osdep_xenforeignmemory_map_resource(
+ xenforeignmemory_handle *fmem, xenforeignmemory_resource_handle *fres)
+{
+ privcmd_mmap_resource_t mr = {
+ .dom = fres->domid,
+ .type = fres->type,
+ .id = fres->id,
+ .idx = fres->frame,
+ .num = fres->nr_frames,
+ };
+ int rc;
+
+ fres->addr = mmap(fres->addr, fres->nr_frames << PAGE_SHIFT,
+ fres->prot, fres->flags | MAP_SHARED, fmem->fd, 0);
+ if ( fres->addr == MAP_FAILED )
+ return -1;
+
+ mr.addr = (uintptr_t)fres->addr;
+
+ rc = ioctl(fmem->fd, IOCTL_PRIVCMD_MMAP_RESOURCE, &mr);
+ if ( rc )
+ {
+ int saved_errno;
+
+ if ( errno != ENOTTY )
+ PERROR("ioctl failed");
+ else
+ errno = EOPNOTSUPP;
+
+ saved_errno = errno;
+ (void)osdep_xenforeignmemory_unmap_resource(fmem, fres);
+ errno = saved_errno;
+
+ return -1;
+ }
+
+ return 0;
+}
+
/*
* Local variables:
* mode: C
diff --git a/tools/libs/foreignmemory/private.h
b/tools/libs/foreignmemory/private.h
index 2470f3c46c..b191000b49 100644
--- a/tools/libs/foreignmemory/private.h
+++ b/tools/libs/foreignmemory/private.h
@@ -45,6 +45,37 @@ void *compat_mapforeign_batch(xenforeignmem_handle *fmem,
uint32_t dom,
xen_pfn_t *arr, int num);
#endif
+struct xenforeignmemory_resource_handle {
+ domid_t domid;
+ unsigned int type;
+ unsigned int id;
+ unsigned long frame;
+ unsigned long nr_frames;
+ void *addr;
+ int prot;
+ int flags;
+};
+
+#ifndef __linux__
+static inline int osdep_xenforeignmemory_map_resource(
+ xenforeignmemory_handle *fmem, xenforeignmemory_resource_handle *fres)
+{
+ errno = EOPNOTSUPP;
+ return -1;
+}
+
+static inline int osdep_xenforeignmemory_unmap_resource(
+ xenforeignmemory_handle *fmem, xenforeignmemory_resource_handle *fres)
+{
+ return 0;
+}
+#else
+int osdep_xenforeignmemory_map_resource(
+ xenforeignmemory_handle *fmem, xenforeignmemory_resource_handle *fres);
+int osdep_xenforeignmemory_unmap_resource(
+ xenforeignmemory_handle *fmem, xenforeignmemory_resource_handle *fres);
+#endif
+
#define PERROR(_f...) \
xtl_log(fmem->logger, XTL_ERROR, errno, "xenforeignmemory", _f)
--
generated by git-patchbot for /home/xen/git/xen.git#master
_______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/xen-changelog
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |