aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorKeir Fraser <keir@xensource.com>2007-03-31 14:03:17 +0100
committerKeir Fraser <keir@xensource.com>2007-03-31 14:03:17 +0100
commit7aeca464254e0c051e362c7ba1a854e918826d0b (patch)
tree7210bb96fe1cd9e5aaf193c82d83d9605b35d036 /tools
parent990f0419bd5b6fc6e5462fba29436d3461bebff7 (diff)
downloadxen-7aeca464254e0c051e362c7ba1a854e918826d0b.tar.gz
xen-7aeca464254e0c051e362c7ba1a854e918826d0b.tar.bz2
xen-7aeca464254e0c051e362c7ba1a854e918826d0b.zip
libxc: User-space grant table device.
Changes to libxc to enable easy access to the grant table device. Signed-off-by: Derek Murray <Derek.Murray@cl.cam.ac.uk>
Diffstat (limited to 'tools')
-rw-r--r--tools/libxc/xc_linux.c156
-rw-r--r--tools/libxc/xenctrl.h59
2 files changed, 215 insertions, 0 deletions
diff --git a/tools/libxc/xc_linux.c b/tools/libxc/xc_linux.c
index eac5acc793..cab3c6588f 100644
--- a/tools/libxc/xc_linux.c
+++ b/tools/libxc/xc_linux.c
@@ -3,6 +3,9 @@
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*
+ * xc_gnttab functions:
+ * Copyright (c) 2007, D G Murray <Derek.Murray@cl.cam.ac.uk>
+ *
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation, version 2 of the
@@ -13,6 +16,7 @@
#include <xen/memory.h>
#include <xen/sys/evtchn.h>
+#include <xen/sys/gntdev.h>
#include <unistd.h>
#include <fcntl.h>
@@ -363,6 +367,158 @@ void discard_file_cache(int fd, int flush)
errno = saved_errno;
}
+#define GNTTAB_DEV_NAME "/dev/xen/gntdev"
+
+int xc_gnttab_open(void)
+{
+ struct stat st;
+ int fd;
+ int devnum;
+
+ devnum = xc_find_device_number("gntdev");
+
+ /* Make sure any existing device file links to correct device. */
+ if ( (lstat(GNTTAB_DEV_NAME, &st) != 0) || !S_ISCHR(st.st_mode) ||
+ (st.st_rdev != devnum) )
+ (void)unlink(GNTTAB_DEV_NAME);
+
+reopen:
+ if ( (fd = open(GNTTAB_DEV_NAME, O_RDWR)) == -1 )
+ {
+ if ( (errno == ENOENT) &&
+ ((mkdir("/dev/xen", 0755) == 0) || (errno == EEXIST)) &&
+ (mknod(GNTTAB_DEV_NAME, S_IFCHR|0600, devnum) == 0) )
+ goto reopen;
+
+ PERROR("Could not open grant table interface");
+ return -1;
+ }
+
+ return fd;
+}
+
+int xc_gnttab_close(int xcg_handle)
+{
+ return close(xcg_handle);
+}
+
+void *xc_gnttab_map_grant_ref(int xcg_handle,
+ uint32_t domid,
+ uint32_t ref,
+ int prot)
+{
+ struct ioctl_gntdev_map_grant_ref map;
+ void *addr;
+
+ map.count = 1;
+ map.refs[0].domid = domid;
+ map.refs[0].ref = ref;
+
+ if ( ioctl(xcg_handle, IOCTL_GNTDEV_MAP_GRANT_REF, &map) )
+ return NULL;
+
+ addr = mmap(NULL, PAGE_SIZE, prot, MAP_SHARED, xcg_handle, 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. */
+ unmap_grant.index = map.index;
+ unmap_grant.count = 1;
+ ioctl(xcg_handle, IOCTL_GNTDEV_UNMAP_GRANT_REF, &unmap_grant);
+ errno = saved_errno;
+ return NULL;
+ }
+
+ return addr;
+}
+
+void *xc_gnttab_map_grant_refs(int xcg_handle,
+ uint32_t count,
+ uint32_t domids[count],
+ uint32_t refs[count],
+ int prot)
+{
+ 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];
+ map->refs[i].ref = refs[i];
+ }
+
+ map->count = count;
+
+ if ( ioctl(xcg_handle, IOCTL_GNTDEV_MAP_GRANT_REF, &map) )
+ goto out;
+
+ addr = mmap(NULL, PAGE_SIZE * count, prot, MAP_SHARED, xcg_handle,
+ 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. */
+ unmap_grant.index = map->index;
+ unmap_grant.count = count;
+ ioctl(xcg_handle, IOCTL_GNTDEV_UNMAP_GRANT_REF, &unmap_grant);
+ errno = saved_errno;
+ addr = NULL;
+ }
+
+ out:
+ free(map);
+ return addr;
+}
+
+int xc_gnttab_munmap(int xcg_handle,
+ void *start_address,
+ uint32_t count)
+{
+ 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;
+ if ( (rc = ioctl(xcg_handle, IOCTL_GNTDEV_GET_OFFSET_FOR_VADDR,
+ &get_offset)) )
+ return rc;
+
+ if ( get_offset.count != count )
+ {
+ errno = EINVAL;
+ return -1;
+ }
+
+ /* Next, unmap the memory. */
+ if ( (rc = munmap(start_address, count * getpagesize())) )
+ return rc;
+
+ /* Finally, unmap the driver slots used to store the grant information. */
+ unmap_grant.index = get_offset.offset;
+ unmap_grant.count = count;
+ if ( (rc = ioctl(xcg_handle, IOCTL_GNTDEV_UNMAP_GRANT_REF, &unmap_grant)) )
+ return rc;
+
+ return 0;
+}
+
/*
* Local variables:
* mode: C
diff --git a/tools/libxc/xenctrl.h b/tools/libxc/xenctrl.h
index 4b346a74f0..f838b70966 100644
--- a/tools/libxc/xenctrl.h
+++ b/tools/libxc/xenctrl.h
@@ -4,6 +4,9 @@
* A library for low-level access to the Xen control interfaces.
*
* Copyright (c) 2003-2004, K A Fraser.
+ *
+ * xc_gnttab functions:
+ * Copyright (c) 2007, D G Murray <Derek.Murray@cl.cam.ac.uk>
*/
#ifndef XENCTRL_H
@@ -740,6 +743,62 @@ evtchn_port_t xc_evtchn_pending(int xce_handle);
*/
int xc_evtchn_unmask(int xce_handle, evtchn_port_t port);
+/**************************
+ * GRANT TABLE OPERATIONS *
+ **************************/
+
+/*
+ * Return a handle to the grant table driver, or -1 on failure, in which case
+ * errno will be set appropriately.
+ */
+int xc_gnttab_open(void);
+
+/*
+ * Close a handle previously allocated with xc_gnttab_open().
+ */
+int xc_gnttab_close(int xcg_handle);
+
+/*
+ * Memory maps a grant reference from one domain to a local address range.
+ * Mappings should be unmapped with xc_gnttab_munmap. Returns NULL on failure.
+ *
+ * @parm xcg_handle a handle on an open grant table interface
+ * @parm domid the domain to map memory from
+ * @parm ref the grant reference ID to map
+ * @parm prot same flag as in mmap()
+ */
+void *xc_gnttab_map_grant_ref(int xcg_handle,
+ uint32_t domid,
+ uint32_t ref,
+ int prot);
+
+/**
+ * Memory maps one or more grant references from one or more domains to a
+ * contiguous local address range. Mappings should be unmapped with
+ * xc_gnttab_munmap. Returns NULL on failure.
+ *
+ * @parm xcg_handle a handle on an open grant table interface
+ * @parm count the number of grant references to be mapped
+ * @parm domids an array of @count domain IDs by which the corresponding @refs
+ * were granted
+ * @parm refs an array of @count grant references to be mapped
+ * @parm prot same flag as in mmap()
+ */
+void *xc_gnttab_map_grant_refs(int xcg_handle,
+ uint32_t count,
+ uint32_t domids[count],
+ uint32_t refs[count],
+ int prot);
+
+/*
+ * Unmaps the @count pages starting at @start_address, which were mapped by a
+ * call to xc_gnttab_map_grant_ref or xc_gnttab_map_grant_refs. Returns zero
+ * on success, otherwise sets errno and returns non-zero.
+ */
+int xc_gnttab_munmap(int xcg_handle,
+ void *start_address,
+ uint32_t count);
+
int xc_hvm_set_pci_intx_level(
int xc_handle, domid_t dom,
uint8_t domain, uint8_t bus, uint8_t device, uint8_t intx,