diff options
Diffstat (limited to 'include/xen/interface/grant_table.h')
| -rw-r--r-- | include/xen/interface/grant_table.h | 181 | 
1 files changed, 171 insertions, 10 deletions
diff --git a/include/xen/interface/grant_table.h b/include/xen/interface/grant_table.h index 39e571796e3..e40fae9bf11 100644 --- a/include/xen/interface/grant_table.h +++ b/include/xen/interface/grant_table.h @@ -85,12 +85,22 @@   */  /* + * Reference to a grant entry in a specified domain's grant table. + */ +typedef uint32_t grant_ref_t; + +/*   * A grant table comprises a packed array of grant entries in one or more   * page frames shared between Xen and a guest.   * [XEN]: This field is written by Xen and read by the sharing guest.   * [GST]: This field is written by the guest and read by Xen.   */ -struct grant_entry { + +/* + * Version 1 of the grant table entry structure is maintained purely + * for backwards compatibility.  New guests should use version 2. + */ +struct grant_entry_v1 {      /* GTF_xxx: various type and flag information.  [XEN,GST] */      uint16_t flags;      /* The domain being granted foreign privileges. [GST] */ @@ -108,10 +118,13 @@ struct grant_entry {   *  GTF_permit_access: Allow @domid to map/access @frame.   *  GTF_accept_transfer: Allow @domid to transfer ownership of one page frame   *                       to this guest. Xen writes the page number to @frame. + *  GTF_transitive: Allow @domid to transitively access a subrange of + *                  @trans_grant in @trans_domid.  No mappings are allowed.   */  #define GTF_invalid         (0U<<0)  #define GTF_permit_access   (1U<<0)  #define GTF_accept_transfer (2U<<0) +#define GTF_transitive      (3U<<0)  #define GTF_type_mask       (3U<<0)  /* @@ -119,6 +132,9 @@ struct grant_entry {   *  GTF_readonly: Restrict @domid to read-only mappings and accesses. [GST]   *  GTF_reading: Grant entry is currently mapped for reading by @domid. [XEN]   *  GTF_writing: Grant entry is currently mapped for writing by @domid. [XEN] + *  GTF_sub_page: Grant access to only a subrange of the page.  @domid + *                will only be allowed to copy from the grant, and not + *                map it. [GST]   */  #define _GTF_readonly       (2)  #define GTF_readonly        (1U<<_GTF_readonly) @@ -126,6 +142,8 @@ struct grant_entry {  #define GTF_reading         (1U<<_GTF_reading)  #define _GTF_writing        (4)  #define GTF_writing         (1U<<_GTF_writing) +#define _GTF_sub_page       (8) +#define GTF_sub_page        (1U<<_GTF_sub_page)  /*   * Subflags for GTF_accept_transfer: @@ -142,15 +160,81 @@ struct grant_entry {  #define _GTF_transfer_completed (3)  #define GTF_transfer_completed  (1U<<_GTF_transfer_completed) +/* + * Version 2 grant table entries.  These fulfil the same role as + * version 1 entries, but can represent more complicated operations. + * Any given domain will have either a version 1 or a version 2 table, + * and every entry in the table will be the same version. + * + * The interface by which domains use grant references does not depend + * on the grant table version in use by the other domain. + */ -/*********************************** - * GRANT TABLE QUERIES AND USES +/* + * Version 1 and version 2 grant entries share a common prefix.  The + * fields of the prefix are documented as part of struct + * grant_entry_v1.   */ +struct grant_entry_header { +    uint16_t flags; +    domid_t  domid; +};  /* - * Reference to a grant entry in a specified domain's grant table. + * Version 2 of the grant entry structure, here is an union because three + * different types are suppotted: full_page, sub_page and transitive. + */ +union grant_entry_v2 { +    struct grant_entry_header hdr; + +    /* +     * This member is used for V1-style full page grants, where either: +     * +     * -- hdr.type is GTF_accept_transfer, or +     * -- hdr.type is GTF_permit_access and GTF_sub_page is not set. +     * +     * In that case, the frame field has the same semantics as the +     * field of the same name in the V1 entry structure. +     */ +    struct { +	struct grant_entry_header hdr; +	uint32_t pad0; +	uint64_t frame; +    } full_page; + +    /* +     * If the grant type is GTF_grant_access and GTF_sub_page is set, +     * @domid is allowed to access bytes [@page_off,@page_off+@length) +     * in frame @frame. +     */ +    struct { +	struct grant_entry_header hdr; +	uint16_t page_off; +	uint16_t length; +	uint64_t frame; +    } sub_page; + +    /* +     * If the grant is GTF_transitive, @domid is allowed to use the +     * grant @gref in domain @trans_domid, as if it was the local +     * domain.  Obviously, the transitive access must be compatible +     * with the original grant. +     */ +    struct { +	struct grant_entry_header hdr; +	domid_t trans_domid; +	uint16_t pad0; +	grant_ref_t gref; +    } transitive; + +    uint32_t __spacer[4]; /* Pad to a power of two */ +}; + +typedef uint16_t grant_status_t; + +/*********************************** + * GRANT TABLE QUERIES AND USES   */ -typedef uint32_t grant_ref_t;  /*   * Handle to track a mapping created via a grant reference. @@ -226,7 +310,7 @@ struct gnttab_setup_table {      uint32_t nr_frames;      /* OUT parameters. */      int16_t  status;              /* GNTST_* */ -    GUEST_HANDLE(ulong) frame_list; +    GUEST_HANDLE(xen_pfn_t) frame_list;  };  DEFINE_GUEST_HANDLE_STRUCT(gnttab_setup_table); @@ -254,7 +338,7 @@ DEFINE_GUEST_HANDLE_STRUCT(gnttab_dump_table);  #define GNTTABOP_transfer                4  struct gnttab_transfer {      /* IN parameters. */ -    unsigned long mfn; +    xen_pfn_t mfn;      domid_t       domid;      grant_ref_t   ref;      /* OUT parameters. */ @@ -291,7 +375,7 @@ struct gnttab_copy {  	struct {  		union {  			grant_ref_t ref; -			unsigned long   gmfn; +			xen_pfn_t   gmfn;  		} u;  		domid_t  domid;  		uint16_t offset; @@ -322,6 +406,79 @@ struct gnttab_query_size {  DEFINE_GUEST_HANDLE_STRUCT(gnttab_query_size);  /* + * GNTTABOP_unmap_and_replace: Destroy one or more grant-reference mappings + * tracked by <handle> but atomically replace the page table entry with one + * pointing to the machine address under <new_addr>.  <new_addr> will be + * redirected to the null entry. + * NOTES: + *  1. The call may fail in an undefined manner if either mapping is not + *     tracked by <handle>. + *  2. After executing a batch of unmaps, it is guaranteed that no stale + *     mappings will remain in the device or host TLBs. + */ +#define GNTTABOP_unmap_and_replace    7 +struct gnttab_unmap_and_replace { +    /* IN parameters. */ +    uint64_t host_addr; +    uint64_t new_addr; +    grant_handle_t handle; +    /* OUT parameters. */ +    int16_t  status;              /* GNTST_* */ +}; +DEFINE_GUEST_HANDLE_STRUCT(gnttab_unmap_and_replace); + +/* + * GNTTABOP_set_version: Request a particular version of the grant + * table shared table structure.  This operation can only be performed + * once in any given domain.  It must be performed before any grants + * are activated; otherwise, the domain will be stuck with version 1. + * The only defined versions are 1 and 2. + */ +#define GNTTABOP_set_version          8 +struct gnttab_set_version { +    /* IN parameters */ +    uint32_t version; +}; +DEFINE_GUEST_HANDLE_STRUCT(gnttab_set_version); + +/* + * GNTTABOP_get_status_frames: Get the list of frames used to store grant + * status for <dom>. In grant format version 2, the status is separated + * from the other shared grant fields to allow more efficient synchronization + * using barriers instead of atomic cmpexch operations. + * <nr_frames> specify the size of vector <frame_list>. + * The frame addresses are returned in the <frame_list>. + * Only <nr_frames> addresses are returned, even if the table is larger. + * NOTES: + *  1. <dom> may be specified as DOMID_SELF. + *  2. Only a sufficiently-privileged domain may specify <dom> != DOMID_SELF. + */ +#define GNTTABOP_get_status_frames     9 +struct gnttab_get_status_frames { +    /* IN parameters. */ +    uint32_t nr_frames; +    domid_t  dom; +    /* OUT parameters. */ +    int16_t  status;              /* GNTST_* */ +    GUEST_HANDLE(uint64_t) frame_list; +}; +DEFINE_GUEST_HANDLE_STRUCT(gnttab_get_status_frames); + +/* + * GNTTABOP_get_version: Get the grant table version which is in + * effect for domain <dom>. + */ +#define GNTTABOP_get_version          10 +struct gnttab_get_version { +    /* IN parameters */ +    domid_t dom; +    uint16_t pad; +    /* OUT parameters */ +    uint32_t version; +}; +DEFINE_GUEST_HANDLE_STRUCT(gnttab_get_version); + +/*   * Bitfield values for update_pin_status.flags.   */   /* Map the grant entry for access by I/O devices. */ @@ -362,7 +519,9 @@ DEFINE_GUEST_HANDLE_STRUCT(gnttab_query_size);  #define GNTST_no_device_space  (-7) /* Out of space in I/O MMU.              */  #define GNTST_permission_denied (-8) /* Not enough privilege for operation.  */  #define GNTST_bad_page         (-9) /* Specified page was invalid for op.    */ -#define GNTST_bad_copy_arg    (-10) /* copy arguments cross page boundary */ +#define GNTST_bad_copy_arg    (-10) /* copy arguments cross page boundary.   */ +#define GNTST_address_too_big (-11) /* transfer page address too large.      */ +#define GNTST_eagain          (-12) /* Operation not done; try again.        */  #define GNTTABOP_error_msgs {                   \      "okay",                                     \ @@ -375,7 +534,9 @@ DEFINE_GUEST_HANDLE_STRUCT(gnttab_query_size);      "no spare translation slot in the I/O MMU", \      "permission denied",                        \      "bad page",                                 \ -    "copy arguments cross page boundary"        \ +    "copy arguments cross page boundary",       \ +    "page address size too large",              \ +    "operation not done; try again"             \  }  #endif /* __XEN_PUBLIC_GRANT_TABLE_H__ */  | 
