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 mmaping 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 112 #ifndef __XEN_GNTDEV_H__ 113 #define __XEN_GNTDEV_H__ 114 115 #include <sys/types.h> 116 117 #define IOCTL_GNTDEV_SET_UNMAP_NOTIFY \ 118 _IOW('E', 0, struct ioctl_gntdev_unmap_notify) 119 struct ioctl_gntdev_unmap_notify { 120 /* IN parameters */ 121 uint64_t index; 122 uint32_t action; 123 uint32_t event_channel_port; 124 }; 125 126 #define UNMAP_NOTIFY_CLEAR_BYTE 0x1 127 #define UNMAP_NOTIFY_SEND_EVENT 0x2 128 129 /*-------------------- Grant Allocation IOCTLs ------------------------------*/ 130 131 #define IOCTL_GNTDEV_ALLOC_GREF \ 132 _IOWR('E', 1, struct ioctl_gntdev_alloc_gref) 133 struct ioctl_gntdev_alloc_gref { 134 /* IN parameters */ 135 uint16_t domid; 136 uint16_t flags; 137 uint32_t count; 138 /* OUT parameters */ 139 uint64_t index; 140 /* Variable OUT parameter */ 141 uint32_t gref_ids[1]; 142 }; 143 144 #define GNTDEV_ALLOC_FLAG_WRITABLE 1 145 146 #define IOCTL_GNTDEV_DEALLOC_GREF \ 147 _IOW('E', 2, struct ioctl_gntdev_dealloc_gref) 148 struct ioctl_gntdev_dealloc_gref { 149 /* IN parameters */ 150 uint64_t index; 151 uint32_t count; 152 }; 153 154 /*-------------------- Grant Mapping IOCTLs ---------------------------------*/ 155 156 struct ioctl_gntdev_grant_ref { 157 uint32_t domid; 158 uint32_t ref; 159 }; 160 161 #define IOCTL_GNTDEV_MAP_GRANT_REF \ 162 _IOWR('E', 3, struct ioctl_gntdev_map_grant_ref) 163 struct ioctl_gntdev_map_grant_ref { 164 /* IN parameters */ 165 uint32_t count; 166 uint32_t pad0; 167 /* OUT parameters */ 168 uint64_t index; 169 /* Variable IN parameter */ 170 struct ioctl_gntdev_grant_ref refs[1]; 171 }; 172 173 #define IOCTL_GNTDEV_UNMAP_GRANT_REF \ 174 _IOW('E', 4, struct ioctl_gntdev_unmap_grant_ref) 175 struct ioctl_gntdev_unmap_grant_ref { 176 /* IN parameters */ 177 uint64_t index; 178 uint32_t count; 179 }; 180 181 #define IOCTL_GNTDEV_GET_OFFSET_FOR_VADDR \ 182 _IOWR('E', 5, struct ioctl_gntdev_get_offset_for_vaddr) 183 struct ioctl_gntdev_get_offset_for_vaddr { 184 /* IN parameters */ 185 uint64_t vaddr; 186 /* OUT parameters */ 187 uint64_t offset; 188 uint32_t count; 189 }; 190 191 #endif /* __XEN_GNTDEV_H__ */ 192