]>
Commit | Line | Data |
---|---|---|
6b621f95 AP |
1 | /******************************************************************************\r |
2 | * grant_table.h\r | |
3 | *\r | |
4 | * Interface for granting foreign access to page frames, and receiving\r | |
5 | * page-ownership transfers.\r | |
6 | *\r | |
6f21d772 | 7 | * SPDX-License-Identifier: MIT\r |
6b621f95 AP |
8 | *\r |
9 | * Copyright (c) 2004, K A Fraser\r | |
10 | */\r | |
11 | \r | |
12 | #ifndef __XEN_PUBLIC_GRANT_TABLE_H__\r | |
13 | #define __XEN_PUBLIC_GRANT_TABLE_H__\r | |
14 | \r | |
15 | #include "xen.h"\r | |
16 | \r | |
17 | /*\r | |
18 | * `incontents 150 gnttab Grant Tables\r | |
19 | *\r | |
20 | * Xen's grant tables provide a generic mechanism to memory sharing\r | |
21 | * between domains. This shared memory interface underpins the split\r | |
22 | * device drivers for block and network IO.\r | |
23 | *\r | |
24 | * Each domain has its own grant table. This is a data structure that\r | |
25 | * is shared with Xen; it allows the domain to tell Xen what kind of\r | |
26 | * permissions other domains have on its pages. Entries in the grant\r | |
27 | * table are identified by grant references. A grant reference is an\r | |
28 | * integer, which indexes into the grant table. It acts as a\r | |
29 | * capability which the grantee can use to perform operations on the\r | |
3e079d01 | 30 | * granter's memory.\r |
6b621f95 AP |
31 | *\r |
32 | * This capability-based system allows shared-memory communications\r | |
33 | * between unprivileged domains. A grant reference also encapsulates\r | |
34 | * the details of a shared page, removing the need for a domain to\r | |
35 | * know the real machine address of a page it is sharing. This makes\r | |
36 | * it possible to share memory correctly with domains running in\r | |
37 | * fully virtualised memory.\r | |
38 | */\r | |
39 | \r | |
40 | /***********************************\r | |
41 | * GRANT TABLE REPRESENTATION\r | |
42 | */\r | |
43 | \r | |
44 | /* Some rough guidelines on accessing and updating grant-table entries\r | |
45 | * in a concurrency-safe manner. For more information, Linux contains a\r | |
46 | * reference implementation for guest OSes (drivers/xen/grant_table.c, see\r | |
47 | * http://git.kernel.org/?p=linux/kernel/git/torvalds/linux.git;a=blob;f=drivers/xen/grant-table.c;hb=HEAD\r | |
48 | *\r | |
49 | * NB. WMB is a no-op on current-generation x86 processors. However, a\r | |
50 | * compiler barrier will still be required.\r | |
51 | *\r | |
52 | * Introducing a valid entry into the grant table:\r | |
53 | * 1. Write ent->domid.\r | |
54 | * 2. Write ent->frame:\r | |
55 | * GTF_permit_access: Frame to which access is permitted.\r | |
56 | * GTF_accept_transfer: Pseudo-phys frame slot being filled by new\r | |
57 | * frame, or zero if none.\r | |
58 | * 3. Write memory barrier (WMB).\r | |
59 | * 4. Write ent->flags, inc. valid type.\r | |
60 | *\r | |
61 | * Invalidating an unused GTF_permit_access entry:\r | |
62 | * 1. flags = ent->flags.\r | |
63 | * 2. Observe that !(flags & (GTF_reading|GTF_writing)).\r | |
64 | * 3. Check result of SMP-safe CMPXCHG(&ent->flags, flags, 0).\r | |
65 | * NB. No need for WMB as reuse of entry is control-dependent on success of\r | |
66 | * step 3, and all architectures guarantee ordering of ctrl-dep writes.\r | |
67 | *\r | |
68 | * Invalidating an in-use GTF_permit_access entry:\r | |
69 | * This cannot be done directly. Request assistance from the domain controller\r | |
70 | * which can set a timeout on the use of a grant entry and take necessary\r | |
71 | * action. (NB. This is not yet implemented!).\r | |
72 | *\r | |
73 | * Invalidating an unused GTF_accept_transfer entry:\r | |
74 | * 1. flags = ent->flags.\r | |
75 | * 2. Observe that !(flags & GTF_transfer_committed). [*]\r | |
76 | * 3. Check result of SMP-safe CMPXCHG(&ent->flags, flags, 0).\r | |
77 | * NB. No need for WMB as reuse of entry is control-dependent on success of\r | |
78 | * step 3, and all architectures guarantee ordering of ctrl-dep writes.\r | |
79 | * [*] If GTF_transfer_committed is set then the grant entry is 'committed'.\r | |
80 | * The guest must /not/ modify the grant entry until the address of the\r | |
81 | * transferred frame is written. It is safe for the guest to spin waiting\r | |
82 | * for this to occur (detect by observing GTF_transfer_completed in\r | |
83 | * ent->flags).\r | |
84 | *\r | |
85 | * Invalidating a committed GTF_accept_transfer entry:\r | |
86 | * 1. Wait for (ent->flags & GTF_transfer_completed).\r | |
87 | *\r | |
88 | * Changing a GTF_permit_access from writable to read-only:\r | |
89 | * Use SMP-safe CMPXCHG to set GTF_readonly, while checking !GTF_writing.\r | |
90 | *\r | |
91 | * Changing a GTF_permit_access from read-only to writable:\r | |
92 | * Use SMP-safe bit-setting instruction.\r | |
93 | */\r | |
94 | \r | |
95 | /*\r | |
96 | * Reference to a grant entry in a specified domain's grant table.\r | |
97 | */\r | |
98 | typedef UINT32 grant_ref_t;\r | |
99 | \r | |
100 | /*\r | |
101 | * A grant table comprises a packed array of grant entries in one or more\r | |
102 | * page frames shared between Xen and a guest.\r | |
103 | * [XEN]: This field is written by Xen and read by the sharing guest.\r | |
104 | * [GST]: This field is written by the guest and read by Xen.\r | |
105 | */\r | |
106 | \r | |
107 | /*\r | |
108 | * Version 1 of the grant table entry structure is maintained purely\r | |
109 | * for backwards compatibility. New guests should use version 2.\r | |
110 | */\r | |
111 | #if __XEN_INTERFACE_VERSION__ < 0x0003020a\r | |
112 | #define grant_entry_v1 grant_entry\r | |
113 | #define grant_entry_v1_t grant_entry_t\r | |
114 | #endif\r | |
115 | struct grant_entry_v1 {\r | |
116 | /* GTF_xxx: various type and flag information. [XEN,GST] */\r | |
117 | UINT16 flags;\r | |
118 | /* The domain being granted foreign privileges. [GST] */\r | |
119 | domid_t domid;\r | |
120 | /*\r | |
121 | * GTF_permit_access: Frame that @domid is allowed to map and access. [GST]\r | |
122 | * GTF_accept_transfer: Frame whose ownership transferred by @domid. [XEN]\r | |
123 | */\r | |
124 | UINT32 frame;\r | |
125 | };\r | |
126 | typedef struct grant_entry_v1 grant_entry_v1_t;\r | |
127 | \r | |
128 | /* The first few grant table entries will be preserved across grant table\r | |
129 | * version changes and may be pre-populated at domain creation by tools.\r | |
130 | */\r | |
131 | #define GNTTAB_NR_RESERVED_ENTRIES 8\r | |
132 | #define GNTTAB_RESERVED_CONSOLE 0\r | |
133 | #define GNTTAB_RESERVED_XENSTORE 1\r | |
134 | \r | |
135 | /*\r | |
136 | * Type of grant entry.\r | |
137 | * GTF_invalid: This grant entry grants no privileges.\r | |
138 | * GTF_permit_access: Allow @domid to map/access @frame.\r | |
139 | * GTF_accept_transfer: Allow @domid to transfer ownership of one page frame\r | |
140 | * to this guest. Xen writes the page number to @frame.\r | |
141 | * GTF_transitive: Allow @domid to transitively access a subrange of\r | |
142 | * @trans_grant in @trans_domid. No mappings are allowed.\r | |
143 | */\r | |
144 | #define GTF_invalid (0U<<0)\r | |
145 | #define GTF_permit_access (1U<<0)\r | |
146 | #define GTF_accept_transfer (2U<<0)\r | |
147 | #define GTF_transitive (3U<<0)\r | |
148 | #define GTF_type_mask (3U<<0)\r | |
149 | \r | |
150 | /*\r | |
151 | * Subflags for GTF_permit_access.\r | |
152 | * GTF_readonly: Restrict @domid to read-only mappings and accesses. [GST]\r | |
153 | * GTF_reading: Grant entry is currently mapped for reading by @domid. [XEN]\r | |
154 | * GTF_writing: Grant entry is currently mapped for writing by @domid. [XEN]\r | |
155 | * GTF_PAT, GTF_PWT, GTF_PCD: (x86) cache attribute flags for the grant [GST]\r | |
156 | * GTF_sub_page: Grant access to only a subrange of the page. @domid\r | |
157 | * will only be allowed to copy from the grant, and not\r | |
158 | * map it. [GST]\r | |
159 | */\r | |
160 | #define _GTF_readonly (2)\r | |
161 | #define GTF_readonly (1U<<_GTF_readonly)\r | |
162 | #define _GTF_reading (3)\r | |
163 | #define GTF_reading (1U<<_GTF_reading)\r | |
164 | #define _GTF_writing (4)\r | |
165 | #define GTF_writing (1U<<_GTF_writing)\r | |
166 | #define _GTF_PWT (5)\r | |
167 | #define GTF_PWT (1U<<_GTF_PWT)\r | |
168 | #define _GTF_PCD (6)\r | |
169 | #define GTF_PCD (1U<<_GTF_PCD)\r | |
170 | #define _GTF_PAT (7)\r | |
171 | #define GTF_PAT (1U<<_GTF_PAT)\r | |
172 | #define _GTF_sub_page (8)\r | |
173 | #define GTF_sub_page (1U<<_GTF_sub_page)\r | |
174 | \r | |
175 | /*\r | |
176 | * Subflags for GTF_accept_transfer:\r | |
177 | * GTF_transfer_committed: Xen sets this flag to indicate that it is committed\r | |
178 | * to transferring ownership of a page frame. When a guest sees this flag\r | |
179 | * it must /not/ modify the grant entry until GTF_transfer_completed is\r | |
180 | * set by Xen.\r | |
181 | * GTF_transfer_completed: It is safe for the guest to spin-wait on this flag\r | |
182 | * after reading GTF_transfer_committed. Xen will always write the frame\r | |
183 | * address, followed by ORing this flag, in a timely manner.\r | |
184 | */\r | |
185 | #define _GTF_transfer_committed (2)\r | |
186 | #define GTF_transfer_committed (1U<<_GTF_transfer_committed)\r | |
187 | #define _GTF_transfer_completed (3)\r | |
188 | #define GTF_transfer_completed (1U<<_GTF_transfer_completed)\r | |
189 | \r | |
190 | /*\r | |
191 | * Version 2 grant table entries. These fulfil the same role as\r | |
192 | * version 1 entries, but can represent more complicated operations.\r | |
193 | * Any given domain will have either a version 1 or a version 2 table,\r | |
194 | * and every entry in the table will be the same version.\r | |
195 | *\r | |
196 | * The interface by which domains use grant references does not depend\r | |
197 | * on the grant table version in use by the other domain.\r | |
198 | */\r | |
199 | #if __XEN_INTERFACE_VERSION__ >= 0x0003020a\r | |
200 | /*\r | |
201 | * Version 1 and version 2 grant entries share a common prefix. The\r | |
202 | * fields of the prefix are documented as part of struct\r | |
203 | * grant_entry_v1.\r | |
204 | */\r | |
205 | struct grant_entry_header {\r | |
206 | UINT16 flags;\r | |
207 | domid_t domid;\r | |
208 | };\r | |
209 | typedef struct grant_entry_header grant_entry_header_t;\r | |
210 | \r | |
211 | /*\r | |
212 | * Version 2 of the grant entry structure.\r | |
213 | */\r | |
214 | union grant_entry_v2 {\r | |
215 | grant_entry_header_t hdr;\r | |
216 | \r | |
217 | /*\r | |
218 | * This member is used for V1-style full page grants, where either:\r | |
219 | *\r | |
220 | * -- hdr.type is GTF_accept_transfer, or\r | |
221 | * -- hdr.type is GTF_permit_access and GTF_sub_page is not set.\r | |
222 | *\r | |
223 | * In that case, the frame field has the same semantics as the\r | |
224 | * field of the same name in the V1 entry structure.\r | |
225 | */\r | |
226 | struct {\r | |
227 | grant_entry_header_t hdr;\r | |
228 | UINT32 pad0;\r | |
229 | UINT64 frame;\r | |
230 | } full_page;\r | |
231 | \r | |
232 | /*\r | |
233 | * If the grant type is GTF_grant_access and GTF_sub_page is set,\r | |
234 | * @domid is allowed to access bytes [@page_off,@page_off+@length)\r | |
235 | * in frame @frame.\r | |
236 | */\r | |
237 | struct {\r | |
238 | grant_entry_header_t hdr;\r | |
239 | UINT16 page_off;\r | |
240 | UINT16 length;\r | |
241 | UINT64 frame;\r | |
242 | } sub_page;\r | |
243 | \r | |
244 | /*\r | |
245 | * If the grant is GTF_transitive, @domid is allowed to use the\r | |
246 | * grant @gref in domain @trans_domid, as if it was the local\r | |
247 | * domain. Obviously, the transitive access must be compatible\r | |
248 | * with the original grant.\r | |
249 | *\r | |
250 | * The current version of Xen does not allow transitive grants\r | |
251 | * to be mapped.\r | |
252 | */\r | |
253 | struct {\r | |
254 | grant_entry_header_t hdr;\r | |
255 | domid_t trans_domid;\r | |
256 | UINT16 pad0;\r | |
257 | grant_ref_t gref;\r | |
258 | } transitive;\r | |
259 | \r | |
260 | UINT32 __spacer[4]; /* Pad to a power of two */\r | |
261 | };\r | |
262 | typedef union grant_entry_v2 grant_entry_v2_t;\r | |
263 | \r | |
264 | typedef UINT16 grant_status_t;\r | |
265 | \r | |
266 | #endif /* __XEN_INTERFACE_VERSION__ */\r | |
267 | \r | |
268 | /***********************************\r | |
269 | * GRANT TABLE QUERIES AND USES\r | |
270 | */\r | |
271 | \r | |
272 | /* ` enum neg_errnoval\r | |
273 | * ` HYPERVISOR_grant_table_op(enum grant_table_op cmd,\r | |
274 | * ` VOID *args,\r | |
275 | * ` UINT32 count)\r | |
276 | * `\r | |
277 | *\r | |
278 | * @args points to an array of a per-command data structure. The array\r | |
279 | * has @count members\r | |
280 | */\r | |
281 | \r | |
282 | /* ` enum grant_table_op { // GNTTABOP_* => struct gnttab_* */\r | |
283 | #define GNTTABOP_map_grant_ref 0\r | |
284 | #define GNTTABOP_unmap_grant_ref 1\r | |
285 | /* ` } */\r | |
286 | \r | |
287 | /*\r | |
288 | * Handle to track a mapping created via a grant reference.\r | |
289 | */\r | |
290 | typedef UINT32 grant_handle_t;\r | |
291 | \r | |
292 | /*\r | |
293 | * GNTTABOP_map_grant_ref: Map the grant entry (<dom>,<ref>) for access\r | |
294 | * by devices and/or host CPUs. If successful, <handle> is a tracking number\r | |
295 | * that must be presented later to destroy the mapping(s). On error, <handle>\r | |
296 | * is a negative status code.\r | |
297 | * NOTES:\r | |
298 | * 1. If GNTMAP_device_map is specified then <dev_bus_addr> is the address\r | |
299 | * via which I/O devices may access the granted frame.\r | |
300 | * 2. If GNTMAP_host_map is specified then a mapping will be added at\r | |
301 | * either a host virtual address in the current address space, or at\r | |
302 | * a PTE at the specified machine address. The type of mapping to\r | |
303 | * perform is selected through the GNTMAP_contains_pte flag, and the\r | |
304 | * address is specified in <host_addr>.\r | |
305 | * 3. Mappings should only be destroyed via GNTTABOP_unmap_grant_ref. If a\r | |
306 | * host mapping is destroyed by other means then it is *NOT* guaranteed\r | |
307 | * to be accounted to the correct grant reference!\r | |
308 | */\r | |
309 | struct gnttab_map_grant_ref {\r | |
310 | /* IN parameters. */\r | |
311 | UINT64 host_addr;\r | |
312 | UINT32 flags; /* GNTMAP_* */\r | |
313 | grant_ref_t ref;\r | |
314 | domid_t dom;\r | |
315 | /* OUT parameters. */\r | |
316 | INT16 status; /* => enum grant_status */\r | |
317 | grant_handle_t handle;\r | |
318 | UINT64 dev_bus_addr;\r | |
319 | };\r | |
320 | typedef struct gnttab_map_grant_ref gnttab_map_grant_ref_t;\r | |
321 | DEFINE_XEN_GUEST_HANDLE(gnttab_map_grant_ref_t);\r | |
322 | \r | |
323 | /*\r | |
324 | * GNTTABOP_unmap_grant_ref: Destroy one or more grant-reference mappings\r | |
325 | * tracked by <handle>. If <host_addr> or <dev_bus_addr> is zero, that\r | |
326 | * field is ignored. If non-zero, they must refer to a device/host mapping\r | |
327 | * that is tracked by <handle>\r | |
328 | * NOTES:\r | |
329 | * 1. The call may fail in an undefined manner if either mapping is not\r | |
330 | * tracked by <handle>.\r | |
331 | * 3. After executing a batch of unmaps, it is guaranteed that no stale\r | |
332 | * mappings will remain in the device or host TLBs.\r | |
333 | */\r | |
334 | struct gnttab_unmap_grant_ref {\r | |
335 | /* IN parameters. */\r | |
336 | UINT64 host_addr;\r | |
337 | UINT64 dev_bus_addr;\r | |
338 | grant_handle_t handle;\r | |
339 | /* OUT parameters. */\r | |
340 | INT16 status; /* => enum grant_status */\r | |
341 | };\r | |
342 | typedef struct gnttab_unmap_grant_ref gnttab_unmap_grant_ref_t;\r | |
343 | DEFINE_XEN_GUEST_HANDLE(gnttab_unmap_grant_ref_t);\r | |
344 | \r | |
345 | /*\r | |
346 | * Bitfield values for gnttab_map_grant_ref.flags.\r | |
347 | */\r | |
348 | /* Map the grant entry for access by I/O devices. */\r | |
349 | #define _GNTMAP_device_map (0)\r | |
350 | #define GNTMAP_device_map (1<<_GNTMAP_device_map)\r | |
351 | /* Map the grant entry for access by host CPUs. */\r | |
352 | #define _GNTMAP_host_map (1)\r | |
353 | #define GNTMAP_host_map (1<<_GNTMAP_host_map)\r | |
354 | /* Accesses to the granted frame will be restricted to read-only access. */\r | |
355 | #define _GNTMAP_readonly (2)\r | |
356 | #define GNTMAP_readonly (1<<_GNTMAP_readonly)\r | |
357 | /*\r | |
358 | * GNTMAP_host_map subflag:\r | |
359 | * 0 => The host mapping is usable only by the guest OS.\r | |
360 | * 1 => The host mapping is usable by guest OS + current application.\r | |
361 | */\r | |
362 | #define _GNTMAP_application_map (3)\r | |
363 | #define GNTMAP_application_map (1<<_GNTMAP_application_map)\r | |
364 | \r | |
365 | /*\r | |
366 | * GNTMAP_contains_pte subflag:\r | |
367 | * 0 => This map request contains a host virtual address.\r | |
368 | * 1 => This map request contains the machine addess of the PTE to update.\r | |
369 | */\r | |
370 | #define _GNTMAP_contains_pte (4)\r | |
371 | #define GNTMAP_contains_pte (1<<_GNTMAP_contains_pte)\r | |
372 | \r | |
373 | #define _GNTMAP_can_fail (5)\r | |
374 | #define GNTMAP_can_fail (1<<_GNTMAP_can_fail)\r | |
375 | \r | |
376 | /*\r | |
377 | * Bits to be placed in guest kernel available PTE bits (architecture\r | |
378 | * dependent; only supported when XENFEAT_gnttab_map_avail_bits is set).\r | |
379 | */\r | |
380 | #define _GNTMAP_guest_avail0 (16)\r | |
381 | #define GNTMAP_guest_avail_mask ((UINT32)~0 << _GNTMAP_guest_avail0)\r | |
382 | \r | |
383 | /*\r | |
384 | * Values for error status returns. All errors are -ve.\r | |
385 | */\r | |
386 | /* ` enum grant_status { */\r | |
387 | #define GNTST_okay (0) /* Normal return. */\r | |
388 | #define GNTST_general_error (-1) /* General undefined error. */\r | |
389 | #define GNTST_bad_domain (-2) /* Unrecognsed domain id. */\r | |
390 | #define GNTST_bad_gntref (-3) /* Unrecognised or inappropriate gntref. */\r | |
391 | #define GNTST_bad_handle (-4) /* Unrecognised or inappropriate handle. */\r | |
392 | #define GNTST_bad_virt_addr (-5) /* Inappropriate virtual address to map. */\r | |
393 | #define GNTST_bad_dev_addr (-6) /* Inappropriate device address to unmap.*/\r | |
394 | #define GNTST_no_device_space (-7) /* Out of space in I/O MMU. */\r | |
395 | #define GNTST_permission_denied (-8) /* Not enough privilege for operation. */\r | |
396 | #define GNTST_bad_page (-9) /* Specified page was invalid for op. */\r | |
397 | #define GNTST_bad_copy_arg (-10) /* copy arguments cross page boundary. */\r | |
398 | #define GNTST_address_too_big (-11) /* transfer page address too large. */\r | |
399 | #define GNTST_eagain (-12) /* Operation not done; try again. */\r | |
400 | /* ` } */\r | |
401 | \r | |
402 | #define GNTTABOP_error_msgs { \\r | |
403 | "okay", \\r | |
404 | "undefined error", \\r | |
405 | "unrecognised domain id", \\r | |
406 | "invalid grant reference", \\r | |
407 | "invalid mapping handle", \\r | |
408 | "invalid virtual address", \\r | |
409 | "invalid device address", \\r | |
410 | "no spare translation slot in the I/O MMU", \\r | |
411 | "permission denied", \\r | |
412 | "bad page", \\r | |
413 | "copy arguments cross page boundary", \\r | |
414 | "page address size too large", \\r | |
415 | "operation not done; try again" \\r | |
416 | }\r | |
417 | \r | |
418 | #endif /* __XEN_PUBLIC_GRANT_TABLE_H__ */\r | |
419 | \r | |
420 | /*\r | |
421 | * Local variables:\r | |
422 | * mode: C\r | |
423 | * c-file-style: "BSD"\r | |
424 | * c-basic-offset: 4\r | |
425 | * tab-width: 4\r | |
426 | * indent-tabs-mode: nil\r | |
427 | * End:\r | |
428 | */\r |