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