diff options
Diffstat (limited to 'include/xen/interface/grant_table.h')
-rw-r--r-- | include/xen/interface/grant_table.h | 301 |
1 files changed, 301 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..e9e06695ed52 --- /dev/null +++ b/include/xen/interface/grant_table.h | |||
@@ -0,0 +1,301 @@ | |||
1 | /****************************************************************************** | ||
2 | * grant_table.h | ||
3 | * | ||
4 | * Interface for granting foreign access to page frames, and receiving | ||
5 | * page-ownership transfers. | ||
6 | * | ||
7 | * Copyright (c) 2004, K A Fraser | ||
8 | */ | ||
9 | |||
10 | #ifndef __XEN_PUBLIC_GRANT_TABLE_H__ | ||
11 | #define __XEN_PUBLIC_GRANT_TABLE_H__ | ||
12 | |||
13 | |||
14 | /*********************************** | ||
15 | * GRANT TABLE REPRESENTATION | ||
16 | */ | ||
17 | |||
18 | /* Some rough guidelines on accessing and updating grant-table entries | ||
19 | * in a concurrency-safe manner. For more information, Linux contains a | ||
20 | * reference implementation for guest OSes (arch/i386/mach-xen/grant_table.c). | ||
21 | * | ||
22 | * NB. WMB is a no-op on current-generation x86 processors. However, a | ||
23 | * compiler barrier will still be required. | ||
24 | * | ||
25 | * Introducing a valid entry into the grant table: | ||
26 | * 1. Write ent->domid. | ||
27 | * 2. Write ent->frame: | ||
28 | * GTF_permit_access: Frame to which access is permitted. | ||
29 | * GTF_accept_transfer: Pseudo-phys frame slot being filled by new | ||
30 | * frame, or zero if none. | ||
31 | * 3. Write memory barrier (WMB). | ||
32 | * 4. Write ent->flags, inc. valid type. | ||
33 | * | ||
34 | * Invalidating an unused GTF_permit_access entry: | ||
35 | * 1. flags = ent->flags. | ||
36 | * 2. Observe that !(flags & (GTF_reading|GTF_writing)). | ||
37 | * 3. Check result of SMP-safe CMPXCHG(&ent->flags, flags, 0). | ||
38 | * NB. No need for WMB as reuse of entry is control-dependent on success of | ||
39 | * step 3, and all architectures guarantee ordering of ctrl-dep writes. | ||
40 | * | ||
41 | * Invalidating an in-use GTF_permit_access entry: | ||
42 | * This cannot be done directly. Request assistance from the domain controller | ||
43 | * which can set a timeout on the use of a grant entry and take necessary | ||
44 | * action. (NB. This is not yet implemented!). | ||
45 | * | ||
46 | * Invalidating an unused GTF_accept_transfer entry: | ||
47 | * 1. flags = ent->flags. | ||
48 | * 2. Observe that !(flags & GTF_transfer_committed). [*] | ||
49 | * 3. Check result of SMP-safe CMPXCHG(&ent->flags, flags, 0). | ||
50 | * NB. No need for WMB as reuse of entry is control-dependent on success of | ||
51 | * step 3, and all architectures guarantee ordering of ctrl-dep writes. | ||
52 | * [*] If GTF_transfer_committed is set then the grant entry is 'committed'. | ||
53 | * The guest must /not/ modify the grant entry until the address of the | ||
54 | * transferred frame is written. It is safe for the guest to spin waiting | ||
55 | * for this to occur (detect by observing GTF_transfer_completed in | ||
56 | * ent->flags). | ||
57 | * | ||
58 | * Invalidating a committed GTF_accept_transfer entry: | ||
59 | * 1. Wait for (ent->flags & GTF_transfer_completed). | ||
60 | * | ||
61 | * Changing a GTF_permit_access from writable to read-only: | ||
62 | * Use SMP-safe CMPXCHG to set GTF_readonly, while checking !GTF_writing. | ||
63 | * | ||
64 | * Changing a GTF_permit_access from read-only to writable: | ||
65 | * Use SMP-safe bit-setting instruction. | ||
66 | */ | ||
67 | |||
68 | /* | ||
69 | * A grant table comprises a packed array of grant entries in one or more | ||
70 | * page frames shared between Xen and a guest. | ||
71 | * [XEN]: This field is written by Xen and read by the sharing guest. | ||
72 | * [GST]: This field is written by the guest and read by Xen. | ||
73 | */ | ||
74 | struct grant_entry { | ||
75 | /* GTF_xxx: various type and flag information. [XEN,GST] */ | ||
76 | uint16_t flags; | ||
77 | /* The domain being granted foreign privileges. [GST] */ | ||
78 | domid_t domid; | ||
79 | /* | ||
80 | * GTF_permit_access: Frame that @domid is allowed to map and access. [GST] | ||
81 | * GTF_accept_transfer: Frame whose ownership transferred by @domid. [XEN] | ||
82 | */ | ||
83 | uint32_t frame; | ||
84 | }; | ||
85 | |||
86 | /* | ||
87 | * Type of grant entry. | ||
88 | * GTF_invalid: This grant entry grants no privileges. | ||
89 | * GTF_permit_access: Allow @domid to map/access @frame. | ||
90 | * GTF_accept_transfer: Allow @domid to transfer ownership of one page frame | ||
91 | * to this guest. Xen writes the page number to @frame. | ||
92 | */ | ||
93 | #define GTF_invalid (0U<<0) | ||
94 | #define GTF_permit_access (1U<<0) | ||
95 | #define GTF_accept_transfer (2U<<0) | ||
96 | #define GTF_type_mask (3U<<0) | ||
97 | |||
98 | /* | ||
99 | * Subflags for GTF_permit_access. | ||
100 | * GTF_readonly: Restrict @domid to read-only mappings and accesses. [GST] | ||
101 | * GTF_reading: Grant entry is currently mapped for reading by @domid. [XEN] | ||
102 | * GTF_writing: Grant entry is currently mapped for writing by @domid. [XEN] | ||
103 | */ | ||
104 | #define _GTF_readonly (2) | ||
105 | #define GTF_readonly (1U<<_GTF_readonly) | ||
106 | #define _GTF_reading (3) | ||
107 | #define GTF_reading (1U<<_GTF_reading) | ||
108 | #define _GTF_writing (4) | ||
109 | #define GTF_writing (1U<<_GTF_writing) | ||
110 | |||
111 | /* | ||
112 | * Subflags for GTF_accept_transfer: | ||
113 | * GTF_transfer_committed: Xen sets this flag to indicate that it is committed | ||
114 | * to transferring ownership of a page frame. When a guest sees this flag | ||
115 | * it must /not/ modify the grant entry until GTF_transfer_completed is | ||
116 | * set by Xen. | ||
117 | * GTF_transfer_completed: It is safe for the guest to spin-wait on this flag | ||
118 | * after reading GTF_transfer_committed. Xen will always write the frame | ||
119 | * address, followed by ORing this flag, in a timely manner. | ||
120 | */ | ||
121 | #define _GTF_transfer_committed (2) | ||
122 | #define GTF_transfer_committed (1U<<_GTF_transfer_committed) | ||
123 | #define _GTF_transfer_completed (3) | ||
124 | #define GTF_transfer_completed (1U<<_GTF_transfer_completed) | ||
125 | |||
126 | |||
127 | /*********************************** | ||
128 | * GRANT TABLE QUERIES AND USES | ||
129 | */ | ||
130 | |||
131 | /* | ||
132 | * Reference to a grant entry in a specified domain's grant table. | ||
133 | */ | ||
134 | typedef uint32_t grant_ref_t; | ||
135 | |||
136 | /* | ||
137 | * Handle to track a mapping created via a grant reference. | ||
138 | */ | ||
139 | typedef uint32_t grant_handle_t; | ||
140 | |||
141 | /* | ||
142 | * GNTTABOP_map_grant_ref: Map the grant entry (<dom>,<ref>) for access | ||
143 | * by devices and/or host CPUs. If successful, <handle> is a tracking number | ||
144 | * that must be presented later to destroy the mapping(s). On error, <handle> | ||
145 | * is a negative status code. | ||
146 | * NOTES: | ||
147 | * 1. If GNTPIN_map_for_dev is specified then <dev_bus_addr> is the address | ||
148 | * via which I/O devices may access the granted frame. | ||
149 | * 2. If GNTPIN_map_for_host is specified then a mapping will be added at | ||
150 | * either a host virtual address in the current address space, or at | ||
151 | * a PTE at the specified machine address. The type of mapping to | ||
152 | * perform is selected through the GNTMAP_contains_pte flag, and the | ||
153 | * address is specified in <host_addr>. | ||
154 | * 3. Mappings should only be destroyed via GNTTABOP_unmap_grant_ref. If a | ||
155 | * host mapping is destroyed by other means then it is *NOT* guaranteed | ||
156 | * to be accounted to the correct grant reference! | ||
157 | */ | ||
158 | #define GNTTABOP_map_grant_ref 0 | ||
159 | struct gnttab_map_grant_ref { | ||
160 | /* IN parameters. */ | ||
161 | uint64_t host_addr; | ||
162 | uint32_t flags; /* GNTMAP_* */ | ||
163 | grant_ref_t ref; | ||
164 | domid_t dom; | ||
165 | /* OUT parameters. */ | ||
166 | int16_t status; /* GNTST_* */ | ||
167 | grant_handle_t handle; | ||
168 | uint64_t dev_bus_addr; | ||
169 | }; | ||
170 | DEFINE_GUEST_HANDLE_STRUCT(gnttab_map_grant_ref); | ||
171 | |||
172 | /* | ||
173 | * GNTTABOP_unmap_grant_ref: Destroy one or more grant-reference mappings | ||
174 | * tracked by <handle>. If <host_addr> or <dev_bus_addr> is zero, that | ||
175 | * field is ignored. If non-zero, they must refer to a device/host mapping | ||
176 | * that is tracked by <handle> | ||
177 | * NOTES: | ||
178 | * 1. The call may fail in an undefined manner if either mapping is not | ||
179 | * tracked by <handle>. | ||
180 | * 3. After executing a batch of unmaps, it is guaranteed that no stale | ||
181 | * mappings will remain in the device or host TLBs. | ||
182 | */ | ||
183 | #define GNTTABOP_unmap_grant_ref 1 | ||
184 | struct gnttab_unmap_grant_ref { | ||
185 | /* IN parameters. */ | ||
186 | uint64_t host_addr; | ||
187 | uint64_t dev_bus_addr; | ||
188 | grant_handle_t handle; | ||
189 | /* OUT parameters. */ | ||
190 | int16_t status; /* GNTST_* */ | ||
191 | }; | ||
192 | DEFINE_GUEST_HANDLE_STRUCT(gnttab_unmap_grant_ref); | ||
193 | |||
194 | /* | ||
195 | * GNTTABOP_setup_table: Set up a grant table for <dom> comprising at least | ||
196 | * <nr_frames> pages. The frame addresses are written to the <frame_list>. | ||
197 | * Only <nr_frames> addresses are written, even if the table is larger. | ||
198 | * NOTES: | ||
199 | * 1. <dom> may be specified as DOMID_SELF. | ||
200 | * 2. Only a sufficiently-privileged domain may specify <dom> != DOMID_SELF. | ||
201 | * 3. Xen may not support more than a single grant-table page per domain. | ||
202 | */ | ||
203 | #define GNTTABOP_setup_table 2 | ||
204 | struct gnttab_setup_table { | ||
205 | /* IN parameters. */ | ||
206 | domid_t dom; | ||
207 | uint32_t nr_frames; | ||
208 | /* OUT parameters. */ | ||
209 | int16_t status; /* GNTST_* */ | ||
210 | GUEST_HANDLE(ulong) frame_list; | ||
211 | }; | ||
212 | DEFINE_GUEST_HANDLE_STRUCT(gnttab_setup_table); | ||
213 | |||
214 | /* | ||
215 | * GNTTABOP_dump_table: Dump the contents of the grant table to the | ||
216 | * xen console. Debugging use only. | ||
217 | */ | ||
218 | #define GNTTABOP_dump_table 3 | ||
219 | struct gnttab_dump_table { | ||
220 | /* IN parameters. */ | ||
221 | domid_t dom; | ||
222 | /* OUT parameters. */ | ||
223 | int16_t status; /* GNTST_* */ | ||
224 | }; | ||
225 | DEFINE_GUEST_HANDLE_STRUCT(gnttab_dump_table); | ||
226 | |||
227 | /* | ||
228 | * GNTTABOP_transfer_grant_ref: Transfer <frame> to a foreign domain. The | ||
229 | * foreign domain has previously registered its interest in the transfer via | ||
230 | * <domid, ref>. | ||
231 | * | ||
232 | * Note that, even if the transfer fails, the specified page no longer belongs | ||
233 | * to the calling domain *unless* the error is GNTST_bad_page. | ||
234 | */ | ||
235 | #define GNTTABOP_transfer 4 | ||
236 | struct gnttab_transfer { | ||
237 | /* IN parameters. */ | ||
238 | unsigned long mfn; | ||
239 | domid_t domid; | ||
240 | grant_ref_t ref; | ||
241 | /* OUT parameters. */ | ||
242 | int16_t status; | ||
243 | }; | ||
244 | DEFINE_GUEST_HANDLE_STRUCT(gnttab_transfer); | ||
245 | |||
246 | /* | ||
247 | * Bitfield values for update_pin_status.flags. | ||
248 | */ | ||
249 | /* Map the grant entry for access by I/O devices. */ | ||
250 | #define _GNTMAP_device_map (0) | ||
251 | #define GNTMAP_device_map (1<<_GNTMAP_device_map) | ||
252 | /* Map the grant entry for access by host CPUs. */ | ||
253 | #define _GNTMAP_host_map (1) | ||
254 | #define GNTMAP_host_map (1<<_GNTMAP_host_map) | ||
255 | /* Accesses to the granted frame will be restricted to read-only access. */ | ||
256 | #define _GNTMAP_readonly (2) | ||
257 | #define GNTMAP_readonly (1<<_GNTMAP_readonly) | ||
258 | /* | ||
259 | * GNTMAP_host_map subflag: | ||
260 | * 0 => The host mapping is usable only by the guest OS. | ||
261 | * 1 => The host mapping is usable by guest OS + current application. | ||
262 | */ | ||
263 | #define _GNTMAP_application_map (3) | ||
264 | #define GNTMAP_application_map (1<<_GNTMAP_application_map) | ||
265 | |||
266 | /* | ||
267 | * GNTMAP_contains_pte subflag: | ||
268 | * 0 => This map request contains a host virtual address. | ||
269 | * 1 => This map request contains the machine addess of the PTE to update. | ||
270 | */ | ||
271 | #define _GNTMAP_contains_pte (4) | ||
272 | #define GNTMAP_contains_pte (1<<_GNTMAP_contains_pte) | ||
273 | |||
274 | /* | ||
275 | * Values for error status returns. All errors are -ve. | ||
276 | */ | ||
277 | #define GNTST_okay (0) /* Normal return. */ | ||
278 | #define GNTST_general_error (-1) /* General undefined error. */ | ||
279 | #define GNTST_bad_domain (-2) /* Unrecognsed domain id. */ | ||
280 | #define GNTST_bad_gntref (-3) /* Unrecognised or inappropriate gntref. */ | ||
281 | #define GNTST_bad_handle (-4) /* Unrecognised or inappropriate handle. */ | ||
282 | #define GNTST_bad_virt_addr (-5) /* Inappropriate virtual address to map. */ | ||
283 | #define GNTST_bad_dev_addr (-6) /* Inappropriate device address to unmap.*/ | ||
284 | #define GNTST_no_device_space (-7) /* Out of space in I/O MMU. */ | ||
285 | #define GNTST_permission_denied (-8) /* Not enough privilege for operation. */ | ||
286 | #define GNTST_bad_page (-9) /* Specified page was invalid for op. */ | ||
287 | |||
288 | #define GNTTABOP_error_msgs { \ | ||
289 | "okay", \ | ||
290 | "undefined error", \ | ||
291 | "unrecognised domain id", \ | ||
292 | "invalid grant reference", \ | ||
293 | "invalid mapping handle", \ | ||
294 | "invalid virtual address", \ | ||
295 | "invalid device address", \ | ||
296 | "no spare translation slot in the I/O MMU", \ | ||
297 | "permission denied", \ | ||
298 | "bad page" \ | ||
299 | } | ||
300 | |||
301 | #endif /* __XEN_PUBLIC_GRANT_TABLE_H__ */ | ||