ia64/xen-unstable

changeset 14685:7b77b47a49d1

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>
author Keir Fraser <keir@xensource.com>
date Sat Mar 31 14:03:17 2007 +0100 (2007-03-31)
parents 5e65a86c8982
children fbe52b559161
files tools/libxc/xc_linux.c tools/libxc/xenctrl.h
line diff
     1.1 --- a/tools/libxc/xc_linux.c	Sat Mar 31 13:53:24 2007 +0100
     1.2 +++ b/tools/libxc/xc_linux.c	Sat Mar 31 14:03:17 2007 +0100
     1.3 @@ -3,6 +3,9 @@
     1.4   * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
     1.5   * Use is subject to license terms.
     1.6   *
     1.7 + * xc_gnttab functions:
     1.8 + * Copyright (c) 2007, D G Murray <Derek.Murray@cl.cam.ac.uk>
     1.9 + *
    1.10   * This program is free software; you can redistribute it and/or
    1.11   * modify it under the terms of the GNU General Public License as
    1.12   * published by the Free Software Foundation, version 2 of the
    1.13 @@ -13,6 +16,7 @@
    1.14  
    1.15  #include <xen/memory.h>
    1.16  #include <xen/sys/evtchn.h>
    1.17 +#include <xen/sys/gntdev.h>
    1.18  #include <unistd.h>
    1.19  #include <fcntl.h>
    1.20  
    1.21 @@ -363,6 +367,158 @@ void discard_file_cache(int fd, int flus
    1.22      errno = saved_errno;
    1.23  }
    1.24  
    1.25 +#define GNTTAB_DEV_NAME "/dev/xen/gntdev"
    1.26 +
    1.27 +int xc_gnttab_open(void)
    1.28 +{
    1.29 +    struct stat st;
    1.30 +    int fd;
    1.31 +    int devnum;
    1.32 +    
    1.33 +    devnum = xc_find_device_number("gntdev");
    1.34 +    
    1.35 +    /* Make sure any existing device file links to correct device. */
    1.36 +    if ( (lstat(GNTTAB_DEV_NAME, &st) != 0) || !S_ISCHR(st.st_mode) ||
    1.37 +         (st.st_rdev != devnum) )
    1.38 +        (void)unlink(GNTTAB_DEV_NAME);
    1.39 +    
    1.40 +reopen:
    1.41 +    if ( (fd = open(GNTTAB_DEV_NAME, O_RDWR)) == -1 )
    1.42 +    {
    1.43 +        if ( (errno == ENOENT) &&
    1.44 +             ((mkdir("/dev/xen", 0755) == 0) || (errno == EEXIST)) &&
    1.45 +             (mknod(GNTTAB_DEV_NAME, S_IFCHR|0600, devnum) == 0) )
    1.46 +            goto reopen;
    1.47 +        
    1.48 +        PERROR("Could not open grant table interface");
    1.49 +        return -1;
    1.50 +    }
    1.51 +    
    1.52 +    return fd;
    1.53 +}
    1.54 +
    1.55 +int xc_gnttab_close(int xcg_handle)
    1.56 +{
    1.57 +    return close(xcg_handle);
    1.58 +}
    1.59 +
    1.60 +void *xc_gnttab_map_grant_ref(int xcg_handle,
    1.61 +                              uint32_t domid,
    1.62 +                              uint32_t ref,
    1.63 +                              int prot)
    1.64 +{
    1.65 +    struct ioctl_gntdev_map_grant_ref map;
    1.66 +    void *addr;
    1.67 +    
    1.68 +    map.count = 1;
    1.69 +    map.refs[0].domid = domid;
    1.70 +    map.refs[0].ref   = ref;
    1.71 +
    1.72 +    if ( ioctl(xcg_handle, IOCTL_GNTDEV_MAP_GRANT_REF, &map) )
    1.73 +        return NULL;
    1.74 +    
    1.75 +    addr = mmap(NULL, PAGE_SIZE, prot, MAP_SHARED, xcg_handle, map.index);
    1.76 +    if ( addr == MAP_FAILED )
    1.77 +    {
    1.78 +        int saved_errno = errno;
    1.79 +        struct ioctl_gntdev_unmap_grant_ref unmap_grant;
    1.80 +        /* Unmap the driver slots used to store the grant information. */
    1.81 +        unmap_grant.index = map.index;
    1.82 +        unmap_grant.count = 1;
    1.83 +        ioctl(xcg_handle, IOCTL_GNTDEV_UNMAP_GRANT_REF, &unmap_grant);
    1.84 +        errno = saved_errno;
    1.85 +        return NULL;
    1.86 +    }
    1.87 +    
    1.88 +    return addr;
    1.89 +}
    1.90 +
    1.91 +void *xc_gnttab_map_grant_refs(int xcg_handle,
    1.92 +                               uint32_t count,
    1.93 +                               uint32_t domids[count],
    1.94 +                               uint32_t refs[count],
    1.95 +                               int prot)
    1.96 +{
    1.97 +    struct ioctl_gntdev_map_grant_ref *map;
    1.98 +    void *addr = NULL;
    1.99 +    int i;
   1.100 +    
   1.101 +    map = malloc(sizeof(*map) +
   1.102 +                 (count-1) * sizeof(struct ioctl_gntdev_map_grant_ref));
   1.103 +    if ( map == NULL )
   1.104 +        return NULL;
   1.105 +
   1.106 +    for ( i = 0; i < count; i++ )
   1.107 +    {
   1.108 +        map->refs[i].domid = domids[i];
   1.109 +        map->refs[i].ref   = refs[i];
   1.110 +    }
   1.111 +
   1.112 +    map->count = count;
   1.113 +    
   1.114 +    if ( ioctl(xcg_handle, IOCTL_GNTDEV_MAP_GRANT_REF, &map) )
   1.115 +        goto out;
   1.116 +
   1.117 +    addr = mmap(NULL, PAGE_SIZE * count, prot, MAP_SHARED, xcg_handle,
   1.118 +                map->index);
   1.119 +    if ( addr == MAP_FAILED )
   1.120 +    {
   1.121 +        int saved_errno = errno;
   1.122 +        struct ioctl_gntdev_unmap_grant_ref unmap_grant;
   1.123 +        /* Unmap the driver slots used to store the grant information. */
   1.124 +        unmap_grant.index = map->index;
   1.125 +        unmap_grant.count = count;
   1.126 +        ioctl(xcg_handle, IOCTL_GNTDEV_UNMAP_GRANT_REF, &unmap_grant);
   1.127 +        errno = saved_errno;
   1.128 +        addr = NULL;
   1.129 +    }
   1.130 +
   1.131 + out:
   1.132 +    free(map);
   1.133 +    return addr;
   1.134 +}
   1.135 +
   1.136 +int xc_gnttab_munmap(int xcg_handle,
   1.137 +                     void *start_address,
   1.138 +                     uint32_t count)
   1.139 +{
   1.140 +    struct ioctl_gntdev_get_offset_for_vaddr get_offset;
   1.141 +    struct ioctl_gntdev_unmap_grant_ref unmap_grant;
   1.142 +    int rc;
   1.143 +
   1.144 +    if ( start_address == NULL )
   1.145 +    {
   1.146 +        errno = EINVAL;
   1.147 +        return -1;
   1.148 +    }
   1.149 +
   1.150 +    /* First, it is necessary to get the offset which was initially used to
   1.151 +     * mmap() the pages.
   1.152 +     */
   1.153 +    get_offset.vaddr = (unsigned long)start_address;
   1.154 +    if ( (rc = ioctl(xcg_handle, IOCTL_GNTDEV_GET_OFFSET_FOR_VADDR, 
   1.155 +                     &get_offset)) )
   1.156 +        return rc;
   1.157 +
   1.158 +    if ( get_offset.count != count )
   1.159 +    {
   1.160 +        errno = EINVAL;
   1.161 +        return -1;
   1.162 +    }
   1.163 +
   1.164 +    /* Next, unmap the memory. */
   1.165 +    if ( (rc = munmap(start_address, count * getpagesize())) )
   1.166 +        return rc;
   1.167 +    
   1.168 +    /* Finally, unmap the driver slots used to store the grant information. */
   1.169 +    unmap_grant.index = get_offset.offset;
   1.170 +    unmap_grant.count = count;
   1.171 +    if ( (rc = ioctl(xcg_handle, IOCTL_GNTDEV_UNMAP_GRANT_REF, &unmap_grant)) )
   1.172 +        return rc;
   1.173 +
   1.174 +    return 0;
   1.175 +}
   1.176 +
   1.177  /*
   1.178   * Local variables:
   1.179   * mode: C
     2.1 --- a/tools/libxc/xenctrl.h	Sat Mar 31 13:53:24 2007 +0100
     2.2 +++ b/tools/libxc/xenctrl.h	Sat Mar 31 14:03:17 2007 +0100
     2.3 @@ -4,6 +4,9 @@
     2.4   * A library for low-level access to the Xen control interfaces.
     2.5   *
     2.6   * Copyright (c) 2003-2004, K A Fraser.
     2.7 + *
     2.8 + * xc_gnttab functions:
     2.9 + * Copyright (c) 2007, D G Murray <Derek.Murray@cl.cam.ac.uk>
    2.10   */
    2.11  
    2.12  #ifndef XENCTRL_H
    2.13 @@ -740,6 +743,62 @@ evtchn_port_t xc_evtchn_pending(int xce_
    2.14   */
    2.15  int xc_evtchn_unmask(int xce_handle, evtchn_port_t port);
    2.16  
    2.17 +/**************************
    2.18 + * GRANT TABLE OPERATIONS *
    2.19 + **************************/
    2.20 +
    2.21 +/*
    2.22 + * Return a handle to the grant table driver, or -1 on failure, in which case
    2.23 + * errno will be set appropriately.
    2.24 + */
    2.25 +int xc_gnttab_open(void);
    2.26 +
    2.27 +/*
    2.28 + * Close a handle previously allocated with xc_gnttab_open().
    2.29 + */
    2.30 +int xc_gnttab_close(int xcg_handle);
    2.31 +
    2.32 +/*
    2.33 + * Memory maps a grant reference from one domain to a local address range.
    2.34 + * Mappings should be unmapped with xc_gnttab_munmap.  Returns NULL on failure.
    2.35 + *
    2.36 + * @parm xcg_handle a handle on an open grant table interface
    2.37 + * @parm domid the domain to map memory from
    2.38 + * @parm ref the grant reference ID to map
    2.39 + * @parm prot same flag as in mmap()
    2.40 + */
    2.41 +void *xc_gnttab_map_grant_ref(int xcg_handle,
    2.42 +                              uint32_t domid,
    2.43 +                              uint32_t ref,
    2.44 +                              int prot);
    2.45 +
    2.46 +/**
    2.47 + * Memory maps one or more grant references from one or more domains to a
    2.48 + * contiguous local address range. Mappings should be unmapped with
    2.49 + * xc_gnttab_munmap.  Returns NULL on failure.
    2.50 + *
    2.51 + * @parm xcg_handle a handle on an open grant table interface
    2.52 + * @parm count the number of grant references to be mapped
    2.53 + * @parm domids an array of @count domain IDs by which the corresponding @refs
    2.54 + *              were granted
    2.55 + * @parm refs an array of @count grant references to be mapped
    2.56 + * @parm prot same flag as in mmap()
    2.57 + */
    2.58 +void *xc_gnttab_map_grant_refs(int xcg_handle,
    2.59 +                               uint32_t count,
    2.60 +                               uint32_t domids[count],
    2.61 +                               uint32_t refs[count],
    2.62 +                               int prot);
    2.63 +
    2.64 +/*
    2.65 + * Unmaps the @count pages starting at @start_address, which were mapped by a
    2.66 + * call to xc_gnttab_map_grant_ref or xc_gnttab_map_grant_refs. Returns zero
    2.67 + * on success, otherwise sets errno and returns non-zero.
    2.68 + */
    2.69 +int xc_gnttab_munmap(int xcg_handle,
    2.70 +                     void *start_address,
    2.71 +                     uint32_t count);
    2.72 +
    2.73  int xc_hvm_set_pci_intx_level(
    2.74      int xc_handle, domid_t dom,
    2.75      uint8_t domain, uint8_t bus, uint8_t device, uint8_t intx,