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