xref: /freebsd/sys/xen/gntdev.h (revision 78eb32933bb31254ca8d28f8597702ea4deb3e33)
1*78eb3293SRoger Pau Monné /*-
2*78eb3293SRoger Pau Monné  * Copyright (c) 2016 Akshay Jaggi <jaggi@FreeBSD.org>
3*78eb3293SRoger Pau Monné  * All rights reserved.
4*78eb3293SRoger Pau Monné  *
5*78eb3293SRoger Pau Monné  * Redistribution and use in source and binary forms, with or without
6*78eb3293SRoger Pau Monné  * modification, are permitted provided that the following conditions
7*78eb3293SRoger Pau Monné  * are met:
8*78eb3293SRoger Pau Monné  * 1. Redistributions of source code must retain the above copyright
9*78eb3293SRoger Pau Monné  *    notice, this list of conditions and the following disclaimer.
10*78eb3293SRoger Pau Monné  * 2. Redistributions in binary form must reproduce the above copyright
11*78eb3293SRoger Pau Monné  *    notice, this list of conditions and the following disclaimer in the
12*78eb3293SRoger Pau Monné  *    documentation and/or other materials provided with the distribution.
13*78eb3293SRoger Pau Monné  *
14*78eb3293SRoger Pau Monné  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15*78eb3293SRoger Pau Monné  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16*78eb3293SRoger Pau Monné  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17*78eb3293SRoger Pau Monné  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18*78eb3293SRoger Pau Monné  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19*78eb3293SRoger Pau Monné  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20*78eb3293SRoger Pau Monné  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21*78eb3293SRoger Pau Monné  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22*78eb3293SRoger Pau Monné  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23*78eb3293SRoger Pau Monné  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24*78eb3293SRoger Pau Monné  * SUCH DAMAGE.
25*78eb3293SRoger Pau Monné  *
26*78eb3293SRoger Pau Monné  * gntdev.h
27*78eb3293SRoger Pau Monné  *
28*78eb3293SRoger Pau Monné  * Interface to /dev/xen/gntdev.
29*78eb3293SRoger Pau Monné  *
30*78eb3293SRoger Pau Monné  * This device provides the user with two kinds of functionalities:
31*78eb3293SRoger Pau Monné  * 1. Grant Allocation
32*78eb3293SRoger Pau Monné  *    Allocate a page of our own memory, and share it with a foreign domain.
33*78eb3293SRoger Pau Monné  * 2. Grant Mapping
34*78eb3293SRoger Pau Monné  *    Map a grant allocated by a foreign domain, into our own memory.
35*78eb3293SRoger Pau Monné  *
36*78eb3293SRoger Pau Monné  *
37*78eb3293SRoger Pau Monné  * Grant Allocation
38*78eb3293SRoger Pau Monné  *
39*78eb3293SRoger Pau Monné  * Steps to allocate a grant:
40*78eb3293SRoger Pau Monné  * 1. Do an `IOCTL_GNTDEV_ALLOC_GREF ioctl`, with
41*78eb3293SRoger Pau Monné  *     - `domid`, as the domain-id of the foreign domain
42*78eb3293SRoger Pau Monné  *     - `flags`, ORed with GNTDEV_ALLOC_FLAG_WRITABLE if you want the foreign
43*78eb3293SRoger Pau Monné  *       domain to have write access to the shared memory
44*78eb3293SRoger Pau Monné  *     - `count`, with the number of pages to share with the foreign domain
45*78eb3293SRoger Pau Monné  *
46*78eb3293SRoger Pau Monné  *    Ensure that the structure you allocate has enough memory to store
47*78eb3293SRoger Pau Monné  *    all the allocated grant-refs, i.e., you need to allocate
48*78eb3293SRoger Pau Monné  *    (sizeof(struct ioctl_gntdev_alloc_gref) + (count - 1)*sizeof(uint32_t))
49*78eb3293SRoger Pau Monné  *    bytes of memory.
50*78eb3293SRoger Pau Monné  *
51*78eb3293SRoger Pau Monné  * 2. Mmap the address given in `index` after a successful ioctl.
52*78eb3293SRoger Pau Monné  *    This will give you access to the granted pages.
53*78eb3293SRoger Pau Monné  *
54*78eb3293SRoger Pau Monné  * Note:
55*78eb3293SRoger Pau Monné  * 1. The grant is not removed until all three of the following conditions
56*78eb3293SRoger Pau Monné  *    are met
57*78eb3293SRoger Pau Monné  *     - The region is not mmaped. That is, munmap() has been called if
58*78eb3293SRoger Pau Monné  *       the region was mmapped previously.
59*78eb3293SRoger Pau Monné  *     - IOCTL_GNTDEV_DEALLOC_GREF ioctl has been performed. After you
60*78eb3293SRoger Pau Monné  *       perform this ioctl, you can no longer mmap or set notify on
61*78eb3293SRoger Pau Monné  *       the grant.
62*78eb3293SRoger Pau Monné  *     - The foreign domain has stopped using the grant.
63*78eb3293SRoger Pau Monné  * 2. Granted pages can only belong to one mmap region.
64*78eb3293SRoger Pau Monné  * 3. Every page of granted memory is a unit in itself. What this means
65*78eb3293SRoger Pau Monné  *    is that you can set a unmap notification for each of the granted
66*78eb3293SRoger Pau Monné  *    pages, individually; you can mmap and dealloc-ioctl a contiguous
67*78eb3293SRoger Pau Monné  *    range of allocated grants (even if alloc-ioctls were performed
68*78eb3293SRoger Pau Monné  *    individually), etc.
69*78eb3293SRoger Pau Monné  *
70*78eb3293SRoger Pau Monné  *
71*78eb3293SRoger Pau Monné  * Grant Mapping
72*78eb3293SRoger Pau Monné  *
73*78eb3293SRoger Pau Monné  * Steps to map a grant:
74*78eb3293SRoger Pau Monné  * 1. Do a `IOCTL_GNTDEV_MAP_GRANT_REF` ioctl, with
75*78eb3293SRoger Pau Monné  *     - `count`, as the number of foreign grants to map
76*78eb3293SRoger Pau Monné  *     - `refs[i].domid`, as the domain id of the foreign domain
77*78eb3293SRoger Pau Monné  *     - `refs[i].ref`, as the grant-ref for the grant to be mapped
78*78eb3293SRoger Pau Monné  *
79*78eb3293SRoger Pau Monné  * 2. Mmap the address given in `index` after a successful ioctl.
80*78eb3293SRoger Pau Monné  *    This will give you access to the mapped pages.
81*78eb3293SRoger Pau Monné  *
82*78eb3293SRoger Pau Monné  * Note:
83*78eb3293SRoger Pau Monné  * 1. The map hypercall is not made till the region is mmapped.
84*78eb3293SRoger Pau Monné  * 2. The unit is defined by the map ioctl. This means that only one
85*78eb3293SRoger Pau Monné  *    unmap notification can be set on a group of pages that were
86*78eb3293SRoger Pau Monné  *    mapped together in one ioctl, and also no single mmaping of contiguous
87*78eb3293SRoger Pau Monné  *    grant-maps is possible.
88*78eb3293SRoger Pau Monné  * 3. You can mmap the same grant-map region multiple times.
89*78eb3293SRoger Pau Monné  * 4. The grant is not unmapped until both of the following conditions are met
90*78eb3293SRoger Pau Monné  *     - The region is not mmaped. That is, munmap() has been called for
91*78eb3293SRoger Pau Monné  *       as many times as the grant was mmapped.
92*78eb3293SRoger Pau Monné  *     - IOCTL_GNTDEV_UNMAP_GRANT_REF ioctl has been called.
93*78eb3293SRoger Pau Monné  * 5. IOCTL_GNTDEV_GET_OFFSET_FOR_VADDR ioctl gives index and count of
94*78eb3293SRoger Pau Monné  *    a grant-map from the virtual address of the location where the grant
95*78eb3293SRoger Pau Monné  *    is mmapped.
96*78eb3293SRoger Pau Monné  *
97*78eb3293SRoger Pau Monné  *
98*78eb3293SRoger Pau Monné  * IOCTL_GNTDEV_SET_UNMAP_NOTIFY
99*78eb3293SRoger Pau Monné  * This ioctl allows us to set notifications to be made when the grant is
100*78eb3293SRoger Pau Monné  * either unmapped (in case of a mapped grant), or when it is ready to be
101*78eb3293SRoger Pau Monné  * deallocated by us, ie, the grant is no more mmapped, and the dealloc
102*78eb3293SRoger Pau Monné  * ioctl has been called (in case of an allocated grant). OR `action` with
103*78eb3293SRoger Pau Monné  * the required notification masks, and fill in the appropriate fields.
104*78eb3293SRoger Pau Monné  *  - UNMAP_NOTIFY_CLEAR_BYTE clears the byte at `index`, where index is
105*78eb3293SRoger Pau Monné  *    the address of the byte in file address space.
106*78eb3293SRoger Pau Monné  *  - UNMAP_NOTIFY_SEND_EVENT sends an event channel notification on
107*78eb3293SRoger Pau Monné  *    `event_channel_port`
108*78eb3293SRoger Pau Monné  * In case of multiple notify ioctls, only the last one survives.
109*78eb3293SRoger Pau Monné  *
110*78eb3293SRoger Pau Monné  * $FreeBSD$
111*78eb3293SRoger Pau Monné  */
112*78eb3293SRoger Pau Monné 
113*78eb3293SRoger Pau Monné #ifndef __XEN_GNTDEV_H__
114*78eb3293SRoger Pau Monné #define __XEN_GNTDEV_H__
115*78eb3293SRoger Pau Monné 
116*78eb3293SRoger Pau Monné #include <sys/types.h>
117*78eb3293SRoger Pau Monné 
118*78eb3293SRoger Pau Monné #define IOCTL_GNTDEV_SET_UNMAP_NOTIFY					\
119*78eb3293SRoger Pau Monné 	_IOW('E', 0, struct ioctl_gntdev_unmap_notify)
120*78eb3293SRoger Pau Monné struct ioctl_gntdev_unmap_notify {
121*78eb3293SRoger Pau Monné     /* IN parameters */
122*78eb3293SRoger Pau Monné     uint64_t index;
123*78eb3293SRoger Pau Monné     uint32_t action;
124*78eb3293SRoger Pau Monné     uint32_t event_channel_port;
125*78eb3293SRoger Pau Monné };
126*78eb3293SRoger Pau Monné 
127*78eb3293SRoger Pau Monné #define UNMAP_NOTIFY_CLEAR_BYTE 0x1
128*78eb3293SRoger Pau Monné #define UNMAP_NOTIFY_SEND_EVENT 0x2
129*78eb3293SRoger Pau Monné 
130*78eb3293SRoger Pau Monné /*-------------------- Grant Allocation IOCTLs  ------------------------------*/
131*78eb3293SRoger Pau Monné 
132*78eb3293SRoger Pau Monné #define IOCTL_GNTDEV_ALLOC_GREF						\
133*78eb3293SRoger Pau Monné 	_IOWR('E', 1, struct ioctl_gntdev_alloc_gref)
134*78eb3293SRoger Pau Monné struct ioctl_gntdev_alloc_gref {
135*78eb3293SRoger Pau Monné     /* IN parameters */
136*78eb3293SRoger Pau Monné     uint16_t domid;
137*78eb3293SRoger Pau Monné     uint16_t flags;
138*78eb3293SRoger Pau Monné     uint32_t count;
139*78eb3293SRoger Pau Monné     /* OUT parameters */
140*78eb3293SRoger Pau Monné     uint64_t index;
141*78eb3293SRoger Pau Monné     /* Variable OUT parameter */
142*78eb3293SRoger Pau Monné     uint32_t gref_ids[1];
143*78eb3293SRoger Pau Monné };
144*78eb3293SRoger Pau Monné 
145*78eb3293SRoger Pau Monné #define GNTDEV_ALLOC_FLAG_WRITABLE 1
146*78eb3293SRoger Pau Monné 
147*78eb3293SRoger Pau Monné #define IOCTL_GNTDEV_DEALLOC_GREF					\
148*78eb3293SRoger Pau Monné 	_IOW('E', 2, struct ioctl_gntdev_dealloc_gref)
149*78eb3293SRoger Pau Monné struct ioctl_gntdev_dealloc_gref {
150*78eb3293SRoger Pau Monné     /* IN parameters */
151*78eb3293SRoger Pau Monné     uint64_t index;
152*78eb3293SRoger Pau Monné     uint32_t count;
153*78eb3293SRoger Pau Monné };
154*78eb3293SRoger Pau Monné 
155*78eb3293SRoger Pau Monné /*-------------------- Grant Mapping IOCTLs  ---------------------------------*/
156*78eb3293SRoger Pau Monné 
157*78eb3293SRoger Pau Monné struct ioctl_gntdev_grant_ref {
158*78eb3293SRoger Pau Monné     uint32_t domid;
159*78eb3293SRoger Pau Monné     uint32_t ref;
160*78eb3293SRoger Pau Monné };
161*78eb3293SRoger Pau Monné 
162*78eb3293SRoger Pau Monné #define IOCTL_GNTDEV_MAP_GRANT_REF					\
163*78eb3293SRoger Pau Monné 	_IOWR('E', 3, struct ioctl_gntdev_map_grant_ref)
164*78eb3293SRoger Pau Monné struct ioctl_gntdev_map_grant_ref {
165*78eb3293SRoger Pau Monné     /* IN parameters */
166*78eb3293SRoger Pau Monné     uint32_t count;
167*78eb3293SRoger Pau Monné     uint32_t pad0;
168*78eb3293SRoger Pau Monné     /* OUT parameters */
169*78eb3293SRoger Pau Monné     uint64_t index;
170*78eb3293SRoger Pau Monné     /* Variable IN parameter */
171*78eb3293SRoger Pau Monné     struct ioctl_gntdev_grant_ref refs[1];
172*78eb3293SRoger Pau Monné };
173*78eb3293SRoger Pau Monné 
174*78eb3293SRoger Pau Monné #define IOCTL_GNTDEV_UNMAP_GRANT_REF					\
175*78eb3293SRoger Pau Monné 	_IOW('E', 4, struct ioctl_gntdev_unmap_grant_ref)
176*78eb3293SRoger Pau Monné struct ioctl_gntdev_unmap_grant_ref {
177*78eb3293SRoger Pau Monné     /* IN parameters */
178*78eb3293SRoger Pau Monné     uint64_t index;
179*78eb3293SRoger Pau Monné     uint32_t count;
180*78eb3293SRoger Pau Monné };
181*78eb3293SRoger Pau Monné 
182*78eb3293SRoger Pau Monné #define IOCTL_GNTDEV_GET_OFFSET_FOR_VADDR				\
183*78eb3293SRoger Pau Monné 	_IOWR('E', 5, struct ioctl_gntdev_get_offset_for_vaddr)
184*78eb3293SRoger Pau Monné struct ioctl_gntdev_get_offset_for_vaddr {
185*78eb3293SRoger Pau Monné     /* IN parameters */
186*78eb3293SRoger Pau Monné     uint64_t vaddr;
187*78eb3293SRoger Pau Monné     /* OUT parameters */
188*78eb3293SRoger Pau Monné     uint64_t offset;
189*78eb3293SRoger Pau Monné     uint32_t count;
190*78eb3293SRoger Pau Monné };
191*78eb3293SRoger Pau Monné 
192*78eb3293SRoger Pau Monné #endif /* __XEN_GNTDEV_H__ */
193