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