178eb3293SRoger Pau Monné /*- 278eb3293SRoger Pau Monné * Copyright (c) 2016 Akshay Jaggi <jaggi@FreeBSD.org> 378eb3293SRoger Pau Monné * All rights reserved. 478eb3293SRoger Pau Monné * 578eb3293SRoger Pau Monné * Redistribution and use in source and binary forms, with or without 678eb3293SRoger Pau Monné * modification, are permitted provided that the following conditions 778eb3293SRoger Pau Monné * are met: 878eb3293SRoger Pau Monné * 1. Redistributions of source code must retain the above copyright 978eb3293SRoger Pau Monné * notice, this list of conditions and the following disclaimer. 1078eb3293SRoger Pau Monné * 2. Redistributions in binary form must reproduce the above copyright 1178eb3293SRoger Pau Monné * notice, this list of conditions and the following disclaimer in the 1278eb3293SRoger Pau Monné * documentation and/or other materials provided with the distribution. 1378eb3293SRoger Pau Monné * 1478eb3293SRoger Pau Monné * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1578eb3293SRoger Pau Monné * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1678eb3293SRoger Pau Monné * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1778eb3293SRoger Pau Monné * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 1878eb3293SRoger Pau Monné * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 1978eb3293SRoger Pau Monné * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2078eb3293SRoger Pau Monné * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2178eb3293SRoger Pau Monné * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2278eb3293SRoger Pau Monné * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2378eb3293SRoger Pau Monné * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2478eb3293SRoger Pau Monné * SUCH DAMAGE. 2578eb3293SRoger Pau Monné * 2678eb3293SRoger Pau Monné * gntdev.h 2778eb3293SRoger Pau Monné * 2878eb3293SRoger Pau Monné * Interface to /dev/xen/gntdev. 2978eb3293SRoger Pau Monné * 3078eb3293SRoger Pau Monné * This device provides the user with two kinds of functionalities: 3178eb3293SRoger Pau Monné * 1. Grant Allocation 3278eb3293SRoger Pau Monné * Allocate a page of our own memory, and share it with a foreign domain. 3378eb3293SRoger Pau Monné * 2. Grant Mapping 3478eb3293SRoger Pau Monné * Map a grant allocated by a foreign domain, into our own memory. 3578eb3293SRoger Pau Monné * 3678eb3293SRoger Pau Monné * 3778eb3293SRoger Pau Monné * Grant Allocation 3878eb3293SRoger Pau Monné * 3978eb3293SRoger Pau Monné * Steps to allocate a grant: 4078eb3293SRoger Pau Monné * 1. Do an `IOCTL_GNTDEV_ALLOC_GREF ioctl`, with 4178eb3293SRoger Pau Monné * - `domid`, as the domain-id of the foreign domain 4278eb3293SRoger Pau Monné * - `flags`, ORed with GNTDEV_ALLOC_FLAG_WRITABLE if you want the foreign 4378eb3293SRoger Pau Monné * domain to have write access to the shared memory 4478eb3293SRoger Pau Monné * - `count`, with the number of pages to share with the foreign domain 4578eb3293SRoger Pau Monné * 4678eb3293SRoger Pau Monné * Ensure that the structure you allocate has enough memory to store 4778eb3293SRoger Pau Monné * all the allocated grant-refs, i.e., you need to allocate 4878eb3293SRoger Pau Monné * (sizeof(struct ioctl_gntdev_alloc_gref) + (count - 1)*sizeof(uint32_t)) 4978eb3293SRoger Pau Monné * bytes of memory. 5078eb3293SRoger Pau Monné * 5178eb3293SRoger Pau Monné * 2. Mmap the address given in `index` after a successful ioctl. 5278eb3293SRoger Pau Monné * This will give you access to the granted pages. 5378eb3293SRoger Pau Monné * 5478eb3293SRoger Pau Monné * Note: 5578eb3293SRoger Pau Monné * 1. The grant is not removed until all three of the following conditions 5678eb3293SRoger Pau Monné * are met 5778eb3293SRoger Pau Monné * - The region is not mmaped. That is, munmap() has been called if 5878eb3293SRoger Pau Monné * the region was mmapped previously. 5978eb3293SRoger Pau Monné * - IOCTL_GNTDEV_DEALLOC_GREF ioctl has been performed. After you 6078eb3293SRoger Pau Monné * perform this ioctl, you can no longer mmap or set notify on 6178eb3293SRoger Pau Monné * the grant. 6278eb3293SRoger Pau Monné * - The foreign domain has stopped using the grant. 6378eb3293SRoger Pau Monné * 2. Granted pages can only belong to one mmap region. 6478eb3293SRoger Pau Monné * 3. Every page of granted memory is a unit in itself. What this means 6578eb3293SRoger Pau Monné * is that you can set a unmap notification for each of the granted 6678eb3293SRoger Pau Monné * pages, individually; you can mmap and dealloc-ioctl a contiguous 6778eb3293SRoger Pau Monné * range of allocated grants (even if alloc-ioctls were performed 6878eb3293SRoger Pau Monné * individually), etc. 6978eb3293SRoger Pau Monné * 7078eb3293SRoger Pau Monné * 7178eb3293SRoger Pau Monné * Grant Mapping 7278eb3293SRoger Pau Monné * 7378eb3293SRoger Pau Monné * Steps to map a grant: 7478eb3293SRoger Pau Monné * 1. Do a `IOCTL_GNTDEV_MAP_GRANT_REF` ioctl, with 7578eb3293SRoger Pau Monné * - `count`, as the number of foreign grants to map 7678eb3293SRoger Pau Monné * - `refs[i].domid`, as the domain id of the foreign domain 7778eb3293SRoger Pau Monné * - `refs[i].ref`, as the grant-ref for the grant to be mapped 7878eb3293SRoger Pau Monné * 7978eb3293SRoger Pau Monné * 2. Mmap the address given in `index` after a successful ioctl. 8078eb3293SRoger Pau Monné * This will give you access to the mapped pages. 8178eb3293SRoger Pau Monné * 8278eb3293SRoger Pau Monné * Note: 8378eb3293SRoger Pau Monné * 1. The map hypercall is not made till the region is mmapped. 8478eb3293SRoger Pau Monné * 2. The unit is defined by the map ioctl. This means that only one 8578eb3293SRoger Pau Monné * unmap notification can be set on a group of pages that were 86*982015d2SGordon Bergling * mapped together in one ioctl, and also no single mapping of contiguous 8778eb3293SRoger Pau Monné * grant-maps is possible. 8878eb3293SRoger Pau Monné * 3. You can mmap the same grant-map region multiple times. 8978eb3293SRoger Pau Monné * 4. The grant is not unmapped until both of the following conditions are met 9078eb3293SRoger Pau Monné * - The region is not mmaped. That is, munmap() has been called for 9178eb3293SRoger Pau Monné * as many times as the grant was mmapped. 9278eb3293SRoger Pau Monné * - IOCTL_GNTDEV_UNMAP_GRANT_REF ioctl has been called. 9378eb3293SRoger Pau Monné * 5. IOCTL_GNTDEV_GET_OFFSET_FOR_VADDR ioctl gives index and count of 9478eb3293SRoger Pau Monné * a grant-map from the virtual address of the location where the grant 9578eb3293SRoger Pau Monné * is mmapped. 9678eb3293SRoger Pau Monné * 9778eb3293SRoger Pau Monné * 9878eb3293SRoger Pau Monné * IOCTL_GNTDEV_SET_UNMAP_NOTIFY 9978eb3293SRoger Pau Monné * This ioctl allows us to set notifications to be made when the grant is 10078eb3293SRoger Pau Monné * either unmapped (in case of a mapped grant), or when it is ready to be 10178eb3293SRoger Pau Monné * deallocated by us, ie, the grant is no more mmapped, and the dealloc 10278eb3293SRoger Pau Monné * ioctl has been called (in case of an allocated grant). OR `action` with 10378eb3293SRoger Pau Monné * the required notification masks, and fill in the appropriate fields. 10478eb3293SRoger Pau Monné * - UNMAP_NOTIFY_CLEAR_BYTE clears the byte at `index`, where index is 10578eb3293SRoger Pau Monné * the address of the byte in file address space. 10678eb3293SRoger Pau Monné * - UNMAP_NOTIFY_SEND_EVENT sends an event channel notification on 10778eb3293SRoger Pau Monné * `event_channel_port` 10878eb3293SRoger Pau Monné * In case of multiple notify ioctls, only the last one survives. 10978eb3293SRoger Pau Monné */ 11078eb3293SRoger Pau Monné 11178eb3293SRoger Pau Monné #ifndef __XEN_GNTDEV_H__ 11278eb3293SRoger Pau Monné #define __XEN_GNTDEV_H__ 11378eb3293SRoger Pau Monné 11478eb3293SRoger Pau Monné #include <sys/types.h> 11578eb3293SRoger Pau Monné 11678eb3293SRoger Pau Monné #define IOCTL_GNTDEV_SET_UNMAP_NOTIFY \ 11778eb3293SRoger Pau Monné _IOW('E', 0, struct ioctl_gntdev_unmap_notify) 11878eb3293SRoger Pau Monné struct ioctl_gntdev_unmap_notify { 11978eb3293SRoger Pau Monné /* IN parameters */ 12078eb3293SRoger Pau Monné uint64_t index; 12178eb3293SRoger Pau Monné uint32_t action; 12278eb3293SRoger Pau Monné uint32_t event_channel_port; 12378eb3293SRoger Pau Monné }; 12478eb3293SRoger Pau Monné 12578eb3293SRoger Pau Monné #define UNMAP_NOTIFY_CLEAR_BYTE 0x1 12678eb3293SRoger Pau Monné #define UNMAP_NOTIFY_SEND_EVENT 0x2 12778eb3293SRoger Pau Monné 12878eb3293SRoger Pau Monné /*-------------------- Grant Allocation IOCTLs ------------------------------*/ 12978eb3293SRoger Pau Monné 13078eb3293SRoger Pau Monné #define IOCTL_GNTDEV_ALLOC_GREF \ 13178eb3293SRoger Pau Monné _IOWR('E', 1, struct ioctl_gntdev_alloc_gref) 13278eb3293SRoger Pau Monné struct ioctl_gntdev_alloc_gref { 13378eb3293SRoger Pau Monné /* IN parameters */ 13478eb3293SRoger Pau Monné uint16_t domid; 13578eb3293SRoger Pau Monné uint16_t flags; 13678eb3293SRoger Pau Monné uint32_t count; 13778eb3293SRoger Pau Monné /* OUT parameters */ 13878eb3293SRoger Pau Monné uint64_t index; 13978eb3293SRoger Pau Monné /* Variable OUT parameter */ 1402602ef7cSRoger Pau Monné uint32_t *gref_ids; 14178eb3293SRoger Pau Monné }; 14278eb3293SRoger Pau Monné 14378eb3293SRoger Pau Monné #define GNTDEV_ALLOC_FLAG_WRITABLE 1 14478eb3293SRoger Pau Monné 14578eb3293SRoger Pau Monné #define IOCTL_GNTDEV_DEALLOC_GREF \ 14678eb3293SRoger Pau Monné _IOW('E', 2, struct ioctl_gntdev_dealloc_gref) 14778eb3293SRoger Pau Monné struct ioctl_gntdev_dealloc_gref { 14878eb3293SRoger Pau Monné /* IN parameters */ 14978eb3293SRoger Pau Monné uint64_t index; 15078eb3293SRoger Pau Monné uint32_t count; 15178eb3293SRoger Pau Monné }; 15278eb3293SRoger Pau Monné 15378eb3293SRoger Pau Monné /*-------------------- Grant Mapping IOCTLs ---------------------------------*/ 15478eb3293SRoger Pau Monné 15578eb3293SRoger Pau Monné struct ioctl_gntdev_grant_ref { 15678eb3293SRoger Pau Monné uint32_t domid; 15778eb3293SRoger Pau Monné uint32_t ref; 15878eb3293SRoger Pau Monné }; 15978eb3293SRoger Pau Monné 16078eb3293SRoger Pau Monné #define IOCTL_GNTDEV_MAP_GRANT_REF \ 16178eb3293SRoger Pau Monné _IOWR('E', 3, struct ioctl_gntdev_map_grant_ref) 16278eb3293SRoger Pau Monné struct ioctl_gntdev_map_grant_ref { 16378eb3293SRoger Pau Monné /* IN parameters */ 16478eb3293SRoger Pau Monné uint32_t count; 16578eb3293SRoger Pau Monné uint32_t pad0; 16678eb3293SRoger Pau Monné /* OUT parameters */ 16778eb3293SRoger Pau Monné uint64_t index; 16878eb3293SRoger Pau Monné /* Variable IN parameter */ 1692602ef7cSRoger Pau Monné struct ioctl_gntdev_grant_ref *refs; 17078eb3293SRoger Pau Monné }; 17178eb3293SRoger Pau Monné 17278eb3293SRoger Pau Monné #define IOCTL_GNTDEV_UNMAP_GRANT_REF \ 17378eb3293SRoger Pau Monné _IOW('E', 4, struct ioctl_gntdev_unmap_grant_ref) 17478eb3293SRoger Pau Monné struct ioctl_gntdev_unmap_grant_ref { 17578eb3293SRoger Pau Monné /* IN parameters */ 17678eb3293SRoger Pau Monné uint64_t index; 17778eb3293SRoger Pau Monné uint32_t count; 17878eb3293SRoger Pau Monné }; 17978eb3293SRoger Pau Monné 18078eb3293SRoger Pau Monné #define IOCTL_GNTDEV_GET_OFFSET_FOR_VADDR \ 18178eb3293SRoger Pau Monné _IOWR('E', 5, struct ioctl_gntdev_get_offset_for_vaddr) 18278eb3293SRoger Pau Monné struct ioctl_gntdev_get_offset_for_vaddr { 18378eb3293SRoger Pau Monné /* IN parameters */ 18478eb3293SRoger Pau Monné uint64_t vaddr; 18578eb3293SRoger Pau Monné /* OUT parameters */ 18678eb3293SRoger Pau Monné uint64_t offset; 18778eb3293SRoger Pau Monné uint32_t count; 18878eb3293SRoger Pau Monné }; 18978eb3293SRoger Pau Monné 19078eb3293SRoger Pau Monné #endif /* __XEN_GNTDEV_H__ */ 191