diff mbox series

[1/2] libs/foreignmemory: implement the missing functions on FreeBSD

Message ID 20210105102546.88462-2-roger.pau@citrix.com (mailing list archive)
State New
Headers show
Series libs: implement some missing functions on FreeBSD | expand

Commit Message

Roger Pau Monné Jan. 5, 2021, 10:25 a.m. UTC
Implement restrict, map resource and unmap resource helpers on
FreeBSD.

Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
---
Note the implementation is fairly similar to the Linux one, so could
likely be merged with some ifdefary. Note sure it's worth it given
that we already have a split file.
---
 tools/include/xen-sys/FreeBSD/privcmd.h | 14 +++++++
 tools/libs/foreignmemory/freebsd.c      | 51 +++++++++++++++++++++++++
 tools/libs/foreignmemory/private.h      |  2 +-
 3 files changed, 66 insertions(+), 1 deletion(-)
diff mbox series

Patch

diff --git a/tools/include/xen-sys/FreeBSD/privcmd.h b/tools/include/xen-sys/FreeBSD/privcmd.h
index cf1241f039..603aad67d5 100644
--- a/tools/include/xen-sys/FreeBSD/privcmd.h
+++ b/tools/include/xen-sys/FreeBSD/privcmd.h
@@ -56,9 +56,23 @@  typedef struct privcmd_mmap_entry {
 	unsigned long npages;
 } privcmd_mmap_entry_t;
 
+struct ioctl_privcmd_mmapresource {
+	domid_t dom; /* target domain */
+	unsigned int type; /* type of resource to map */
+	unsigned int id; /* type-specific resource identifier */
+	unsigned int idx; /* the index of the initial frame to be mapped */
+	unsigned long num; /* number of frames of the resource to be mapped */
+	unsigned long addr; /* physical address to map into */
+};
+typedef struct ioctl_privcmd_mmapresource privcmd_mmap_resource_t;
+
 #define IOCTL_PRIVCMD_HYPERCALL					\
 	_IOWR('E', 0, struct ioctl_privcmd_hypercall)
 #define IOCTL_PRIVCMD_MMAPBATCH					\
 	_IOWR('E', 1, struct ioctl_privcmd_mmapbatch)
+#define IOCTL_PRIVCMD_MMAP_RESOURCE				\
+	_IOW('E', 2, struct ioctl_privcmd_mmapresource)
+#define IOCTL_PRIVCMD_RESTRICT					\
+	_IOW('E', 4, domid_t)
 
 #endif /* !__XEN_PRIVCMD_H__ */
diff --git a/tools/libs/foreignmemory/freebsd.c b/tools/libs/foreignmemory/freebsd.c
index 6e6bc4b11f..3d403a7cd0 100644
--- a/tools/libs/foreignmemory/freebsd.c
+++ b/tools/libs/foreignmemory/freebsd.c
@@ -95,6 +95,57 @@  int osdep_xenforeignmemory_unmap(xenforeignmemory_handle *fmem,
     return munmap(addr, num << PAGE_SHIFT);
 }
 
+int osdep_xenforeignmemory_restrict(xenforeignmemory_handle *fmem,
+                                    domid_t domid)
+{
+    return ioctl(fmem->fd, IOCTL_PRIVCMD_RESTRICT, &domid);
+}
+
+int osdep_xenforeignmemory_unmap_resource(xenforeignmemory_handle *fmem,
+                                        xenforeignmemory_resource_handle *fres)
+{
+    return fres ? munmap(fres->addr, fres->nr_frames << PAGE_SHIFT) : 0;
+}
+
+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 != ENOSYS )
+            PERROR("mmap resource ioctl failed");
+        else
+            errno = EOPNOTSUPP;
+
+        saved_errno = errno;
+        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 8f1bf081ed..ebd45c4785 100644
--- a/tools/libs/foreignmemory/private.h
+++ b/tools/libs/foreignmemory/private.h
@@ -54,7 +54,7 @@  struct xenforeignmemory_resource_handle {
     int flags;
 };
 
-#ifndef __linux__
+#if !defined(__linux__) && !defined(__FreeBSD__)
 static inline int osdep_xenforeignmemory_restrict(xenforeignmemory_handle *fmem,
                                                   domid_t domid)
 {