1*78eb3293SRoger Pau Monné /*- 2*78eb3293SRoger Pau Monné * Copyright (c) 2016 Akshay Jaggi <jaggi@FreeBSD.org> 3*78eb3293SRoger Pau Monné * All rights reserved. 4*78eb3293SRoger Pau Monné * 5*78eb3293SRoger Pau Monné * Redistribution and use in source and binary forms, with or without 6*78eb3293SRoger Pau Monné * modification, are permitted provided that the following conditions 7*78eb3293SRoger Pau Monné * are met: 8*78eb3293SRoger Pau Monné * 1. Redistributions of source code must retain the above copyright 9*78eb3293SRoger Pau Monné * notice, this list of conditions and the following disclaimer. 10*78eb3293SRoger Pau Monné * 2. Redistributions in binary form must reproduce the above copyright 11*78eb3293SRoger Pau Monné * notice, this list of conditions and the following disclaimer in the 12*78eb3293SRoger Pau Monné * documentation and/or other materials provided with the distribution. 13*78eb3293SRoger Pau Monné * 14*78eb3293SRoger Pau Monné * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15*78eb3293SRoger Pau Monné * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16*78eb3293SRoger Pau Monné * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17*78eb3293SRoger Pau Monné * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18*78eb3293SRoger Pau Monné * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19*78eb3293SRoger Pau Monné * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20*78eb3293SRoger Pau Monné * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21*78eb3293SRoger Pau Monné * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22*78eb3293SRoger Pau Monné * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23*78eb3293SRoger Pau Monné * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24*78eb3293SRoger Pau Monné * SUCH DAMAGE. 25*78eb3293SRoger Pau Monné * 26*78eb3293SRoger Pau Monné * gntdev.h 27*78eb3293SRoger Pau Monné * 28*78eb3293SRoger Pau Monné * Interface to /dev/xen/gntdev. 29*78eb3293SRoger Pau Monné * 30*78eb3293SRoger Pau Monné * This device provides the user with two kinds of functionalities: 31*78eb3293SRoger Pau Monné * 1. Grant Allocation 32*78eb3293SRoger Pau Monné * Allocate a page of our own memory, and share it with a foreign domain. 33*78eb3293SRoger Pau Monné * 2. Grant Mapping 34*78eb3293SRoger Pau Monné * Map a grant allocated by a foreign domain, into our own memory. 35*78eb3293SRoger Pau Monné * 36*78eb3293SRoger Pau Monné * 37*78eb3293SRoger Pau Monné * Grant Allocation 38*78eb3293SRoger Pau Monné * 39*78eb3293SRoger Pau Monné * Steps to allocate a grant: 40*78eb3293SRoger Pau Monné * 1. Do an `IOCTL_GNTDEV_ALLOC_GREF ioctl`, with 41*78eb3293SRoger Pau Monné * - `domid`, as the domain-id of the foreign domain 42*78eb3293SRoger Pau Monné * - `flags`, ORed with GNTDEV_ALLOC_FLAG_WRITABLE if you want the foreign 43*78eb3293SRoger Pau Monné * domain to have write access to the shared memory 44*78eb3293SRoger Pau Monné * - `count`, with the number of pages to share with the foreign domain 45*78eb3293SRoger Pau Monné * 46*78eb3293SRoger Pau Monné * Ensure that the structure you allocate has enough memory to store 47*78eb3293SRoger Pau Monné * all the allocated grant-refs, i.e., you need to allocate 48*78eb3293SRoger Pau Monné * (sizeof(struct ioctl_gntdev_alloc_gref) + (count - 1)*sizeof(uint32_t)) 49*78eb3293SRoger Pau Monné * bytes of memory. 50*78eb3293SRoger Pau Monné * 51*78eb3293SRoger Pau Monné * 2. Mmap the address given in `index` after a successful ioctl. 52*78eb3293SRoger Pau Monné * This will give you access to the granted pages. 53*78eb3293SRoger Pau Monné * 54*78eb3293SRoger Pau Monné * Note: 55*78eb3293SRoger Pau Monné * 1. The grant is not removed until all three of the following conditions 56*78eb3293SRoger Pau Monné * are met 57*78eb3293SRoger Pau Monné * - The region is not mmaped. That is, munmap() has been called if 58*78eb3293SRoger Pau Monné * the region was mmapped previously. 59*78eb3293SRoger Pau Monné * - IOCTL_GNTDEV_DEALLOC_GREF ioctl has been performed. After you 60*78eb3293SRoger Pau Monné * perform this ioctl, you can no longer mmap or set notify on 61*78eb3293SRoger Pau Monné * the grant. 62*78eb3293SRoger Pau Monné * - The foreign domain has stopped using the grant. 63*78eb3293SRoger Pau Monné * 2. Granted pages can only belong to one mmap region. 64*78eb3293SRoger Pau Monné * 3. Every page of granted memory is a unit in itself. What this means 65*78eb3293SRoger Pau Monné * is that you can set a unmap notification for each of the granted 66*78eb3293SRoger Pau Monné * pages, individually; you can mmap and dealloc-ioctl a contiguous 67*78eb3293SRoger Pau Monné * range of allocated grants (even if alloc-ioctls were performed 68*78eb3293SRoger Pau Monné * individually), etc. 69*78eb3293SRoger Pau Monné * 70*78eb3293SRoger Pau Monné * 71*78eb3293SRoger Pau Monné * Grant Mapping 72*78eb3293SRoger Pau Monné * 73*78eb3293SRoger Pau Monné * Steps to map a grant: 74*78eb3293SRoger Pau Monné * 1. Do a `IOCTL_GNTDEV_MAP_GRANT_REF` ioctl, with 75*78eb3293SRoger Pau Monné * - `count`, as the number of foreign grants to map 76*78eb3293SRoger Pau Monné * - `refs[i].domid`, as the domain id of the foreign domain 77*78eb3293SRoger Pau Monné * - `refs[i].ref`, as the grant-ref for the grant to be mapped 78*78eb3293SRoger Pau Monné * 79*78eb3293SRoger Pau Monné * 2. Mmap the address given in `index` after a successful ioctl. 80*78eb3293SRoger Pau Monné * This will give you access to the mapped pages. 81*78eb3293SRoger Pau Monné * 82*78eb3293SRoger Pau Monné * Note: 83*78eb3293SRoger Pau Monné * 1. The map hypercall is not made till the region is mmapped. 84*78eb3293SRoger Pau Monné * 2. The unit is defined by the map ioctl. This means that only one 85*78eb3293SRoger Pau Monné * unmap notification can be set on a group of pages that were 86*78eb3293SRoger Pau Monné * mapped together in one ioctl, and also no single mmaping of contiguous 87*78eb3293SRoger Pau Monné * grant-maps is possible. 88*78eb3293SRoger Pau Monné * 3. You can mmap the same grant-map region multiple times. 89*78eb3293SRoger Pau Monné * 4. The grant is not unmapped until both of the following conditions are met 90*78eb3293SRoger Pau Monné * - The region is not mmaped. That is, munmap() has been called for 91*78eb3293SRoger Pau Monné * as many times as the grant was mmapped. 92*78eb3293SRoger Pau Monné * - IOCTL_GNTDEV_UNMAP_GRANT_REF ioctl has been called. 93*78eb3293SRoger Pau Monné * 5. IOCTL_GNTDEV_GET_OFFSET_FOR_VADDR ioctl gives index and count of 94*78eb3293SRoger Pau Monné * a grant-map from the virtual address of the location where the grant 95*78eb3293SRoger Pau Monné * is mmapped. 96*78eb3293SRoger Pau Monné * 97*78eb3293SRoger Pau Monné * 98*78eb3293SRoger Pau Monné * IOCTL_GNTDEV_SET_UNMAP_NOTIFY 99*78eb3293SRoger Pau Monné * This ioctl allows us to set notifications to be made when the grant is 100*78eb3293SRoger Pau Monné * either unmapped (in case of a mapped grant), or when it is ready to be 101*78eb3293SRoger Pau Monné * deallocated by us, ie, the grant is no more mmapped, and the dealloc 102*78eb3293SRoger Pau Monné * ioctl has been called (in case of an allocated grant). OR `action` with 103*78eb3293SRoger Pau Monné * the required notification masks, and fill in the appropriate fields. 104*78eb3293SRoger Pau Monné * - UNMAP_NOTIFY_CLEAR_BYTE clears the byte at `index`, where index is 105*78eb3293SRoger Pau Monné * the address of the byte in file address space. 106*78eb3293SRoger Pau Monné * - UNMAP_NOTIFY_SEND_EVENT sends an event channel notification on 107*78eb3293SRoger Pau Monné * `event_channel_port` 108*78eb3293SRoger Pau Monné * In case of multiple notify ioctls, only the last one survives. 109*78eb3293SRoger Pau Monné * 110*78eb3293SRoger Pau Monné * $FreeBSD$ 111*78eb3293SRoger Pau Monné */ 112*78eb3293SRoger Pau Monné 113*78eb3293SRoger Pau Monné #ifndef __XEN_GNTDEV_H__ 114*78eb3293SRoger Pau Monné #define __XEN_GNTDEV_H__ 115*78eb3293SRoger Pau Monné 116*78eb3293SRoger Pau Monné #include <sys/types.h> 117*78eb3293SRoger Pau Monné 118*78eb3293SRoger Pau Monné #define IOCTL_GNTDEV_SET_UNMAP_NOTIFY \ 119*78eb3293SRoger Pau Monné _IOW('E', 0, struct ioctl_gntdev_unmap_notify) 120*78eb3293SRoger Pau Monné struct ioctl_gntdev_unmap_notify { 121*78eb3293SRoger Pau Monné /* IN parameters */ 122*78eb3293SRoger Pau Monné uint64_t index; 123*78eb3293SRoger Pau Monné uint32_t action; 124*78eb3293SRoger Pau Monné uint32_t event_channel_port; 125*78eb3293SRoger Pau Monné }; 126*78eb3293SRoger Pau Monné 127*78eb3293SRoger Pau Monné #define UNMAP_NOTIFY_CLEAR_BYTE 0x1 128*78eb3293SRoger Pau Monné #define UNMAP_NOTIFY_SEND_EVENT 0x2 129*78eb3293SRoger Pau Monné 130*78eb3293SRoger Pau Monné /*-------------------- Grant Allocation IOCTLs ------------------------------*/ 131*78eb3293SRoger Pau Monné 132*78eb3293SRoger Pau Monné #define IOCTL_GNTDEV_ALLOC_GREF \ 133*78eb3293SRoger Pau Monné _IOWR('E', 1, struct ioctl_gntdev_alloc_gref) 134*78eb3293SRoger Pau Monné struct ioctl_gntdev_alloc_gref { 135*78eb3293SRoger Pau Monné /* IN parameters */ 136*78eb3293SRoger Pau Monné uint16_t domid; 137*78eb3293SRoger Pau Monné uint16_t flags; 138*78eb3293SRoger Pau Monné uint32_t count; 139*78eb3293SRoger Pau Monné /* OUT parameters */ 140*78eb3293SRoger Pau Monné uint64_t index; 141*78eb3293SRoger Pau Monné /* Variable OUT parameter */ 142*78eb3293SRoger Pau Monné uint32_t gref_ids[1]; 143*78eb3293SRoger Pau Monné }; 144*78eb3293SRoger Pau Monné 145*78eb3293SRoger Pau Monné #define GNTDEV_ALLOC_FLAG_WRITABLE 1 146*78eb3293SRoger Pau Monné 147*78eb3293SRoger Pau Monné #define IOCTL_GNTDEV_DEALLOC_GREF \ 148*78eb3293SRoger Pau Monné _IOW('E', 2, struct ioctl_gntdev_dealloc_gref) 149*78eb3293SRoger Pau Monné struct ioctl_gntdev_dealloc_gref { 150*78eb3293SRoger Pau Monné /* IN parameters */ 151*78eb3293SRoger Pau Monné uint64_t index; 152*78eb3293SRoger Pau Monné uint32_t count; 153*78eb3293SRoger Pau Monné }; 154*78eb3293SRoger Pau Monné 155*78eb3293SRoger Pau Monné /*-------------------- Grant Mapping IOCTLs ---------------------------------*/ 156*78eb3293SRoger Pau Monné 157*78eb3293SRoger Pau Monné struct ioctl_gntdev_grant_ref { 158*78eb3293SRoger Pau Monné uint32_t domid; 159*78eb3293SRoger Pau Monné uint32_t ref; 160*78eb3293SRoger Pau Monné }; 161*78eb3293SRoger Pau Monné 162*78eb3293SRoger Pau Monné #define IOCTL_GNTDEV_MAP_GRANT_REF \ 163*78eb3293SRoger Pau Monné _IOWR('E', 3, struct ioctl_gntdev_map_grant_ref) 164*78eb3293SRoger Pau Monné struct ioctl_gntdev_map_grant_ref { 165*78eb3293SRoger Pau Monné /* IN parameters */ 166*78eb3293SRoger Pau Monné uint32_t count; 167*78eb3293SRoger Pau Monné uint32_t pad0; 168*78eb3293SRoger Pau Monné /* OUT parameters */ 169*78eb3293SRoger Pau Monné uint64_t index; 170*78eb3293SRoger Pau Monné /* Variable IN parameter */ 171*78eb3293SRoger Pau Monné struct ioctl_gntdev_grant_ref refs[1]; 172*78eb3293SRoger Pau Monné }; 173*78eb3293SRoger Pau Monné 174*78eb3293SRoger Pau Monné #define IOCTL_GNTDEV_UNMAP_GRANT_REF \ 175*78eb3293SRoger Pau Monné _IOW('E', 4, struct ioctl_gntdev_unmap_grant_ref) 176*78eb3293SRoger Pau Monné struct ioctl_gntdev_unmap_grant_ref { 177*78eb3293SRoger Pau Monné /* IN parameters */ 178*78eb3293SRoger Pau Monné uint64_t index; 179*78eb3293SRoger Pau Monné uint32_t count; 180*78eb3293SRoger Pau Monné }; 181*78eb3293SRoger Pau Monné 182*78eb3293SRoger Pau Monné #define IOCTL_GNTDEV_GET_OFFSET_FOR_VADDR \ 183*78eb3293SRoger Pau Monné _IOWR('E', 5, struct ioctl_gntdev_get_offset_for_vaddr) 184*78eb3293SRoger Pau Monné struct ioctl_gntdev_get_offset_for_vaddr { 185*78eb3293SRoger Pau Monné /* IN parameters */ 186*78eb3293SRoger Pau Monné uint64_t vaddr; 187*78eb3293SRoger Pau Monné /* OUT parameters */ 188*78eb3293SRoger Pau Monné uint64_t offset; 189*78eb3293SRoger Pau Monné uint32_t count; 190*78eb3293SRoger Pau Monné }; 191*78eb3293SRoger Pau Monné 192*78eb3293SRoger Pau Monné #endif /* __XEN_GNTDEV_H__ */ 193