Home | History | Annotate | Download | only in xen
      1 /* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR MIT) */
      2 /******************************************************************************
      3  * gntdev.h
      4  *
      5  * Interface to /dev/xen/gntdev.
      6  *
      7  * Copyright (c) 2007, D G Murray
      8  * Copyright (c) 2018, Oleksandr Andrushchenko, EPAM Systems Inc.
      9  *
     10  * This program is free software; you can redistribute it and/or
     11  * modify it under the terms of the GNU General Public License version 2
     12  * as published by the Free Software Foundation; or, when distributed
     13  * separately from the Linux kernel or incorporated into other
     14  * software packages, subject to the following license:
     15  *
     16  * Permission is hereby granted, free of charge, to any person obtaining a copy
     17  * of this source file (the "Software"), to deal in the Software without
     18  * restriction, including without limitation the rights to use, copy, modify,
     19  * merge, publish, distribute, sublicense, and/or sell copies of the Software,
     20  * and to permit persons to whom the Software is furnished to do so, subject to
     21  * the following conditions:
     22  *
     23  * The above copyright notice and this permission notice shall be included in
     24  * all copies or substantial portions of the Software.
     25  *
     26  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     27  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     28  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
     29  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     30  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
     31  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
     32  * IN THE SOFTWARE.
     33  */
     34 
     35 #ifndef __LINUX_PUBLIC_GNTDEV_H__
     36 #define __LINUX_PUBLIC_GNTDEV_H__
     37 
     38 #include <linux/types.h>
     39 
     40 struct ioctl_gntdev_grant_ref {
     41 	/* The domain ID of the grant to be mapped. */
     42 	__u32 domid;
     43 	/* The grant reference of the grant to be mapped. */
     44 	__u32 ref;
     45 };
     46 
     47 /*
     48  * Inserts the grant references into the mapping table of an instance
     49  * of gntdev. N.B. This does not perform the mapping, which is deferred
     50  * until mmap() is called with @index as the offset.
     51  */
     52 #define IOCTL_GNTDEV_MAP_GRANT_REF \
     53 _IOC(_IOC_NONE, 'G', 0, sizeof(struct ioctl_gntdev_map_grant_ref))
     54 struct ioctl_gntdev_map_grant_ref {
     55 	/* IN parameters */
     56 	/* The number of grants to be mapped. */
     57 	__u32 count;
     58 	__u32 pad;
     59 	/* OUT parameters */
     60 	/* The offset to be used on a subsequent call to mmap(). */
     61 	__u64 index;
     62 	/* Variable IN parameter. */
     63 	/* Array of grant references, of size @count. */
     64 	struct ioctl_gntdev_grant_ref refs[1];
     65 };
     66 
     67 /*
     68  * Removes the grant references from the mapping table of an instance of
     69  * of gntdev. N.B. munmap() must be called on the relevant virtual address(es)
     70  * before this ioctl is called, or an error will result.
     71  */
     72 #define IOCTL_GNTDEV_UNMAP_GRANT_REF \
     73 _IOC(_IOC_NONE, 'G', 1, sizeof(struct ioctl_gntdev_unmap_grant_ref))
     74 struct ioctl_gntdev_unmap_grant_ref {
     75 	/* IN parameters */
     76 	/* The offset was returned by the corresponding map operation. */
     77 	__u64 index;
     78 	/* The number of pages to be unmapped. */
     79 	__u32 count;
     80 	__u32 pad;
     81 };
     82 
     83 /*
     84  * Returns the offset in the driver's address space that corresponds
     85  * to @vaddr. This can be used to perform a munmap(), followed by an
     86  * UNMAP_GRANT_REF ioctl, where no state about the offset is retained by
     87  * the caller. The number of pages that were allocated at the same time as
     88  * @vaddr is returned in @count.
     89  *
     90  * N.B. Where more than one page has been mapped into a contiguous range, the
     91  *      supplied @vaddr must correspond to the start of the range; otherwise
     92  *      an error will result. It is only possible to munmap() the entire
     93  *      contiguously-allocated range at once, and not any subrange thereof.
     94  */
     95 #define IOCTL_GNTDEV_GET_OFFSET_FOR_VADDR \
     96 _IOC(_IOC_NONE, 'G', 2, sizeof(struct ioctl_gntdev_get_offset_for_vaddr))
     97 struct ioctl_gntdev_get_offset_for_vaddr {
     98 	/* IN parameters */
     99 	/* The virtual address of the first mapped page in a range. */
    100 	__u64 vaddr;
    101 	/* OUT parameters */
    102 	/* The offset that was used in the initial mmap() operation. */
    103 	__u64 offset;
    104 	/* The number of pages mapped in the VM area that begins at @vaddr. */
    105 	__u32 count;
    106 	__u32 pad;
    107 };
    108 
    109 /*
    110  * Sets the maximum number of grants that may mapped at once by this gntdev
    111  * instance.
    112  *
    113  * N.B. This must be called before any other ioctl is performed on the device.
    114  */
    115 #define IOCTL_GNTDEV_SET_MAX_GRANTS \
    116 _IOC(_IOC_NONE, 'G', 3, sizeof(struct ioctl_gntdev_set_max_grants))
    117 struct ioctl_gntdev_set_max_grants {
    118 	/* IN parameter */
    119 	/* The maximum number of grants that may be mapped at once. */
    120 	__u32 count;
    121 };
    122 
    123 /*
    124  * Sets up an unmap notification within the page, so that the other side can do
    125  * cleanup if this side crashes. Required to implement cross-domain robust
    126  * mutexes or close notification on communication channels.
    127  *
    128  * Each mapped page only supports one notification; multiple calls referring to
    129  * the same page overwrite the previous notification. You must clear the
    130  * notification prior to the IOCTL_GNTALLOC_DEALLOC_GREF if you do not want it
    131  * to occur.
    132  */
    133 #define IOCTL_GNTDEV_SET_UNMAP_NOTIFY \
    134 _IOC(_IOC_NONE, 'G', 7, sizeof(struct ioctl_gntdev_unmap_notify))
    135 struct ioctl_gntdev_unmap_notify {
    136 	/* IN parameters */
    137 	/* Offset in the file descriptor for a byte within the page (same as
    138 	 * used in mmap). If using UNMAP_NOTIFY_CLEAR_BYTE, this is the byte to
    139 	 * be cleared. Otherwise, it can be any byte in the page whose
    140 	 * notification we are adjusting.
    141 	 */
    142 	__u64 index;
    143 	/* Action(s) to take on unmap */
    144 	__u32 action;
    145 	/* Event channel to notify */
    146 	__u32 event_channel_port;
    147 };
    148 
    149 struct gntdev_grant_copy_segment {
    150 	union {
    151 		void __user *virt;
    152 		struct {
    153 			grant_ref_t ref;
    154 			__u16 offset;
    155 			domid_t domid;
    156 		} foreign;
    157 	} source, dest;
    158 	__u16 len;
    159 
    160 	__u16 flags;  /* GNTCOPY_* */
    161 	__s16 status; /* GNTST_* */
    162 };
    163 
    164 /*
    165  * Copy between grant references and local buffers.
    166  *
    167  * The copy is split into @count @segments, each of which can copy
    168  * to/from one grant reference.
    169  *
    170  * Each segment is similar to struct gnttab_copy in the hypervisor ABI
    171  * except the local buffer is specified using a virtual address
    172  * (instead of a GFN and offset).
    173  *
    174  * The local buffer may cross a Xen page boundary -- the driver will
    175  * split segments into multiple ops if required.
    176  *
    177  * Returns 0 if all segments have been processed and @status in each
    178  * segment is valid.  Note that one or more segments may have failed
    179  * (status != GNTST_okay).
    180  *
    181  * If the driver had to split a segment into two or more ops, @status
    182  * includes the status of the first failed op for that segment (or
    183  * GNTST_okay if all ops were successful).
    184  *
    185  * If -1 is returned, the status of all segments is undefined.
    186  *
    187  * EINVAL: A segment has local buffers for both source and
    188  *         destination.
    189  * EINVAL: A segment crosses the boundary of a foreign page.
    190  * EFAULT: A segment's local buffer is not accessible.
    191  */
    192 #define IOCTL_GNTDEV_GRANT_COPY \
    193 	_IOC(_IOC_NONE, 'G', 8, sizeof(struct ioctl_gntdev_grant_copy))
    194 struct ioctl_gntdev_grant_copy {
    195 	unsigned int count;
    196 	struct gntdev_grant_copy_segment __user *segments;
    197 };
    198 
    199 /* Clear (set to zero) the byte specified by index */
    200 #define UNMAP_NOTIFY_CLEAR_BYTE 0x1
    201 /* Send an interrupt on the indicated event channel */
    202 #define UNMAP_NOTIFY_SEND_EVENT 0x2
    203 
    204 /*
    205  * Flags to be used while requesting memory mapping's backing storage
    206  * to be allocated with DMA API.
    207  */
    208 
    209 /*
    210  * The buffer is backed with memory allocated with dma_alloc_wc.
    211  */
    212 #define GNTDEV_DMA_FLAG_WC		(1 << 0)
    213 
    214 /*
    215  * The buffer is backed with memory allocated with dma_alloc_coherent.
    216  */
    217 #define GNTDEV_DMA_FLAG_COHERENT	(1 << 1)
    218 
    219 /*
    220  * Create a dma-buf [1] from grant references @refs of count @count provided
    221  * by the foreign domain @domid with flags @flags.
    222  *
    223  * By default dma-buf is backed by system memory pages, but by providing
    224  * one of the GNTDEV_DMA_FLAG_XXX flags it can also be created as
    225  * a DMA write-combine or coherent buffer, e.g. allocated with dma_alloc_wc/
    226  * dma_alloc_coherent.
    227  *
    228  * Returns 0 if dma-buf was successfully created and the corresponding
    229  * dma-buf's file descriptor is returned in @fd.
    230  *
    231  * [1] Documentation/driver-api/dma-buf.rst
    232  */
    233 
    234 #define IOCTL_GNTDEV_DMABUF_EXP_FROM_REFS \
    235 	_IOC(_IOC_NONE, 'G', 9, \
    236 	     sizeof(struct ioctl_gntdev_dmabuf_exp_from_refs))
    237 struct ioctl_gntdev_dmabuf_exp_from_refs {
    238 	/* IN parameters. */
    239 	/* Specific options for this dma-buf: see GNTDEV_DMA_FLAG_XXX. */
    240 	__u32 flags;
    241 	/* Number of grant references in @refs array. */
    242 	__u32 count;
    243 	/* OUT parameters. */
    244 	/* File descriptor of the dma-buf. */
    245 	__u32 fd;
    246 	/* The domain ID of the grant references to be mapped. */
    247 	__u32 domid;
    248 	/* Variable IN parameter. */
    249 	/* Array of grant references of size @count. */
    250 	__u32 refs[1];
    251 };
    252 
    253 /*
    254  * This will block until the dma-buf with the file descriptor @fd is
    255  * released. This is only valid for buffers created with
    256  * IOCTL_GNTDEV_DMABUF_EXP_FROM_REFS.
    257  *
    258  * If within @wait_to_ms milliseconds the buffer is not released
    259  * then -ETIMEDOUT error is returned.
    260  * If the buffer with the file descriptor @fd does not exist or has already
    261  * been released, then -ENOENT is returned. For valid file descriptors
    262  * this must not be treated as error.
    263  */
    264 #define IOCTL_GNTDEV_DMABUF_EXP_WAIT_RELEASED \
    265 	_IOC(_IOC_NONE, 'G', 10, \
    266 	     sizeof(struct ioctl_gntdev_dmabuf_exp_wait_released))
    267 struct ioctl_gntdev_dmabuf_exp_wait_released {
    268 	/* IN parameters */
    269 	__u32 fd;
    270 	__u32 wait_to_ms;
    271 };
    272 
    273 /*
    274  * Import a dma-buf with file descriptor @fd and export granted references
    275  * to the pages of that dma-buf into array @refs of size @count.
    276  */
    277 #define IOCTL_GNTDEV_DMABUF_IMP_TO_REFS \
    278 	_IOC(_IOC_NONE, 'G', 11, \
    279 	     sizeof(struct ioctl_gntdev_dmabuf_imp_to_refs))
    280 struct ioctl_gntdev_dmabuf_imp_to_refs {
    281 	/* IN parameters. */
    282 	/* File descriptor of the dma-buf. */
    283 	__u32 fd;
    284 	/* Number of grant references in @refs array. */
    285 	__u32 count;
    286 	/* The domain ID for which references to be granted. */
    287 	__u32 domid;
    288 	/* Reserved - must be zero. */
    289 	__u32 reserved;
    290 	/* OUT parameters. */
    291 	/* Array of grant references of size @count. */
    292 	__u32 refs[1];
    293 };
    294 
    295 /*
    296  * This will close all references to the imported buffer with file descriptor
    297  * @fd, so it can be released by the owner. This is only valid for buffers
    298  * created with IOCTL_GNTDEV_DMABUF_IMP_TO_REFS.
    299  */
    300 #define IOCTL_GNTDEV_DMABUF_IMP_RELEASE \
    301 	_IOC(_IOC_NONE, 'G', 12, \
    302 	     sizeof(struct ioctl_gntdev_dmabuf_imp_release))
    303 struct ioctl_gntdev_dmabuf_imp_release {
    304 	/* IN parameters */
    305 	__u32 fd;
    306 	__u32 reserved;
    307 };
    308 
    309 #endif /* __LINUX_PUBLIC_GNTDEV_H__ */
    310