grant_table.h 11 KB

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