diff options
Diffstat (limited to 'include/xen/interface/grant_table.h')
-rw-r--r-- | include/xen/interface/grant_table.h | 375 |
1 files changed, 375 insertions, 0 deletions
diff --git a/include/xen/interface/grant_table.h b/include/xen/interface/grant_table.h new file mode 100644 index 000000000000..219049802cf2 --- /dev/null +++ b/include/xen/interface/grant_table.h | |||
@@ -0,0 +1,375 @@ | |||
1 | /****************************************************************************** | ||
2 | * grant_table.h | ||
3 | * | ||
4 | * Interface for granting foreign access to page frames, and receiving | ||
5 | * page-ownership transfers. | ||
6 | * | ||
7 | * Permission is hereby granted, free of charge, to any person obtaining a copy | ||
8 | * of this software and associated documentation files (the "Software"), to | ||
9 | * deal in the Software without restriction, including without limitation the | ||
10 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or | ||
11 | * sell copies of the Software, and to permit persons to whom the Software is | ||
12 | * furnished to do so, subject to the following conditions: | ||
13 | * | ||
14 | * The above copyright notice and this permission notice shall be included in | ||
15 | * all copies or substantial portions of the Software. | ||
16 | * | ||
17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
22 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | ||
23 | * DEALINGS IN THE SOFTWARE. | ||
24 | * | ||
25 | * Copyright (c) 2004, K A Fraser | ||
26 | */ | ||
27 | |||
28 | #ifndef __XEN_PUBLIC_GRANT_TABLE_H__ | ||
29 | #define __XEN_PUBLIC_GRANT_TABLE_H__ | ||
30 | |||
31 | |||
32 | /*********************************** | ||
33 | * GRANT TABLE REPRESENTATION | ||
34 | */ | ||
35 | |||
36 | /* Some rough guidelines on accessing and updating grant-table entries | ||
37 | * in a concurrency-safe manner. For more information, Linux contains a | ||
38 | * reference implementation for guest OSes (arch/xen/kernel/grant_table.c). | ||
39 | * | ||
40 | * NB. WMB is a no-op on current-generation x86 processors. However, a | ||
41 | * compiler barrier will still be required. | ||
42 | * | ||
43 | * Introducing a valid entry into the grant table: | ||
44 | * 1. Write ent->domid. | ||
45 | * 2. Write ent->frame: | ||
46 | * GTF_permit_access: Frame to which access is permitted. | ||
47 | * GTF_accept_transfer: Pseudo-phys frame slot being filled by new | ||
48 | * frame, or zero if none. | ||
49 | * 3. Write memory barrier (WMB). | ||
50 | * 4. Write ent->flags, inc. valid type. | ||
51 | * | ||
52 | * Invalidating an unused GTF_permit_access entry: | ||
53 | * 1. flags = ent->flags. | ||
54 | * 2. Observe that !(flags & (GTF_reading|GTF_writing)). | ||
55 | * 3. Check result of SMP-safe CMPXCHG(&ent->flags, flags, 0). | ||
56 | * NB. No need for WMB as reuse of entry is control-dependent on success of | ||
57 | * step 3, and all architectures guarantee ordering of ctrl-dep writes. | ||
58 | * | ||
59 | * Invalidating an in-use GTF_permit_access entry: | ||
60 | * This cannot be done directly. Request assistance from the domain controller | ||
61 | * which can set a timeout on the use of a grant entry and take necessary | ||
62 | * action. (NB. This is not yet implemented!). | ||
63 | * | ||
64 | * Invalidating an unused GTF_accept_transfer entry: | ||
65 | * 1. flags = ent->flags. | ||
66 | * 2. Observe that !(flags & GTF_transfer_committed). [*] | ||
67 | * 3. Check result of SMP-safe CMPXCHG(&ent->flags, flags, 0). | ||
68 | * NB. No need for WMB as reuse of entry is control-dependent on success of | ||
69 | * step 3, and all architectures guarantee ordering of ctrl-dep writes. | ||
70 | * [*] If GTF_transfer_committed is set then the grant entry is 'committed'. | ||
71 | * The guest must /not/ modify the grant entry until the address of the | ||
72 | * transferred frame is written. It is safe for the guest to spin waiting | ||
73 | * for this to occur (detect by observing GTF_transfer_completed in | ||
74 | * ent->flags). | ||
75 | * | ||
76 | * Invalidating a committed GTF_accept_transfer entry: | ||
77 | * 1. Wait for (ent->flags & GTF_transfer_completed). | ||
78 | * | ||
79 | * Changing a GTF_permit_access from writable to read-only: | ||
80 | * Use SMP-safe CMPXCHG to set GTF_readonly, while checking !GTF_writing. | ||
81 | * | ||
82 | * Changing a GTF_permit_access from read-only to writable: | ||
83 | * Use SMP-safe bit-setting instruction. | ||
84 | */ | ||
85 | |||
86 | /* | ||
87 | * A grant table comprises a packed array of grant entries in one or more | ||
88 | * page frames shared between Xen and a guest. | ||
89 | * [XEN]: This field is written by Xen and read by the sharing guest. | ||
90 | * [GST]: This field is written by the guest and read by Xen. | ||
91 | */ | ||
92 | struct grant_entry { | ||
93 | /* GTF_xxx: various type and flag information. [XEN,GST] */ | ||
94 | uint16_t flags; | ||
95 | /* The domain being granted foreign privileges. [GST] */ | ||
96 | domid_t domid; | ||
97 | /* | ||
98 | * GTF_permit_access: Frame that @domid is allowed to map and access. [GST] | ||
99 | * GTF_accept_transfer: Frame whose ownership transferred by @domid. [XEN] | ||
100 | */ | ||
101 | uint32_t frame; | ||
102 | }; | ||
103 | |||
104 | /* | ||
105 | * Type of grant entry. | ||
106 | * GTF_invalid: This grant entry grants no privileges. | ||
107 | * GTF_permit_access: Allow @domid to map/access @frame. | ||
108 | * GTF_accept_transfer: Allow @domid to transfer ownership of one page frame | ||
109 | * to this guest. Xen writes the page number to @frame. | ||
110 | */ | ||
111 | #define GTF_invalid (0U<<0) | ||
112 | #define GTF_permit_access (1U<<0) | ||
113 | #define GTF_accept_transfer (2U<<0) | ||
114 | #define GTF_type_mask (3U<<0) | ||
115 | |||
116 | /* | ||
117 | * Subflags for GTF_permit_access. | ||
118 | * GTF_readonly: Restrict @domid to read-only mappings and accesses. [GST] | ||
119 | * GTF_reading: Grant entry is currently mapped for reading by @domid. [XEN] | ||
120 | * GTF_writing: Grant entry is currently mapped for writing by @domid. [XEN] | ||
121 | */ | ||
122 | #define _GTF_readonly (2) | ||
123 | #define GTF_readonly (1U<<_GTF_readonly) | ||
124 | #define _GTF_reading (3) | ||
125 | #define GTF_reading (1U<<_GTF_reading) | ||
126 | #define _GTF_writing (4) | ||
127 | #define GTF_writing (1U<<_GTF_writing) | ||
128 | |||
129 | /* | ||
130 | * Subflags for GTF_accept_transfer: | ||
131 | * GTF_transfer_committed: Xen sets this flag to indicate that it is committed | ||
132 | * to transferring ownership of a page frame. When a guest sees this flag | ||
133 | * it must /not/ modify the grant entry until GTF_transfer_completed is | ||
134 | * set by Xen. | ||
135 | * GTF_transfer_completed: It is safe for the guest to spin-wait on this flag | ||
136 | * after reading GTF_transfer_committed. Xen will always write the frame | ||
137 | * address, followed by ORing this flag, in a timely manner. | ||
138 | */ | ||
139 | #define _GTF_transfer_committed (2) | ||
140 | #define GTF_transfer_committed (1U<<_GTF_transfer_committed) | ||
141 | #define _GTF_transfer_completed (3) | ||
142 | #define GTF_transfer_completed (1U<<_GTF_transfer_completed) | ||
143 | |||
144 | |||
145 | /*********************************** | ||
146 | * GRANT TABLE QUERIES AND USES | ||
147 | */ | ||
148 | |||
149 | /* | ||
150 | * Reference to a grant entry in a specified domain's grant table. | ||
151 | */ | ||
152 | typedef uint32_t grant_ref_t; | ||
153 | |||
154 | /* | ||
155 | * Handle to track a mapping created via a grant reference. | ||
156 | */ | ||
157 | typedef uint32_t grant_handle_t; | ||
158 | |||
159 | /* | ||
160 | * GNTTABOP_map_grant_ref: Map the grant entry (<dom>,<ref>) for access | ||
161 | * by devices and/or host CPUs. If successful, <handle> is a tracking number | ||
162 | * that must be presented later to destroy the mapping(s). On error, <handle> | ||
163 | * is a negative status code. | ||
164 | * NOTES: | ||
165 | * 1. If GNTMAP_device_map is specified then <dev_bus_addr> is the address | ||
166 | * via which I/O devices may access the granted frame. | ||
167 | * 2. If GNTMAP_host_map is specified then a mapping will be added at | ||
168 | * either a host virtual address in the current address space, or at | ||
169 | * a PTE at the specified machine address. The type of mapping to | ||
170 | * perform is selected through the GNTMAP_contains_pte flag, and the | ||
171 | * address is specified in <host_addr>. | ||
172 | * 3. Mappings should only be destroyed via GNTTABOP_unmap_grant_ref. If a | ||
173 | * host mapping is destroyed by other means then it is *NOT* guaranteed | ||
174 | * to be accounted to the correct grant reference! | ||
175 | */ | ||
176 | #define GNTTABOP_map_grant_ref 0 | ||
177 | struct gnttab_map_grant_ref { | ||
178 | /* IN parameters. */ | ||
179 | uint64_t host_addr; | ||
180 | uint32_t flags; /* GNTMAP_* */ | ||
181 | grant_ref_t ref; | ||
182 | domid_t dom; | ||
183 | /* OUT parameters. */ | ||
184 | int16_t status; /* GNTST_* */ | ||
185 | grant_handle_t handle; | ||
186 | uint64_t dev_bus_addr; | ||
187 | }; | ||
188 | |||
189 | /* | ||
190 | * GNTTABOP_unmap_grant_ref: Destroy one or more grant-reference mappings | ||
191 | * tracked by <handle>. If <host_addr> or <dev_bus_addr> is zero, that | ||
192 | * field is ignored. If non-zero, they must refer to a device/host mapping | ||
193 | * that is tracked by <handle> | ||
194 | * NOTES: | ||
195 | * 1. The call may fail in an undefined manner if either mapping is not | ||
196 | * tracked by <handle>. | ||
197 | * 3. After executing a batch of unmaps, it is guaranteed that no stale | ||
198 | * mappings will remain in the device or host TLBs. | ||
199 | */ | ||
200 | #define GNTTABOP_unmap_grant_ref 1 | ||
201 | struct gnttab_unmap_grant_ref { | ||
202 | /* IN parameters. */ | ||
203 | uint64_t host_addr; | ||
204 | uint64_t dev_bus_addr; | ||
205 | grant_handle_t handle; | ||
206 | /* OUT parameters. */ | ||
207 | int16_t status; /* GNTST_* */ | ||
208 | }; | ||
209 | |||
210 | /* | ||
211 | * GNTTABOP_setup_table: Set up a grant table for <dom> comprising at least | ||
212 | * <nr_frames> pages. The frame addresses are written to the <frame_list>. | ||
213 | * Only <nr_frames> addresses are written, even if the table is larger. | ||
214 | * NOTES: | ||
215 | * 1. <dom> may be specified as DOMID_SELF. | ||
216 | * 2. Only a sufficiently-privileged domain may specify <dom> != DOMID_SELF. | ||
217 | * 3. Xen may not support more than a single grant-table page per domain. | ||
218 | */ | ||
219 | #define GNTTABOP_setup_table 2 | ||
220 | struct gnttab_setup_table { | ||
221 | /* IN parameters. */ | ||
222 | domid_t dom; | ||
223 | uint32_t nr_frames; | ||
224 | /* OUT parameters. */ | ||
225 | int16_t status; /* GNTST_* */ | ||
226 | ulong *frame_list; | ||
227 | }; | ||
228 | |||
229 | /* | ||
230 | * GNTTABOP_dump_table: Dump the contents of the grant table to the | ||
231 | * xen console. Debugging use only. | ||
232 | */ | ||
233 | #define GNTTABOP_dump_table 3 | ||
234 | struct gnttab_dump_table { | ||
235 | /* IN parameters. */ | ||
236 | domid_t dom; | ||
237 | /* OUT parameters. */ | ||
238 | int16_t status; /* GNTST_* */ | ||
239 | }; | ||
240 | |||
241 | /* | ||
242 | * GNTTABOP_transfer_grant_ref: Transfer <frame> to a foreign domain. The | ||
243 | * foreign domain has previously registered its interest in the transfer via | ||
244 | * <domid, ref>. | ||
245 | * | ||
246 | * Note that, even if the transfer fails, the specified page no longer belongs | ||
247 | * to the calling domain *unless* the error is GNTST_bad_page. | ||
248 | */ | ||
249 | #define GNTTABOP_transfer 4 | ||
250 | struct gnttab_transfer { | ||
251 | /* IN parameters. */ | ||
252 | unsigned long mfn; | ||
253 | domid_t domid; | ||
254 | grant_ref_t ref; | ||
255 | /* OUT parameters. */ | ||
256 | int16_t status; | ||
257 | }; | ||
258 | |||
259 | |||
260 | /* | ||
261 | * GNTTABOP_copy: Hypervisor based copy | ||
262 | * source and destinations can be eithers MFNs or, for foreign domains, | ||
263 | * grant references. the foreign domain has to grant read/write access | ||
264 | * in its grant table. | ||
265 | * | ||
266 | * The flags specify what type source and destinations are (either MFN | ||
267 | * or grant reference). | ||
268 | * | ||
269 | * Note that this can also be used to copy data between two domains | ||
270 | * via a third party if the source and destination domains had previously | ||
271 | * grant appropriate access to their pages to the third party. | ||
272 | * | ||
273 | * source_offset specifies an offset in the source frame, dest_offset | ||
274 | * the offset in the target frame and len specifies the number of | ||
275 | * bytes to be copied. | ||
276 | */ | ||
277 | |||
278 | #define _GNTCOPY_source_gref (0) | ||
279 | #define GNTCOPY_source_gref (1<<_GNTCOPY_source_gref) | ||
280 | #define _GNTCOPY_dest_gref (1) | ||
281 | #define GNTCOPY_dest_gref (1<<_GNTCOPY_dest_gref) | ||
282 | |||
283 | #define GNTTABOP_copy 5 | ||
284 | struct gnttab_copy { | ||
285 | /* IN parameters. */ | ||
286 | struct { | ||
287 | union { | ||
288 | grant_ref_t ref; | ||
289 | unsigned long gmfn; | ||
290 | } u; | ||
291 | domid_t domid; | ||
292 | uint16_t offset; | ||
293 | } source, dest; | ||
294 | uint16_t len; | ||
295 | uint16_t flags; /* GNTCOPY_* */ | ||
296 | /* OUT parameters. */ | ||
297 | int16_t status; | ||
298 | }; | ||
299 | |||
300 | /* | ||
301 | * GNTTABOP_query_size: Query the current and maximum sizes of the shared | ||
302 | * grant table. | ||
303 | * NOTES: | ||
304 | * 1. <dom> may be specified as DOMID_SELF. | ||
305 | * 2. Only a sufficiently-privileged domain may specify <dom> != DOMID_SELF. | ||
306 | */ | ||
307 | #define GNTTABOP_query_size 6 | ||
308 | struct gnttab_query_size { | ||
309 | /* IN parameters. */ | ||
310 | domid_t dom; | ||
311 | /* OUT parameters. */ | ||
312 | uint32_t nr_frames; | ||
313 | uint32_t max_nr_frames; | ||
314 | int16_t status; /* GNTST_* */ | ||
315 | }; | ||
316 | |||
317 | |||
318 | /* | ||
319 | * Bitfield values for update_pin_status.flags. | ||
320 | */ | ||
321 | /* Map the grant entry for access by I/O devices. */ | ||
322 | #define _GNTMAP_device_map (0) | ||
323 | #define GNTMAP_device_map (1<<_GNTMAP_device_map) | ||
324 | /* Map the grant entry for access by host CPUs. */ | ||
325 | #define _GNTMAP_host_map (1) | ||
326 | #define GNTMAP_host_map (1<<_GNTMAP_host_map) | ||
327 | /* Accesses to the granted frame will be restricted to read-only access. */ | ||
328 | #define _GNTMAP_readonly (2) | ||
329 | #define GNTMAP_readonly (1<<_GNTMAP_readonly) | ||
330 | /* | ||
331 | * GNTMAP_host_map subflag: | ||
332 | * 0 => The host mapping is usable only by the guest OS. | ||
333 | * 1 => The host mapping is usable by guest OS + current application. | ||
334 | */ | ||
335 | #define _GNTMAP_application_map (3) | ||
336 | #define GNTMAP_application_map (1<<_GNTMAP_application_map) | ||
337 | |||
338 | /* | ||
339 | * GNTMAP_contains_pte subflag: | ||
340 | * 0 => This map request contains a host virtual address. | ||
341 | * 1 => This map request contains the machine addess of the PTE to update. | ||
342 | */ | ||
343 | #define _GNTMAP_contains_pte (4) | ||
344 | #define GNTMAP_contains_pte (1<<_GNTMAP_contains_pte) | ||
345 | |||
346 | /* | ||
347 | * Values for error status returns. All errors are -ve. | ||
348 | */ | ||
349 | #define GNTST_okay (0) /* Normal return. */ | ||
350 | #define GNTST_general_error (-1) /* General undefined error. */ | ||
351 | #define GNTST_bad_domain (-2) /* Unrecognsed domain id. */ | ||
352 | #define GNTST_bad_gntref (-3) /* Unrecognised or inappropriate gntref. */ | ||
353 | #define GNTST_bad_handle (-4) /* Unrecognised or inappropriate handle. */ | ||
354 | #define GNTST_bad_virt_addr (-5) /* Inappropriate virtual address to map. */ | ||
355 | #define GNTST_bad_dev_addr (-6) /* Inappropriate device address to unmap.*/ | ||
356 | #define GNTST_no_device_space (-7) /* Out of space in I/O MMU. */ | ||
357 | #define GNTST_permission_denied (-8) /* Not enough privilege for operation. */ | ||
358 | #define GNTST_bad_page (-9) /* Specified page was invalid for op. */ | ||
359 | #define GNTST_bad_copy_arg (-10) /* copy arguments cross page boundary */ | ||
360 | |||
361 | #define GNTTABOP_error_msgs { \ | ||
362 | "okay", \ | ||
363 | "undefined error", \ | ||
364 | "unrecognised domain id", \ | ||
365 | "invalid grant reference", \ | ||
366 | "invalid mapping handle", \ | ||
367 | "invalid virtual address", \ | ||
368 | "invalid device address", \ | ||
369 | "no spare translation slot in the I/O MMU", \ | ||
370 | "permission denied", \ | ||
371 | "bad page", \ | ||
372 | "copy arguments cross page boundary" \ | ||
373 | } | ||
374 | |||
375 | #endif /* __XEN_PUBLIC_GRANT_TABLE_H__ */ | ||