Derek Murray
2007-Mar-19 10:40 UTC
[Xen-devel] [PATCH 2/3] [RFC] User-space grant table device - changes to libxc
Changes to libxc to enable easy access to the grant table device. Signed-off-by: Derek Murray <Derek.Murray@cl.cam.ac.uk> --- diff -r 809f36b1b685 tools/libxc/xc_linux.c --- a/tools/libxc/xc_linux.c Thu Mar 15 10:43:13 2007 +0000 +++ b/tools/libxc/xc_linux.c Thu Mar 15 17:46:06 2007 +0000 @@ -13,6 +13,7 @@ #include <xen/memory.h> #include <xen/sys/evtchn.h> +#include <xen/sys/gntdev.h> #include <unistd.h> #include <fcntl.h> @@ -361,6 +362,143 @@ void discard_file_cache(int fd, int flus out: 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; + struct ioctl_gntdev_grant_ref op; + void *addr; + + op.domid = domid; + op.ref = ref; + map.count = 1; + map.refs = &op; + + 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) { + 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; + struct ioctl_gntdev_grant_ref *ops = malloc(count * sizeof(*ops)); + void *addr; + int i; + + if (ops == NULL) { + return NULL; + } + + for (i = 0; i < count; ++i) { + ops[i].domid = domids[i]; + ops[i].ref = refs[i]; + } + + map.count = count; + map.refs = ops; + + if (ioctl(xcg_handle, IOCTL_GNTDEV_MAP_GRANT_REF, &map)) { + return NULL; + } + + printf("Going to mmap() at index %#lx\n", map.index); + + addr = mmap(NULL, PAGE_SIZE * count, prot, MAP_SHARED, xcg_handle, + map.index); + if (addr == MAP_FAILED) { + return NULL; + } + + 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; + + /* First, it is necessary to get the offset which was initially used to + * mmap() the pages. + */ + get_offset.vaddr = start_address; + if ((rc = ioctl(xcg_handle, IOCTL_GNTDEV_GET_OFFSET_FOR_VADDR, + &get_offset))) + { + return rc; + } + if (get_offset.count != count) { + errno = -EFAULT; + return -EFAULT; + } + + /* 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; } /* diff -r 809f36b1b685 tools/libxc/xenctrl.h --- a/tools/libxc/xenctrl.h Thu Mar 15 10:43:13 2007 +0000 +++ b/tools/libxc/xenctrl.h Thu Mar 15 17:46:06 2007 +0000 @@ -740,6 +740,62 @@ evtchn_port_t xc_evtchn_pending(int xce_ */ 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, _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Seemingly Similar Threads
- [PATCH] xenconsoled: use grant references instead of map_foreign_range
- [PATCH v2 1/2] xenconsoled: use grant references instead of map_foreign_range
- Question about using xenctl
- Grant tables
- [PATCH 0 of 6 RESEND v2] blktap3/sring: shared ring between tapdisk and the front-end