mirror of
https://github.com/Stichting-MINIX-Research-Foundation/pkgsrc-ng.git
synced 2025-09-27 22:11:24 -04:00
214 lines
5.2 KiB
Plaintext
214 lines
5.2 KiB
Plaintext
$NetBSD: patch-bb,v 1.1.1.1 2011/04/06 09:10:27 cegger Exp $
|
|
|
|
--- libxc/xc_netbsd.c.orig 2011-03-29 17:09:58.000000000 +0000
|
|
+++ libxc/xc_netbsd.c
|
|
@@ -21,6 +21,7 @@
|
|
#include "xc_private.h"
|
|
|
|
#include <xen/sys/evtchn.h>
|
|
+#include <xen/sys/gntdev.h>
|
|
#include <unistd.h>
|
|
#include <fcntl.h>
|
|
|
|
@@ -351,7 +352,189 @@ void discard_file_cache(xc_interface *xc
|
|
errno = saved_errno;
|
|
}
|
|
|
|
-static struct xc_osdep_ops *netbsd_osdep_init(xc_interface *xch, enum xc_osdep_type type)
|
|
+#define DEVXEN "/dev/xen/"
|
|
+
|
|
+static xc_osdep_handle
|
|
+netbsd_gnttab_open(xc_gnttab *xcg)
|
|
+{
|
|
+ int fd;
|
|
+
|
|
+ fd = open(DEVXEN "gntdev", O_RDWR);
|
|
+ if (fd == -1)
|
|
+ return XC_OSDEP_OPEN_ERROR;
|
|
+
|
|
+ return (xc_osdep_handle)fd;
|
|
+}
|
|
+
|
|
+static int
|
|
+netbsd_gnttab_close(xc_gnttab *xcg, xc_osdep_handle h)
|
|
+{
|
|
+ int fd = (int)h;
|
|
+ return close(fd);
|
|
+}
|
|
+
|
|
+static void *
|
|
+netbsd_gnttab_map_grant_ref(xc_gnttab *xch, xc_osdep_handle h,
|
|
+ uint32_t domid, uint32_t ref, int prot)
|
|
+{
|
|
+ int fd = (int)h;
|
|
+ struct ioctl_gntdev_map_grant_ref map;
|
|
+ void *addr;
|
|
+
|
|
+ map.count = 1;
|
|
+ map.refs[0].domid = domid;
|
|
+ map.refs[0].ref = ref;
|
|
+
|
|
+ if ( ioctl(fd, IOCTL_GNTDEV_MAP_GRANT_REF, &map) ) {
|
|
+ PERROR("netbsd_gnttab_map_grant_ref: ioctl MAP_GRANT_REF failed");
|
|
+ return NULL;
|
|
+ }
|
|
+
|
|
+mmap_again:
|
|
+ addr = mmap(NULL, XC_PAGE_SIZE, prot, MAP_SHARED, fd, map.index);
|
|
+ if ( addr == MAP_FAILED )
|
|
+ {
|
|
+ int saved_errno = errno;
|
|
+ struct ioctl_gntdev_unmap_grant_ref unmap_grant;
|
|
+
|
|
+ if ( saved_errno == EAGAIN )
|
|
+ {
|
|
+ usleep(1000);
|
|
+ goto mmap_again;
|
|
+ }
|
|
+ /* Unmap the driver slots used to store the grant information. */
|
|
+ PERROR("netbsd_gnttab_map_grant_ref: mmap failed");
|
|
+ unmap_grant.index = map.index;
|
|
+ unmap_grant.count = 1;
|
|
+ ioctl(fd, IOCTL_GNTDEV_UNMAP_GRANT_REF, &unmap_grant);
|
|
+ errno = saved_errno;
|
|
+ return NULL;
|
|
+ }
|
|
+
|
|
+ return addr;
|
|
+}
|
|
+
|
|
+static void *
|
|
+do_gnttab_map_grant_refs(xc_gnttab *xch, xc_osdep_handle h,
|
|
+ uint32_t count, uint32_t *domids, int domids_stride,
|
|
+ uint32_t *refs, int prot)
|
|
+{
|
|
+ int fd = (int)h;
|
|
+ struct ioctl_gntdev_map_grant_ref *map;
|
|
+ void *addr = NULL;
|
|
+ int i;
|
|
+
|
|
+ map = malloc(sizeof(*map) +
|
|
+ (count - 1) * sizeof(struct ioctl_gntdev_map_grant_ref));
|
|
+ if ( map == NULL )
|
|
+ return NULL;
|
|
+
|
|
+ for ( i = 0; i < count; i++ )
|
|
+ {
|
|
+ map->refs[i].domid = domids[i * domids_stride];
|
|
+ map->refs[i].ref = refs[i];
|
|
+ }
|
|
+
|
|
+ map->count = count;
|
|
+
|
|
+ if ( ioctl(fd, IOCTL_GNTDEV_MAP_GRANT_REF, map) ) {
|
|
+ PERROR("xc_gnttab_map_grant_refs: ioctl MAP_GRANT_REF failed");
|
|
+ goto out;
|
|
+ }
|
|
+
|
|
+ addr = mmap(NULL, XC_PAGE_SIZE * count, prot, MAP_SHARED, fd,
|
|
+ map->index);
|
|
+ if ( addr == MAP_FAILED )
|
|
+ {
|
|
+ int saved_errno = errno;
|
|
+ struct ioctl_gntdev_unmap_grant_ref unmap_grant;
|
|
+
|
|
+ /* Unmap the driver slots used to store the grant information. */
|
|
+ PERROR("xc_gnttab_map_grant_refs: mmap failed");
|
|
+ unmap_grant.index = map->index;
|
|
+ unmap_grant.count = count;
|
|
+ ioctl(fd, IOCTL_GNTDEV_UNMAP_GRANT_REF, &unmap_grant);
|
|
+ errno = saved_errno;
|
|
+ addr = NULL;
|
|
+ }
|
|
+
|
|
+ out:
|
|
+ free(map);
|
|
+
|
|
+ return addr;
|
|
+}
|
|
+
|
|
+static void *
|
|
+netbsd_gnttab_map_grant_refs(xc_gnttab *xcg, xc_osdep_handle h,
|
|
+ uint32_t count, uint32_t *domids, uint32_t *refs, int prot)
|
|
+{
|
|
+ return do_gnttab_map_grant_refs(xcg, h, count, domids, 1, refs, prot);
|
|
+}
|
|
+
|
|
+static void *
|
|
+netbsd_gnttab_map_domain_grant_refs(xc_gnttab *xcg, xc_osdep_handle h,
|
|
+ uint32_t count, uint32_t domid, uint32_t *refs, int prot)
|
|
+{
|
|
+ return do_gnttab_map_grant_refs(xcg, h, count, &domid, 0, refs, prot);
|
|
+}
|
|
+
|
|
+static int
|
|
+netbsd_gnttab_munmap(xc_gnttab *xcg, xc_osdep_handle h,
|
|
+ void *start_address, uint32_t count)
|
|
+{
|
|
+ int fd = (int)h;
|
|
+ struct ioctl_gntdev_get_offset_for_vaddr get_offset;
|
|
+ struct ioctl_gntdev_unmap_grant_ref unmap_grant;
|
|
+ int rc;
|
|
+
|
|
+ if ( start_address == NULL )
|
|
+ {
|
|
+ errno = EINVAL;
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ /* First, it is necessary to get the offset which was initially used to
|
|
+ * mmap() the pages.
|
|
+ */
|
|
+ get_offset.vaddr = (unsigned long)start_address;
|
|
+ rc = ioctl(fd, IOCTL_GNTDEV_GET_OFFSET_FOR_VADDR, &get_offset);
|
|
+ if ( rc )
|
|
+ return rc;
|
|
+
|
|
+ if ( get_offset.count != count )
|
|
+ {
|
|
+ errno = EINVAL;
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ /* Next, unmap the memory. */
|
|
+ rc = munmap(start_address, count * getpagesize());
|
|
+ if ( rc )
|
|
+ return rc;
|
|
+
|
|
+ /* Finally, unmap the driver slots used to store the grant information. */
|
|
+ unmap_grant.index = get_offset.offset;
|
|
+ unmap_grant.count = count;
|
|
+ rc = ioctl(fd, IOCTL_GNTDEV_UNMAP_GRANT_REF, &unmap_grant);
|
|
+ if ( rc )
|
|
+ return rc;
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static struct xc_osdep_ops netbsd_gnttab_ops = {
|
|
+ .open = &netbsd_gnttab_open,
|
|
+ .close = &netbsd_gnttab_close,
|
|
+
|
|
+ .u.gnttab = {
|
|
+ .map_grant_ref = &netbsd_gnttab_map_grant_ref,
|
|
+ .map_grant_refs = &netbsd_gnttab_map_grant_refs,
|
|
+ .map_domain_grant_refs = &netbsd_gnttab_map_domain_grant_refs,
|
|
+ .munmap = &netbsd_gnttab_munmap,
|
|
+ },
|
|
+};
|
|
+
|
|
+static struct xc_osdep_ops *
|
|
+netbsd_osdep_init(xc_interface *xch, enum xc_osdep_type type)
|
|
{
|
|
switch ( type )
|
|
{
|
|
@@ -360,8 +543,7 @@ static struct xc_osdep_ops *netbsd_osdep
|
|
case XC_OSDEP_EVTCHN:
|
|
return &netbsd_evtchn_ops;
|
|
case XC_OSDEP_GNTTAB:
|
|
- ERROR("GNTTAB interface not supported on this platform");
|
|
- return NULL;
|
|
+ return &netbsd_gnttab_ops;
|
|
default:
|
|
return NULL;
|
|
}
|