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