diff options
author | Keir Fraser <keir@xensource.com> | 2007-03-31 14:03:17 +0100 |
---|---|---|
committer | Keir Fraser <keir@xensource.com> | 2007-03-31 14:03:17 +0100 |
commit | 7aeca464254e0c051e362c7ba1a854e918826d0b (patch) | |
tree | 7210bb96fe1cd9e5aaf193c82d83d9605b35d036 /tools | |
parent | 990f0419bd5b6fc6e5462fba29436d3461bebff7 (diff) | |
download | xen-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.c | 156 | ||||
-rw-r--r-- | tools/libxc/xenctrl.h | 59 |
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, |