Commit | Line | Data |
---|---|---|
a42089dd JF |
1 | /****************************************************************************** |
2 | * grant_table.h | |
3 | * | |
4 | * Interface for granting foreign access to page frames, and receiving | |
5 | * page-ownership transfers. | |
6 | * | |
ad9a8612 JF |
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 | * | |
a42089dd JF |
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 | |
ad9a8612 | 38 | * reference implementation for guest OSes (arch/xen/kernel/grant_table.c). |
a42089dd JF |
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: | |
ad9a8612 | 165 | * 1. If GNTMAP_device_map is specified then <dev_bus_addr> is the address |
a42089dd | 166 | * via which I/O devices may access the granted frame. |
ad9a8612 | 167 | * 2. If GNTMAP_host_map is specified then a mapping will be added at |
a42089dd JF |
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 | }; | |
87e27cf6 | 188 | DEFINE_GUEST_HANDLE_STRUCT(gnttab_map_grant_ref); |
a42089dd JF |
189 | |
190 | /* | |
191 | * GNTTABOP_unmap_grant_ref: Destroy one or more grant-reference mappings | |
192 | * tracked by <handle>. If <host_addr> or <dev_bus_addr> is zero, that | |
193 | * field is ignored. If non-zero, they must refer to a device/host mapping | |
194 | * that is tracked by <handle> | |
195 | * NOTES: | |
196 | * 1. The call may fail in an undefined manner if either mapping is not | |
197 | * tracked by <handle>. | |
198 | * 3. After executing a batch of unmaps, it is guaranteed that no stale | |
199 | * mappings will remain in the device or host TLBs. | |
200 | */ | |
201 | #define GNTTABOP_unmap_grant_ref 1 | |
202 | struct gnttab_unmap_grant_ref { | |
203 | /* IN parameters. */ | |
204 | uint64_t host_addr; | |
205 | uint64_t dev_bus_addr; | |
206 | grant_handle_t handle; | |
207 | /* OUT parameters. */ | |
208 | int16_t status; /* GNTST_* */ | |
209 | }; | |
87e27cf6 | 210 | DEFINE_GUEST_HANDLE_STRUCT(gnttab_unmap_grant_ref); |
a42089dd JF |
211 | |
212 | /* | |
213 | * GNTTABOP_setup_table: Set up a grant table for <dom> comprising at least | |
214 | * <nr_frames> pages. The frame addresses are written to the <frame_list>. | |
215 | * Only <nr_frames> addresses are written, even if the table is larger. | |
216 | * NOTES: | |
217 | * 1. <dom> may be specified as DOMID_SELF. | |
218 | * 2. Only a sufficiently-privileged domain may specify <dom> != DOMID_SELF. | |
219 | * 3. Xen may not support more than a single grant-table page per domain. | |
220 | */ | |
221 | #define GNTTABOP_setup_table 2 | |
222 | struct gnttab_setup_table { | |
223 | /* IN parameters. */ | |
224 | domid_t dom; | |
225 | uint32_t nr_frames; | |
226 | /* OUT parameters. */ | |
227 | int16_t status; /* GNTST_* */ | |
87e27cf6 | 228 | GUEST_HANDLE(ulong) frame_list; |
a42089dd | 229 | }; |
87e27cf6 | 230 | DEFINE_GUEST_HANDLE_STRUCT(gnttab_setup_table); |
a42089dd JF |
231 | |
232 | /* | |
233 | * GNTTABOP_dump_table: Dump the contents of the grant table to the | |
234 | * xen console. Debugging use only. | |
235 | */ | |
236 | #define GNTTABOP_dump_table 3 | |
237 | struct gnttab_dump_table { | |
238 | /* IN parameters. */ | |
239 | domid_t dom; | |
240 | /* OUT parameters. */ | |
241 | int16_t status; /* GNTST_* */ | |
242 | }; | |
87e27cf6 | 243 | DEFINE_GUEST_HANDLE_STRUCT(gnttab_dump_table); |
a42089dd JF |
244 | |
245 | /* | |
246 | * GNTTABOP_transfer_grant_ref: Transfer <frame> to a foreign domain. The | |
247 | * foreign domain has previously registered its interest in the transfer via | |
248 | * <domid, ref>. | |
249 | * | |
250 | * Note that, even if the transfer fails, the specified page no longer belongs | |
251 | * to the calling domain *unless* the error is GNTST_bad_page. | |
252 | */ | |
253 | #define GNTTABOP_transfer 4 | |
254 | struct gnttab_transfer { | |
255 | /* IN parameters. */ | |
256 | unsigned long mfn; | |
257 | domid_t domid; | |
258 | grant_ref_t ref; | |
259 | /* OUT parameters. */ | |
260 | int16_t status; | |
261 | }; | |
87e27cf6 | 262 | DEFINE_GUEST_HANDLE_STRUCT(gnttab_transfer); |
ad9a8612 JF |
263 | |
264 | /* | |
265 | * GNTTABOP_copy: Hypervisor based copy | |
266 | * source and destinations can be eithers MFNs or, for foreign domains, | |
267 | * grant references. the foreign domain has to grant read/write access | |
268 | * in its grant table. | |
269 | * | |
270 | * The flags specify what type source and destinations are (either MFN | |
271 | * or grant reference). | |
272 | * | |
273 | * Note that this can also be used to copy data between two domains | |
274 | * via a third party if the source and destination domains had previously | |
275 | * grant appropriate access to their pages to the third party. | |
276 | * | |
277 | * source_offset specifies an offset in the source frame, dest_offset | |
278 | * the offset in the target frame and len specifies the number of | |
279 | * bytes to be copied. | |
280 | */ | |
281 | ||
282 | #define _GNTCOPY_source_gref (0) | |
283 | #define GNTCOPY_source_gref (1<<_GNTCOPY_source_gref) | |
284 | #define _GNTCOPY_dest_gref (1) | |
285 | #define GNTCOPY_dest_gref (1<<_GNTCOPY_dest_gref) | |
286 | ||
287 | #define GNTTABOP_copy 5 | |
288 | struct gnttab_copy { | |
289 | /* IN parameters. */ | |
290 | struct { | |
291 | union { | |
292 | grant_ref_t ref; | |
293 | unsigned long gmfn; | |
294 | } u; | |
295 | domid_t domid; | |
296 | uint16_t offset; | |
297 | } source, dest; | |
298 | uint16_t len; | |
299 | uint16_t flags; /* GNTCOPY_* */ | |
300 | /* OUT parameters. */ | |
301 | int16_t status; | |
302 | }; | |
87e27cf6 | 303 | DEFINE_GUEST_HANDLE_STRUCT(gnttab_copy); |
ad9a8612 JF |
304 | |
305 | /* | |
306 | * GNTTABOP_query_size: Query the current and maximum sizes of the shared | |
307 | * grant table. | |
308 | * NOTES: | |
309 | * 1. <dom> may be specified as DOMID_SELF. | |
310 | * 2. Only a sufficiently-privileged domain may specify <dom> != DOMID_SELF. | |
311 | */ | |
312 | #define GNTTABOP_query_size 6 | |
313 | struct gnttab_query_size { | |
314 | /* IN parameters. */ | |
315 | domid_t dom; | |
316 | /* OUT parameters. */ | |
317 | uint32_t nr_frames; | |
318 | uint32_t max_nr_frames; | |
319 | int16_t status; /* GNTST_* */ | |
320 | }; | |
87e27cf6 | 321 | DEFINE_GUEST_HANDLE_STRUCT(gnttab_query_size); |
a42089dd JF |
322 | |
323 | /* | |
324 | * Bitfield values for update_pin_status.flags. | |
325 | */ | |
326 | /* Map the grant entry for access by I/O devices. */ | |
327 | #define _GNTMAP_device_map (0) | |
328 | #define GNTMAP_device_map (1<<_GNTMAP_device_map) | |
329 | /* Map the grant entry for access by host CPUs. */ | |
330 | #define _GNTMAP_host_map (1) | |
331 | #define GNTMAP_host_map (1<<_GNTMAP_host_map) | |
332 | /* Accesses to the granted frame will be restricted to read-only access. */ | |
333 | #define _GNTMAP_readonly (2) | |
334 | #define GNTMAP_readonly (1<<_GNTMAP_readonly) | |
335 | /* | |
336 | * GNTMAP_host_map subflag: | |
337 | * 0 => The host mapping is usable only by the guest OS. | |
338 | * 1 => The host mapping is usable by guest OS + current application. | |
339 | */ | |
340 | #define _GNTMAP_application_map (3) | |
341 | #define GNTMAP_application_map (1<<_GNTMAP_application_map) | |
342 | ||
343 | /* | |
344 | * GNTMAP_contains_pte subflag: | |
345 | * 0 => This map request contains a host virtual address. | |
346 | * 1 => This map request contains the machine addess of the PTE to update. | |
347 | */ | |
348 | #define _GNTMAP_contains_pte (4) | |
349 | #define GNTMAP_contains_pte (1<<_GNTMAP_contains_pte) | |
350 | ||
351 | /* | |
352 | * Values for error status returns. All errors are -ve. | |
353 | */ | |
354 | #define GNTST_okay (0) /* Normal return. */ | |
355 | #define GNTST_general_error (-1) /* General undefined error. */ | |
356 | #define GNTST_bad_domain (-2) /* Unrecognsed domain id. */ | |
357 | #define GNTST_bad_gntref (-3) /* Unrecognised or inappropriate gntref. */ | |
358 | #define GNTST_bad_handle (-4) /* Unrecognised or inappropriate handle. */ | |
359 | #define GNTST_bad_virt_addr (-5) /* Inappropriate virtual address to map. */ | |
360 | #define GNTST_bad_dev_addr (-6) /* Inappropriate device address to unmap.*/ | |
361 | #define GNTST_no_device_space (-7) /* Out of space in I/O MMU. */ | |
362 | #define GNTST_permission_denied (-8) /* Not enough privilege for operation. */ | |
363 | #define GNTST_bad_page (-9) /* Specified page was invalid for op. */ | |
ad9a8612 | 364 | #define GNTST_bad_copy_arg (-10) /* copy arguments cross page boundary */ |
a42089dd JF |
365 | |
366 | #define GNTTABOP_error_msgs { \ | |
367 | "okay", \ | |
368 | "undefined error", \ | |
369 | "unrecognised domain id", \ | |
370 | "invalid grant reference", \ | |
371 | "invalid mapping handle", \ | |
372 | "invalid virtual address", \ | |
373 | "invalid device address", \ | |
374 | "no spare translation slot in the I/O MMU", \ | |
375 | "permission denied", \ | |
ad9a8612 JF |
376 | "bad page", \ |
377 | "copy arguments cross page boundary" \ | |
a42089dd JF |
378 | } |
379 | ||
380 | #endif /* __XEN_PUBLIC_GRANT_TABLE_H__ */ |