|
|
1.1 ! root 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: typedef struct grant_entry grant_entry_t; ! 104: ! 105: /* ! 106: * Type of grant entry. ! 107: * GTF_invalid: This grant entry grants no privileges. ! 108: * GTF_permit_access: Allow @domid to map/access @frame. ! 109: * GTF_accept_transfer: Allow @domid to transfer ownership of one page frame ! 110: * to this guest. Xen writes the page number to @frame. ! 111: */ ! 112: #define GTF_invalid (0U<<0) ! 113: #define GTF_permit_access (1U<<0) ! 114: #define GTF_accept_transfer (2U<<0) ! 115: #define GTF_type_mask (3U<<0) ! 116: ! 117: /* ! 118: * Subflags for GTF_permit_access. ! 119: * GTF_readonly: Restrict @domid to read-only mappings and accesses. [GST] ! 120: * GTF_reading: Grant entry is currently mapped for reading by @domid. [XEN] ! 121: * GTF_writing: Grant entry is currently mapped for writing by @domid. [XEN] ! 122: * GTF_PAT, GTF_PWT, GTF_PCD: (x86) cache attribute flags for the grant [GST] ! 123: */ ! 124: #define _GTF_readonly (2) ! 125: #define GTF_readonly (1U<<_GTF_readonly) ! 126: #define _GTF_reading (3) ! 127: #define GTF_reading (1U<<_GTF_reading) ! 128: #define _GTF_writing (4) ! 129: #define GTF_writing (1U<<_GTF_writing) ! 130: #define _GTF_PWT (5) ! 131: #define GTF_PWT (1U<<_GTF_PWT) ! 132: #define _GTF_PCD (6) ! 133: #define GTF_PCD (1U<<_GTF_PCD) ! 134: #define _GTF_PAT (7) ! 135: #define GTF_PAT (1U<<_GTF_PAT) ! 136: ! 137: /* ! 138: * Subflags for GTF_accept_transfer: ! 139: * GTF_transfer_committed: Xen sets this flag to indicate that it is committed ! 140: * to transferring ownership of a page frame. When a guest sees this flag ! 141: * it must /not/ modify the grant entry until GTF_transfer_completed is ! 142: * set by Xen. ! 143: * GTF_transfer_completed: It is safe for the guest to spin-wait on this flag ! 144: * after reading GTF_transfer_committed. Xen will always write the frame ! 145: * address, followed by ORing this flag, in a timely manner. ! 146: */ ! 147: #define _GTF_transfer_committed (2) ! 148: #define GTF_transfer_committed (1U<<_GTF_transfer_committed) ! 149: #define _GTF_transfer_completed (3) ! 150: #define GTF_transfer_completed (1U<<_GTF_transfer_completed) ! 151: ! 152: ! 153: /*********************************** ! 154: * GRANT TABLE QUERIES AND USES ! 155: */ ! 156: ! 157: /* ! 158: * Reference to a grant entry in a specified domain's grant table. ! 159: */ ! 160: typedef uint32_t grant_ref_t; ! 161: ! 162: /* ! 163: * Handle to track a mapping created via a grant reference. ! 164: */ ! 165: typedef uint32_t grant_handle_t; ! 166: ! 167: /* ! 168: * GNTTABOP_map_grant_ref: Map the grant entry (<dom>,<ref>) for access ! 169: * by devices and/or host CPUs. If successful, <handle> is a tracking number ! 170: * that must be presented later to destroy the mapping(s). On error, <handle> ! 171: * is a negative status code. ! 172: * NOTES: ! 173: * 1. If GNTMAP_device_map is specified then <dev_bus_addr> is the address ! 174: * via which I/O devices may access the granted frame. ! 175: * 2. If GNTMAP_host_map is specified then a mapping will be added at ! 176: * either a host virtual address in the current address space, or at ! 177: * a PTE at the specified machine address. The type of mapping to ! 178: * perform is selected through the GNTMAP_contains_pte flag, and the ! 179: * address is specified in <host_addr>. ! 180: * 3. Mappings should only be destroyed via GNTTABOP_unmap_grant_ref. If a ! 181: * host mapping is destroyed by other means then it is *NOT* guaranteed ! 182: * to be accounted to the correct grant reference! ! 183: */ ! 184: #define GNTTABOP_map_grant_ref 0 ! 185: struct gnttab_map_grant_ref { ! 186: /* IN parameters. */ ! 187: uint64_t host_addr; ! 188: uint32_t flags; /* GNTMAP_* */ ! 189: grant_ref_t ref; ! 190: domid_t dom; ! 191: /* OUT parameters. */ ! 192: int16_t status; /* GNTST_* */ ! 193: grant_handle_t handle; ! 194: uint64_t dev_bus_addr; ! 195: }; ! 196: typedef struct gnttab_map_grant_ref gnttab_map_grant_ref_t; ! 197: DEFINE_XEN_GUEST_HANDLE(gnttab_map_grant_ref_t); ! 198: ! 199: /* ! 200: * GNTTABOP_unmap_grant_ref: Destroy one or more grant-reference mappings ! 201: * tracked by <handle>. If <host_addr> or <dev_bus_addr> is zero, that ! 202: * field is ignored. If non-zero, they must refer to a device/host mapping ! 203: * that is tracked by <handle> ! 204: * NOTES: ! 205: * 1. The call may fail in an undefined manner if either mapping is not ! 206: * tracked by <handle>. ! 207: * 3. After executing a batch of unmaps, it is guaranteed that no stale ! 208: * mappings will remain in the device or host TLBs. ! 209: */ ! 210: #define GNTTABOP_unmap_grant_ref 1 ! 211: struct gnttab_unmap_grant_ref { ! 212: /* IN parameters. */ ! 213: uint64_t host_addr; ! 214: uint64_t dev_bus_addr; ! 215: grant_handle_t handle; ! 216: /* OUT parameters. */ ! 217: int16_t status; /* GNTST_* */ ! 218: }; ! 219: typedef struct gnttab_unmap_grant_ref gnttab_unmap_grant_ref_t; ! 220: DEFINE_XEN_GUEST_HANDLE(gnttab_unmap_grant_ref_t); ! 221: ! 222: /* ! 223: * GNTTABOP_setup_table: Set up a grant table for <dom> comprising at least ! 224: * <nr_frames> pages. The frame addresses are written to the <frame_list>. ! 225: * Only <nr_frames> addresses are written, even if the table is larger. ! 226: * NOTES: ! 227: * 1. <dom> may be specified as DOMID_SELF. ! 228: * 2. Only a sufficiently-privileged domain may specify <dom> != DOMID_SELF. ! 229: * 3. Xen may not support more than a single grant-table page per domain. ! 230: */ ! 231: #define GNTTABOP_setup_table 2 ! 232: struct gnttab_setup_table { ! 233: /* IN parameters. */ ! 234: domid_t dom; ! 235: uint32_t nr_frames; ! 236: /* OUT parameters. */ ! 237: int16_t status; /* GNTST_* */ ! 238: XEN_GUEST_HANDLE(ulong) frame_list; ! 239: }; ! 240: typedef struct gnttab_setup_table gnttab_setup_table_t; ! 241: DEFINE_XEN_GUEST_HANDLE(gnttab_setup_table_t); ! 242: ! 243: /* ! 244: * GNTTABOP_dump_table: Dump the contents of the grant table to the ! 245: * xen console. Debugging use only. ! 246: */ ! 247: #define GNTTABOP_dump_table 3 ! 248: struct gnttab_dump_table { ! 249: /* IN parameters. */ ! 250: domid_t dom; ! 251: /* OUT parameters. */ ! 252: int16_t status; /* GNTST_* */ ! 253: }; ! 254: typedef struct gnttab_dump_table gnttab_dump_table_t; ! 255: DEFINE_XEN_GUEST_HANDLE(gnttab_dump_table_t); ! 256: ! 257: /* ! 258: * GNTTABOP_transfer_grant_ref: Transfer <frame> to a foreign domain. The ! 259: * foreign domain has previously registered its interest in the transfer via ! 260: * <domid, ref>. ! 261: * ! 262: * Note that, even if the transfer fails, the specified page no longer belongs ! 263: * to the calling domain *unless* the error is GNTST_bad_page. ! 264: */ ! 265: #define GNTTABOP_transfer 4 ! 266: struct gnttab_transfer { ! 267: /* IN parameters. */ ! 268: xen_pfn_t mfn; ! 269: domid_t domid; ! 270: grant_ref_t ref; ! 271: /* OUT parameters. */ ! 272: int16_t status; ! 273: }; ! 274: typedef struct gnttab_transfer gnttab_transfer_t; ! 275: DEFINE_XEN_GUEST_HANDLE(gnttab_transfer_t); ! 276: ! 277: ! 278: /* ! 279: * GNTTABOP_copy: Hypervisor based copy ! 280: * source and destinations can be eithers MFNs or, for foreign domains, ! 281: * grant references. the foreign domain has to grant read/write access ! 282: * in its grant table. ! 283: * ! 284: * The flags specify what type source and destinations are (either MFN ! 285: * or grant reference). ! 286: * ! 287: * Note that this can also be used to copy data between two domains ! 288: * via a third party if the source and destination domains had previously ! 289: * grant appropriate access to their pages to the third party. ! 290: * ! 291: * source_offset specifies an offset in the source frame, dest_offset ! 292: * the offset in the target frame and len specifies the number of ! 293: * bytes to be copied. ! 294: */ ! 295: ! 296: #define _GNTCOPY_source_gref (0) ! 297: #define GNTCOPY_source_gref (1<<_GNTCOPY_source_gref) ! 298: #define _GNTCOPY_dest_gref (1) ! 299: #define GNTCOPY_dest_gref (1<<_GNTCOPY_dest_gref) ! 300: ! 301: #define GNTTABOP_copy 5 ! 302: typedef struct gnttab_copy { ! 303: /* IN parameters. */ ! 304: struct { ! 305: union { ! 306: grant_ref_t ref; ! 307: xen_pfn_t gmfn; ! 308: } u; ! 309: domid_t domid; ! 310: uint16_t offset; ! 311: } source, dest; ! 312: uint16_t len; ! 313: uint16_t flags; /* GNTCOPY_* */ ! 314: /* OUT parameters. */ ! 315: int16_t status; ! 316: } gnttab_copy_t; ! 317: DEFINE_XEN_GUEST_HANDLE(gnttab_copy_t); ! 318: ! 319: /* ! 320: * GNTTABOP_query_size: Query the current and maximum sizes of the shared ! 321: * grant table. ! 322: * NOTES: ! 323: * 1. <dom> may be specified as DOMID_SELF. ! 324: * 2. Only a sufficiently-privileged domain may specify <dom> != DOMID_SELF. ! 325: */ ! 326: #define GNTTABOP_query_size 6 ! 327: struct gnttab_query_size { ! 328: /* IN parameters. */ ! 329: domid_t dom; ! 330: /* OUT parameters. */ ! 331: uint32_t nr_frames; ! 332: uint32_t max_nr_frames; ! 333: int16_t status; /* GNTST_* */ ! 334: }; ! 335: typedef struct gnttab_query_size gnttab_query_size_t; ! 336: DEFINE_XEN_GUEST_HANDLE(gnttab_query_size_t); ! 337: ! 338: /* ! 339: * GNTTABOP_unmap_and_replace: Destroy one or more grant-reference mappings ! 340: * tracked by <handle> but atomically replace the page table entry with one ! 341: * pointing to the machine address under <new_addr>. <new_addr> will be ! 342: * redirected to the null entry. ! 343: * NOTES: ! 344: * 1. The call may fail in an undefined manner if either mapping is not ! 345: * tracked by <handle>. ! 346: * 2. After executing a batch of unmaps, it is guaranteed that no stale ! 347: * mappings will remain in the device or host TLBs. ! 348: */ ! 349: #define GNTTABOP_unmap_and_replace 7 ! 350: struct gnttab_unmap_and_replace { ! 351: /* IN parameters. */ ! 352: uint64_t host_addr; ! 353: uint64_t new_addr; ! 354: grant_handle_t handle; ! 355: /* OUT parameters. */ ! 356: int16_t status; /* GNTST_* */ ! 357: }; ! 358: typedef struct gnttab_unmap_and_replace gnttab_unmap_and_replace_t; ! 359: DEFINE_XEN_GUEST_HANDLE(gnttab_unmap_and_replace_t); ! 360: ! 361: ! 362: /* ! 363: * Bitfield values for gnttab_map_grant_ref.flags. ! 364: */ ! 365: /* Map the grant entry for access by I/O devices. */ ! 366: #define _GNTMAP_device_map (0) ! 367: #define GNTMAP_device_map (1<<_GNTMAP_device_map) ! 368: /* Map the grant entry for access by host CPUs. */ ! 369: #define _GNTMAP_host_map (1) ! 370: #define GNTMAP_host_map (1<<_GNTMAP_host_map) ! 371: /* Accesses to the granted frame will be restricted to read-only access. */ ! 372: #define _GNTMAP_readonly (2) ! 373: #define GNTMAP_readonly (1<<_GNTMAP_readonly) ! 374: /* ! 375: * GNTMAP_host_map subflag: ! 376: * 0 => The host mapping is usable only by the guest OS. ! 377: * 1 => The host mapping is usable by guest OS + current application. ! 378: */ ! 379: #define _GNTMAP_application_map (3) ! 380: #define GNTMAP_application_map (1<<_GNTMAP_application_map) ! 381: ! 382: /* ! 383: * GNTMAP_contains_pte subflag: ! 384: * 0 => This map request contains a host virtual address. ! 385: * 1 => This map request contains the machine addess of the PTE to update. ! 386: */ ! 387: #define _GNTMAP_contains_pte (4) ! 388: #define GNTMAP_contains_pte (1<<_GNTMAP_contains_pte) ! 389: ! 390: /* ! 391: * Bits to be placed in guest kernel available PTE bits (architecture ! 392: * dependent; only supported when XENFEAT_gnttab_map_avail_bits is set). ! 393: */ ! 394: #define _GNTMAP_guest_avail0 (16) ! 395: #define GNTMAP_guest_avail_mask ((uint32_t)~0 << _GNTMAP_guest_avail0) ! 396: ! 397: /* ! 398: * Values for error status returns. All errors are -ve. ! 399: */ ! 400: #define GNTST_okay (0) /* Normal return. */ ! 401: #define GNTST_general_error (-1) /* General undefined error. */ ! 402: #define GNTST_bad_domain (-2) /* Unrecognsed domain id. */ ! 403: #define GNTST_bad_gntref (-3) /* Unrecognised or inappropriate gntref. */ ! 404: #define GNTST_bad_handle (-4) /* Unrecognised or inappropriate handle. */ ! 405: #define GNTST_bad_virt_addr (-5) /* Inappropriate virtual address to map. */ ! 406: #define GNTST_bad_dev_addr (-6) /* Inappropriate device address to unmap.*/ ! 407: #define GNTST_no_device_space (-7) /* Out of space in I/O MMU. */ ! 408: #define GNTST_permission_denied (-8) /* Not enough privilege for operation. */ ! 409: #define GNTST_bad_page (-9) /* Specified page was invalid for op. */ ! 410: #define GNTST_bad_copy_arg (-10) /* copy arguments cross page boundary. */ ! 411: #define GNTST_address_too_big (-11) /* transfer page address too large. */ ! 412: ! 413: #define GNTTABOP_error_msgs { \ ! 414: "okay", \ ! 415: "undefined error", \ ! 416: "unrecognised domain id", \ ! 417: "invalid grant reference", \ ! 418: "invalid mapping handle", \ ! 419: "invalid virtual address", \ ! 420: "invalid device address", \ ! 421: "no spare translation slot in the I/O MMU", \ ! 422: "permission denied", \ ! 423: "bad page", \ ! 424: "copy arguments cross page boundary", \ ! 425: "page address size too large" \ ! 426: } ! 427: ! 428: #endif /* __XEN_PUBLIC_GRANT_TABLE_H__ */ ! 429: ! 430: /* ! 431: * Local variables: ! 432: * mode: C ! 433: * c-set-style: "BSD" ! 434: * c-basic-offset: 4 ! 435: * tab-width: 4 ! 436: * indent-tabs-mode: nil ! 437: * End: ! 438: */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.