1 /*
2  * This library is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU Lesser General Public
4  * License as published by the Free Software Foundation;
5  * version 2.1 of the License.
6  *
7  * This library is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
10  * Lesser General Public License for more details.
11  *
12  * You should have received a copy of the GNU Lesser General Public
13  * License along with this library; If not, see <http://www.gnu.org/licenses/>.
14  *
15  * Split off from:
16  * xenctrl.h
17  *
18  * A library for low-level access to the Xen control interfaces.
19  *
20  * Copyright (c) 2007-2008, D G Murray <Derek.Murray@cl.cam.ac.uk>
21  */
22 #ifndef XENGNTTAB_H
23 #define XENGNTTAB_H
24 
25 #include <stdint.h>
26 
27 #include <xen/grant_table.h>
28 #include <xen/event_channel.h>
29 
30 /* Callers who don't care don't need to #include <xentoollog.h> */
31 struct xentoollog_logger;
32 
33 /*
34  * PRODUCING AND CONSUMING GRANT REFERENCES
35  * ========================================
36  *
37  * The xengnttab library contains two distinct interfaces, each with
38  * their own distinct handle type and entry points. The represent the
39  * two sides of the grant table interface, producer (gntshr) and
40  * consumer (gnttab).
41  *
42  * The xengnttab_* interfaces take a xengnttab_handle and provide
43  * mechanisms for consuming (i.e. mapping or copying to/from) grant
44  * references provided by a peer.
45  *
46  * The xengntshr_* interfaces take a xengntshr_handle and provide a
47  * mechanism to produce grantable memory and grant references to that
48  * memory, which can be handed to some peer.
49  *
50  * UNMAP NOTIFICATION
51  * ==================
52  *
53  * The xengnt{tab,shr}_*_notify interfaces implement a cooperative
54  * interface which is intended to allow the underlying kernel
55  * interfaces to attempt to notify the peer to perform graceful
56  * teardown upon failure (i.e. crash or exit) of the process on their
57  * end.
58  *
59  * These interfaces operate on a single page only and are intended for
60  * use on the main shared-ring page of a protocol. It is assumed that
61  * on teardown both ends would automatically teardown all grants
62  * associated with the protocol in addition to the shared ring itself.
63  *
64  * Each end is able to optionally nominate a byte offset within the
65  * shared page or an event channel or both. On exit of the process the
66  * underlying kernel driver will zero the byte at the given offset and
67  * signal the event channel.
68  *
69  * The event channel can be the same event channel used for regular
70  * ring progress notifications, or may be a dedicated event channel.
71  *
72  * Both ends may share the same notification byte offset within the
73  * shared page, or may have dedicated "client" and "server" status
74  * bytes.
75  *
76  * Since the byte is cleared on shutdown the protocol must use 0 as
77  * the "closed/dead" status, but is permitted to use any other non-0
78  * values to indicate various other "live" states (waiting for
79  * connection, connected, etc).
80  *
81  * Both ends are permitted to modify (including clear) their
82  * respective status bytes and to signal the event channel themselves
83  * from userspace.
84  *
85  * Depending on the mechanisms which have been registered an
86  * the peer may receive a shutdown notification as:
87  *
88  *   - An event channel notification on a dedicated event channel
89  *   - Observation of the other ends's status byte being cleared
90  *     (whether in response to an explicit notification or in the
91  *     course of normal operation).
92  *
93  * The mechanism should be defined as part of the specific ring
94  * protocol.
95  *
96  * Upon receiving notification of the peer is expected to teardown any
97  * resources (and in particular any grant mappings) in a timely
98  * manner.
99  *
100  * NOTE: this protocol is intended to allow for better error behaviour
101  * and recovery between two cooperating peers. It does not cover the
102  * case of a malicious peer who may continue to hold resources open.
103  */
104 
105 /*
106  * Grant Table Interface (making use of grants from other domains)
107  */
108 
109 typedef struct xengntdev_handle xengnttab_handle;
110 
111 /*
112  * Returns a handle onto the grant table driver.  Logs errors.
113  *
114  * Note: After fork(2) a child process must not use any opened gnttab
115  * handle inherited from their parent, nor access any grant mapped
116  * areas associated with that handle.
117  *
118  * The child must open a new handle if they want to interact with
119  * gnttab.
120  *
121  * Calling exec(2) in a child will safely (and reliably) reclaim any
122  * resources which were allocated via a xengnttab_handle in the parent.
123  *
124  * A child which does not call exec(2) may safely call
125  * xengnttab_close() on a xengnttab_handle inherited from their
126  * parent. This will attempt to reclaim any resources associated with
127  * that handle. Note that in some implementations this reclamation may
128  * not be completely effective, in this case any affected resources
129  * remain allocated.
130  *
131  * Calling xengnttab_close() is the only safe operation on a
132  * xengnttab_handle which has been inherited. xengnttab_unmap() must
133  * not be called under such circumstances.
134  */
135 xengnttab_handle *xengnttab_open(struct xentoollog_logger *logger,
136                                  unsigned open_flags);
137 
138 /*
139  * Close a handle previously allocated with xengnttab_open(),
140  * including unmaping any current grant maps.  Never logs errors.
141  *
142  * Under normal circumstances (i.e. not in the child after a fork)
143  * xengnttab_unmap() should be used on all mappings allocated through
144  * a xengnttab_handle prior to closing the handle in order to free up
145  * resources associated with those mappings.
146  *
147  * This is the only function which may be safely called on a
148  * xengnttab_handle in a child after a fork.
149  */
150 int xengnttab_close(xengnttab_handle *xgt);
151 
152 /**
153  * Memory maps a grant reference from one domain to a local address range.
154  * Mappings should be unmapped with xengnttab_unmap.  Logs errors.
155  *
156  * @parm xgt a handle on an open grant table interface
157  * @parm domid the domain to map memory from
158  * @parm ref the grant reference ID to map
159  * @parm prot same flag as in mmap()
160  */
161 void *xengnttab_map_grant_ref(xengnttab_handle *xgt,
162                               uint32_t domid,
163                               uint32_t ref,
164                               int prot);
165 
166 /**
167  * Memory maps one or more grant references from one or more domains to a
168  * contiguous local address range. Mappings should be unmapped with
169  * xengnttab_unmap.  Logs errors.
170  *
171  * On failure (including partial failure) sets errno and returns
172  * NULL. On partial failure no mappings are established (any partial
173  * work is undone).
174  *
175  * @parm xgt a handle on an open grant table interface
176  * @parm count the number of grant references to be mapped
177  * @parm domids an array of @count domain IDs by which the corresponding @refs
178  *              were granted
179  * @parm refs an array of @count grant references to be mapped
180  * @parm prot same flag as in mmap()
181  */
182 void *xengnttab_map_grant_refs(xengnttab_handle *xgt,
183                                uint32_t count,
184                                uint32_t *domids,
185                                uint32_t *refs,
186                                int prot);
187 
188 /**
189  * Memory maps one or more grant references from one domain to a
190  * contiguous local address range. Mappings should be unmapped with
191  * xengnttab_unmap.  Logs errors.
192  *
193  * This call is equivalent to calling @xengnttab_map_grant_refs with a
194  * @domids array with every entry set to @domid.
195  *
196  * @parm xgt a handle on an open grant table interface
197  * @parm count the number of grant references to be mapped
198  * @parm domid the domain to map memory from
199  * @parm refs an array of @count grant references to be mapped
200  * @parm prot same flag as in mmap()
201  */
202 void *xengnttab_map_domain_grant_refs(xengnttab_handle *xgt,
203                                       uint32_t count,
204                                       uint32_t domid,
205                                       uint32_t *refs,
206                                       int prot);
207 
208 /**
209  * Memory maps a grant reference from one domain to a local address range.
210  * Mappings should be unmapped with xengnttab_unmap. If notify_offset or
211  * notify_port are not -1, this version will attempt to set up an unmap
212  * notification at the given offset and event channel. When the page is
213  * unmapped, the byte at the given offset will be zeroed and a wakeup will be
214  * sent to the given event channel.  Logs errors.
215  *
216  * On failure sets errno and returns NULL.
217  *
218  * If notify_offset or notify_port are requested and cannot be set up
219  * an error will be returned and no mapping will be made.
220  *
221  * @parm xgt a handle on an open grant table interface
222  * @parm domid the domain to map memory from
223  * @parm ref the grant reference ID to map
224  * @parm prot same flag as in mmap()
225  * @parm notify_offset The byte offset in the page to use for unmap
226  *                     notification; -1 for none.
227  * @parm notify_port The event channel port to use for unmap notify, or -1
228  */
229 void *xengnttab_map_grant_ref_notify(xengnttab_handle *xgt,
230                                      uint32_t domid,
231                                      uint32_t ref,
232                                      int prot,
233                                      uint32_t notify_offset,
234                                      evtchn_port_t notify_port);
235 
236 /**
237  * Unmaps the @count pages starting at @start_address, which were
238  * mapped by a call to xengnttab_map_grant_ref,
239  * xengnttab_map_grant_refs or xengnttab_map_grant_ref_notify. Never
240  * logs.
241  *
242  * If the mapping was made using xengnttab_map_grant_ref_notify() with
243  * either notify_offset or notify_port then the peer will be notified.
244  */
245 int xengnttab_unmap(xengnttab_handle *xgt, void *start_address, uint32_t count);
246 
247 /**
248  * Sets the maximum number of grants that may be mapped by the given
249  * instance to @count.  Never logs.
250  *
251  * N.B. This function must be called after opening the handle, and before any
252  *      other functions are invoked on it.
253  *
254  * N.B. When variable-length grants are mapped, fragmentation may be observed,
255  *      and it may not be possible to satisfy requests up to the maximum number
256  *      of grants.
257  */
258 int xengnttab_set_max_grants(xengnttab_handle *xgt,
259                              uint32_t nr_grants);
260 
261 struct xengnttab_grant_copy_segment {
262     union xengnttab_copy_ptr {
263         void *virt;
264         struct {
265             uint32_t ref;
266             uint16_t offset;
267             uint16_t domid;
268         } foreign;
269     } source, dest;
270     uint16_t len;
271     uint16_t flags;
272     int16_t status;
273 };
274 
275 typedef struct xengnttab_grant_copy_segment xengnttab_grant_copy_segment_t;
276 
277 /**
278  * Copy memory from or to grant references. The information of each operations
279  * are contained in 'xengnttab_grant_copy_segment_t'. The @flag value indicate
280  * the direction of an operation (GNTCOPY_source_gref\GNTCOPY_dest_gref).
281  *
282  * For each segment, @virt may cross a page boundary but @offset + @len
283  * must not exceed XEN_PAGE_SIZE.
284  */
285 int xengnttab_grant_copy(xengnttab_handle *xgt,
286                          uint32_t count,
287                          xengnttab_grant_copy_segment_t *segs);
288 
289 /*
290  * Grant Sharing Interface (allocating and granting pages to others)
291  */
292 
293 typedef struct xengntdev_handle xengntshr_handle;
294 
295 /*
296  * Returns a handle onto the grant sharing driver.  Logs errors.
297  *
298  * Note: After fork(2) a child process must not use any opened gntshr
299  * handle inherited from their parent, nor access any grant mapped
300  * areas associated with that handle.
301  *
302  * The child must open a new handle if they want to interact with
303  * gntshr.
304  *
305  * Calling exec(2) in a child will safely (and reliably) reclaim any
306  * resources which were allocated via a xengntshr_handle in the
307  * parent.
308  *
309  * A child which does not call exec(2) may safely call
310  * xengntshr_close() on a xengntshr_handle inherited from their
311  * parent. This will attempt to reclaim any resources associated with
312  * that handle. Note that in some implementations this reclamation may
313  * not be completely effective, in this case any affected resources
314  * remain allocated.
315  *
316  * Calling xengntshr_close() is the only safe operation on a
317  * xengntshr_handle which has been inherited.
318  */
319 xengntshr_handle *xengntshr_open(struct xentoollog_logger *logger,
320                                  unsigned open_flags);
321 
322 /*
323  * Close a handle previously allocated with xengntshr_open().
324  * Never logs errors.
325  *
326  * Under normal circumstances (i.e. not in the child after a fork)
327  * xengntshr_unmap() should be used on all mappings allocated through
328  * a xengnttab_handle prior to closing the handle in order to free up
329  * resources associated with those mappings.
330  *
331  * xengntshr_close() is the only function which may be safely called
332  * on a xengntshr_handle in a child after a fork. xengntshr_unshare()
333  * must not be called under such circumstances.
334  */
335 int xengntshr_close(xengntshr_handle *xgs);
336 
337 /**
338  * Allocates and shares pages with another domain.
339  *
340  * On failure sets errno and returns NULL. No allocations will be made.
341  *
342  * This library only provides functionality for sharing memory
343  * allocated via this call, memory from elsewhere (malloc, mmap etc)
344  * cannot be shared here.
345  *
346  * @parm xgs a handle to an open grant sharing instance
347  * @parm domid the domain to share memory with
348  * @parm count the number of pages to share
349  * @parm refs the grant references of the pages (output)
350  * @parm writable true if the other domain can write to the pages
351  * @return local mapping of the pages
352  */
353 void *xengntshr_share_pages(xengntshr_handle *xgs, uint32_t domid,
354                             int count, uint32_t *refs, int writable);
355 
356 /**
357  * Creates and shares a page with another domain, with unmap notification.
358  *
359  * @parm xgs a handle to an open grant sharing instance
360  * @parm domid the domain to share memory with
361  * @parm refs the grant reference of the pages (output)
362  * @parm writable true if the other domain can write to the page
363  * @parm notify_offset The byte offset in the page to use for unmap
364  *                     notification; -1 for none.
365  * @parm notify_port The event channel port to use for unmap notify, or -1
366  * @return local mapping of the page
367  */
368 void *xengntshr_share_page_notify(xengntshr_handle *xgs, uint32_t domid,
369                                   uint32_t *ref, int writable,
370                                   uint32_t notify_offset,
371                                   evtchn_port_t notify_port);
372 
373 /**
374  * Unmaps the @count pages starting at @start_address, which were
375  * mapped by a call to xengntshr_share_*. Never logs.
376  *
377  * If the mapping was made using xengntshr_share_page_notify() with
378  * either notify_offset or notify_port then the peer will be notified.
379  */
380 int xengntshr_unshare(xengntshr_handle *xgs, void *start_address, uint32_t count);
381 
382 #endif
383 
384 /*
385  * Local variables:
386  * mode: C
387  * c-file-style: "BSD"
388  * c-basic-offset: 4
389  * tab-width: 4
390  * indent-tabs-mode: nil
391  * End:
392  */
393