brintos

brintos / linux-shallow public Read only

0
0
Text · 21.1 KiB · cebbd99 Raw
591 lines · c
1/* SPDX-License-Identifier: MIT */2/******************************************************************************3 * grant_table.h4 *5 * Interface for granting foreign access to page frames, and receiving6 * page-ownership transfers.7 *8 * Copyright (c) 2004, K A Fraser9 */10 11#ifndef __XEN_PUBLIC_GRANT_TABLE_H__12#define __XEN_PUBLIC_GRANT_TABLE_H__13 14#include <xen/interface/xen.h>15 16/***********************************17 * GRANT TABLE REPRESENTATION18 */19 20/* Some rough guidelines on accessing and updating grant-table entries21 * in a concurrency-safe manner. For more information, Linux contains a22 * reference implementation for guest OSes (drivers/xen/grant_table.c, see23 * http://git.kernel.org/?p=linux/kernel/git/torvalds/linux.git;a=blob;f=drivers/xen/grant-table.c;hb=HEAD24 *25 * NB. WMB is a no-op on current-generation x86 processors. However, a26 *     compiler barrier will still be required.27 *28 * Introducing a valid entry into the grant table:29 *  1. Write ent->domid.30 *  2. Write ent->frame:31 *      GTF_permit_access:   Frame to which access is permitted.32 *      GTF_accept_transfer: Pseudo-phys frame slot being filled by new33 *                           frame, or zero if none.34 *  3. Write memory barrier (WMB).35 *  4. Write ent->flags, inc. valid type.36 *37 * Invalidating an unused GTF_permit_access entry:38 *  1. flags = ent->flags.39 *  2. Observe that !(flags & (GTF_reading|GTF_writing)).40 *  3. Check result of SMP-safe CMPXCHG(&ent->flags, flags, 0).41 *  NB. No need for WMB as reuse of entry is control-dependent on success of42 *      step 3, and all architectures guarantee ordering of ctrl-dep writes.43 *44 * Invalidating an in-use GTF_permit_access entry:45 *  This cannot be done directly. Request assistance from the domain controller46 *  which can set a timeout on the use of a grant entry and take necessary47 *  action. (NB. This is not yet implemented!).48 *49 * Invalidating an unused GTF_accept_transfer entry:50 *  1. flags = ent->flags.51 *  2. Observe that !(flags & GTF_transfer_committed). [*]52 *  3. Check result of SMP-safe CMPXCHG(&ent->flags, flags, 0).53 *  NB. No need for WMB as reuse of entry is control-dependent on success of54 *      step 3, and all architectures guarantee ordering of ctrl-dep writes.55 *  [*] If GTF_transfer_committed is set then the grant entry is 'committed'.56 *      The guest must /not/ modify the grant entry until the address of the57 *      transferred frame is written. It is safe for the guest to spin waiting58 *      for this to occur (detect by observing GTF_transfer_completed in59 *      ent->flags).60 *61 * Invalidating a committed GTF_accept_transfer entry:62 *  1. Wait for (ent->flags & GTF_transfer_completed).63 *64 * Changing a GTF_permit_access from writable to read-only:65 *  Use SMP-safe CMPXCHG to set GTF_readonly, while checking !GTF_writing.66 *67 * Changing a GTF_permit_access from read-only to writable:68 *  Use SMP-safe bit-setting instruction.69 */70 71/*72 * Reference to a grant entry in a specified domain's grant table.73 */74typedef uint32_t grant_ref_t;75 76/*77 * A grant table comprises a packed array of grant entries in one or more78 * page frames shared between Xen and a guest.79 * [XEN]: This field is written by Xen and read by the sharing guest.80 * [GST]: This field is written by the guest and read by Xen.81 */82 83/*84 * Version 1 of the grant table entry structure is maintained largely for85 * backwards compatibility.  New guests are recommended to support using86 * version 2 to overcome version 1 limitations, but to default to version 1.87 */88struct grant_entry_v1 {89    /* GTF_xxx: various type and flag information.  [XEN,GST] */90    uint16_t flags;91    /* The domain being granted foreign privileges. [GST] */92    domid_t  domid;93    /*94     * GTF_permit_access: GFN that @domid is allowed to map and access. [GST]95     * GTF_accept_transfer: GFN that @domid is allowed to transfer into. [GST]96     * GTF_transfer_completed: MFN whose ownership transferred by @domid97     *                         (non-translated guests only). [XEN]98     */99    uint32_t frame;100};101 102/* The first few grant table entries will be preserved across grant table103 * version changes and may be pre-populated at domain creation by tools.104 */105#define GNTTAB_NR_RESERVED_ENTRIES     8106#define GNTTAB_RESERVED_CONSOLE        0107#define GNTTAB_RESERVED_XENSTORE       1108 109/*110 * Type of grant entry.111 *  GTF_invalid: This grant entry grants no privileges.112 *  GTF_permit_access: Allow @domid to map/access @frame.113 *  GTF_accept_transfer: Allow @domid to transfer ownership of one page frame114 *                       to this guest. Xen writes the page number to @frame.115 *  GTF_transitive: Allow @domid to transitively access a subrange of116 *                  @trans_grant in @trans_domid.  No mappings are allowed.117 */118#define GTF_invalid         (0U<<0)119#define GTF_permit_access   (1U<<0)120#define GTF_accept_transfer (2U<<0)121#define GTF_transitive      (3U<<0)122#define GTF_type_mask       (3U<<0)123 124/*125 * Subflags for GTF_permit_access and GTF_transitive.126 *  GTF_readonly: Restrict @domid to read-only mappings and accesses. [GST]127 *  GTF_reading: Grant entry is currently mapped for reading by @domid. [XEN]128 *  GTF_writing: Grant entry is currently mapped for writing by @domid. [XEN]129 * Further subflags for GTF_permit_access only.130 *  GTF_PAT, GTF_PWT, GTF_PCD: (x86) cache attribute flags to be used for131 *                             mappings of the grant [GST]132 *  GTF_sub_page: Grant access to only a subrange of the page.  @domid133 *                will only be allowed to copy from the grant, and not134 *                map it. [GST]135 */136#define _GTF_readonly       (2)137#define GTF_readonly        (1U<<_GTF_readonly)138#define _GTF_reading        (3)139#define GTF_reading         (1U<<_GTF_reading)140#define _GTF_writing        (4)141#define GTF_writing         (1U<<_GTF_writing)142#define _GTF_PWT            (5)143#define GTF_PWT             (1U<<_GTF_PWT)144#define _GTF_PCD            (6)145#define GTF_PCD             (1U<<_GTF_PCD)146#define _GTF_PAT            (7)147#define GTF_PAT             (1U<<_GTF_PAT)148#define _GTF_sub_page       (8)149#define GTF_sub_page        (1U<<_GTF_sub_page)150 151/*152 * Subflags for GTF_accept_transfer:153 *  GTF_transfer_committed: Xen sets this flag to indicate that it is committed154 *      to transferring ownership of a page frame. When a guest sees this flag155 *      it must /not/ modify the grant entry until GTF_transfer_completed is156 *      set by Xen.157 *  GTF_transfer_completed: It is safe for the guest to spin-wait on this flag158 *      after reading GTF_transfer_committed. Xen will always write the frame159 *      address, followed by ORing this flag, in a timely manner.160 */161#define _GTF_transfer_committed (2)162#define GTF_transfer_committed  (1U<<_GTF_transfer_committed)163#define _GTF_transfer_completed (3)164#define GTF_transfer_completed  (1U<<_GTF_transfer_completed)165 166/*167 * Version 2 grant table entries.  These fulfil the same role as168 * version 1 entries, but can represent more complicated operations.169 * Any given domain will have either a version 1 or a version 2 table,170 * and every entry in the table will be the same version.171 *172 * The interface by which domains use grant references does not depend173 * on the grant table version in use by the other domain.174 */175 176/*177 * Version 1 and version 2 grant entries share a common prefix.  The178 * fields of the prefix are documented as part of struct179 * grant_entry_v1.180 */181struct grant_entry_header {182    uint16_t flags;183    domid_t  domid;184};185 186/*187 * Version 2 of the grant entry structure.188 */189union grant_entry_v2 {190    struct grant_entry_header hdr;191 192    /*193     * This member is used for V1-style full page grants, where either:194     *195     * -- hdr.type is GTF_accept_transfer, or196     * -- hdr.type is GTF_permit_access and GTF_sub_page is not set.197     *198     * In that case, the frame field has the same semantics as the199     * field of the same name in the V1 entry structure.200     */201    struct {202        struct grant_entry_header hdr;203        uint32_t pad0;204        uint64_t frame;205    } full_page;206 207    /*208     * If the grant type is GTF_grant_access and GTF_sub_page is set,209     * @domid is allowed to access bytes [@page_off,@page_off+@length)210     * in frame @frame.211     */212    struct {213        struct grant_entry_header hdr;214        uint16_t page_off;215        uint16_t length;216        uint64_t frame;217    } sub_page;218 219    /*220     * If the grant is GTF_transitive, @domid is allowed to use the221     * grant @gref in domain @trans_domid, as if it was the local222     * domain.  Obviously, the transitive access must be compatible223     * with the original grant.224     *225     * The current version of Xen does not allow transitive grants226     * to be mapped.227     */228    struct {229        struct grant_entry_header hdr;230        domid_t trans_domid;231        uint16_t pad0;232        grant_ref_t gref;233    } transitive;234 235    uint32_t __spacer[4]; /* Pad to a power of two */236};237 238typedef uint16_t grant_status_t;239 240/***********************************241 * GRANT TABLE QUERIES AND USES242 */243 244#define GNTTABOP_map_grant_ref        0245#define GNTTABOP_unmap_grant_ref      1246#define GNTTABOP_setup_table          2247#define GNTTABOP_dump_table           3248#define GNTTABOP_transfer             4249#define GNTTABOP_copy                 5250#define GNTTABOP_query_size           6251#define GNTTABOP_unmap_and_replace    7252#define GNTTABOP_set_version          8253#define GNTTABOP_get_status_frames    9254#define GNTTABOP_get_version          10255#define GNTTABOP_swap_grant_ref	      11256#define GNTTABOP_cache_flush	      12257/* ` } */258 259/*260 * Handle to track a mapping created via a grant reference.261 */262typedef uint32_t grant_handle_t;263 264/*265 * GNTTABOP_map_grant_ref: Map the grant entry (<dom>,<ref>) for access266 * by devices and/or host CPUs. If successful, <handle> is a tracking number267 * that must be presented later to destroy the mapping(s). On error, <status>268 * is a negative status code.269 * NOTES:270 *  1. If GNTMAP_device_map is specified then <dev_bus_addr> is the address271 *     via which I/O devices may access the granted frame.272 *  2. If GNTMAP_host_map is specified then a mapping will be added at273 *     either a host virtual address in the current address space, or at274 *     a PTE at the specified machine address.  The type of mapping to275 *     perform is selected through the GNTMAP_contains_pte flag, and the276 *     address is specified in <host_addr>.277 *  3. Mappings should only be destroyed via GNTTABOP_unmap_grant_ref. If a278 *     host mapping is destroyed by other means then it is *NOT* guaranteed279 *     to be accounted to the correct grant reference!280 */281struct gnttab_map_grant_ref {282    /* IN parameters. */283    uint64_t host_addr;284    uint32_t flags;               /* GNTMAP_* */285    grant_ref_t ref;286    domid_t  dom;287    /* OUT parameters. */288    int16_t  status;              /* GNTST_* */289    grant_handle_t handle;290    uint64_t dev_bus_addr;291};292DEFINE_GUEST_HANDLE_STRUCT(gnttab_map_grant_ref);293 294/*295 * GNTTABOP_unmap_grant_ref: Destroy one or more grant-reference mappings296 * tracked by <handle>. If <host_addr> or <dev_bus_addr> is zero, that297 * field is ignored. If non-zero, they must refer to a device/host mapping298 * that is tracked by <handle>299 * NOTES:300 *  1. The call may fail in an undefined manner if either mapping is not301 *     tracked by <handle>.302 *  3. After executing a batch of unmaps, it is guaranteed that no stale303 *     mappings will remain in the device or host TLBs.304 */305struct gnttab_unmap_grant_ref {306    /* IN parameters. */307    uint64_t host_addr;308    uint64_t dev_bus_addr;309    grant_handle_t handle;310    /* OUT parameters. */311    int16_t  status;              /* GNTST_* */312};313DEFINE_GUEST_HANDLE_STRUCT(gnttab_unmap_grant_ref);314 315/*316 * GNTTABOP_setup_table: Set up a grant table for <dom> comprising at least317 * <nr_frames> pages. The frame addresses are written to the <frame_list>.318 * Only <nr_frames> addresses are written, even if the table is larger.319 * NOTES:320 *  1. <dom> may be specified as DOMID_SELF.321 *  2. Only a sufficiently-privileged domain may specify <dom> != DOMID_SELF.322 *  3. Xen may not support more than a single grant-table page per domain.323 */324struct gnttab_setup_table {325    /* IN parameters. */326    domid_t  dom;327    uint32_t nr_frames;328    /* OUT parameters. */329    int16_t  status;              /* GNTST_* */330    GUEST_HANDLE(xen_pfn_t) frame_list;331};332DEFINE_GUEST_HANDLE_STRUCT(gnttab_setup_table);333 334/*335 * GNTTABOP_dump_table: Dump the contents of the grant table to the336 * xen console. Debugging use only.337 */338struct gnttab_dump_table {339    /* IN parameters. */340    domid_t dom;341    /* OUT parameters. */342    int16_t status;               /* GNTST_* */343};344DEFINE_GUEST_HANDLE_STRUCT(gnttab_dump_table);345 346/*347 * GNTTABOP_transfer: Transfer <frame> to a foreign domain. The foreign domain348 * has previously registered its interest in the transfer via <domid, ref>.349 *350 * Note that, even if the transfer fails, the specified page no longer belongs351 * to the calling domain *unless* the error is GNTST_bad_page.352 *353 * Note further that only PV guests can use this operation.354 */355struct gnttab_transfer {356    /* IN parameters. */357    xen_pfn_t     mfn;358    domid_t       domid;359    grant_ref_t   ref;360    /* OUT parameters. */361    int16_t       status;362};363DEFINE_GUEST_HANDLE_STRUCT(gnttab_transfer);364 365/*366 * GNTTABOP_copy: Hypervisor based copy367 * source and destinations can be eithers MFNs or, for foreign domains,368 * grant references. the foreign domain has to grant read/write access369 * in its grant table.370 *371 * The flags specify what type source and destinations are (either MFN372 * or grant reference).373 *374 * Note that this can also be used to copy data between two domains375 * via a third party if the source and destination domains had previously376 * grant appropriate access to their pages to the third party.377 *378 * source_offset specifies an offset in the source frame, dest_offset379 * the offset in the target frame and  len specifies the number of380 * bytes to be copied.381 */382 383#define _GNTCOPY_source_gref      (0)384#define GNTCOPY_source_gref       (1<<_GNTCOPY_source_gref)385#define _GNTCOPY_dest_gref        (1)386#define GNTCOPY_dest_gref         (1<<_GNTCOPY_dest_gref)387 388struct gnttab_copy {389    /* IN parameters. */390    struct gnttab_copy_ptr {391        union {392            grant_ref_t ref;393            xen_pfn_t   gmfn;394        } u;395        domid_t  domid;396        uint16_t offset;397    } source, dest;398    uint16_t      len;399    uint16_t      flags;          /* GNTCOPY_* */400    /* OUT parameters. */401    int16_t       status;402};403DEFINE_GUEST_HANDLE_STRUCT(gnttab_copy);404 405/*406 * GNTTABOP_query_size: Query the current and maximum sizes of the shared407 * grant table.408 * NOTES:409 *  1. <dom> may be specified as DOMID_SELF.410 *  2. Only a sufficiently-privileged domain may specify <dom> != DOMID_SELF.411 */412struct gnttab_query_size {413    /* IN parameters. */414    domid_t  dom;415    /* OUT parameters. */416    uint32_t nr_frames;417    uint32_t max_nr_frames;418    int16_t  status;              /* GNTST_* */419};420DEFINE_GUEST_HANDLE_STRUCT(gnttab_query_size);421 422/*423 * GNTTABOP_unmap_and_replace: Destroy one or more grant-reference mappings424 * tracked by <handle> but atomically replace the page table entry with one425 * pointing to the machine address under <new_addr>.  <new_addr> will be426 * redirected to the null entry.427 * NOTES:428 *  1. The call may fail in an undefined manner if either mapping is not429 *     tracked by <handle>.430 *  2. After executing a batch of unmaps, it is guaranteed that no stale431 *     mappings will remain in the device or host TLBs.432 */433struct gnttab_unmap_and_replace {434    /* IN parameters. */435    uint64_t host_addr;436    uint64_t new_addr;437    grant_handle_t handle;438    /* OUT parameters. */439    int16_t  status;              /* GNTST_* */440};441DEFINE_GUEST_HANDLE_STRUCT(gnttab_unmap_and_replace);442 443/*444 * GNTTABOP_set_version: Request a particular version of the grant445 * table shared table structure.  This operation may be used to toggle446 * between different versions, but must be performed while no grants447 * are active.  The only defined versions are 1 and 2.448 */449struct gnttab_set_version {450    /* IN/OUT parameters */451    uint32_t version;452};453DEFINE_GUEST_HANDLE_STRUCT(gnttab_set_version);454 455/*456 * GNTTABOP_get_status_frames: Get the list of frames used to store grant457 * status for <dom>. In grant format version 2, the status is separated458 * from the other shared grant fields to allow more efficient synchronization459 * using barriers instead of atomic cmpexch operations.460 * <nr_frames> specify the size of vector <frame_list>.461 * The frame addresses are returned in the <frame_list>.462 * Only <nr_frames> addresses are returned, even if the table is larger.463 * NOTES:464 *  1. <dom> may be specified as DOMID_SELF.465 *  2. Only a sufficiently-privileged domain may specify <dom> != DOMID_SELF.466 */467struct gnttab_get_status_frames {468    /* IN parameters. */469    uint32_t nr_frames;470    domid_t  dom;471    /* OUT parameters. */472    int16_t  status;              /* GNTST_* */473    GUEST_HANDLE(uint64_t) frame_list;474};475DEFINE_GUEST_HANDLE_STRUCT(gnttab_get_status_frames);476 477/*478 * GNTTABOP_get_version: Get the grant table version which is in479 * effect for domain <dom>.480 */481struct gnttab_get_version {482    /* IN parameters */483    domid_t dom;484    uint16_t pad;485    /* OUT parameters */486    uint32_t version;487};488DEFINE_GUEST_HANDLE_STRUCT(gnttab_get_version);489 490/*491 * GNTTABOP_swap_grant_ref: Swap the contents of two grant entries.492 */493struct gnttab_swap_grant_ref {494    /* IN parameters */495    grant_ref_t ref_a;496    grant_ref_t ref_b;497    /* OUT parameters */498    int16_t status;             /* GNTST_* */499};500DEFINE_GUEST_HANDLE_STRUCT(gnttab_swap_grant_ref);501 502/*503 * Issue one or more cache maintenance operations on a portion of a504 * page granted to the calling domain by a foreign domain.505 */506struct gnttab_cache_flush {507    union {508        uint64_t dev_bus_addr;509        grant_ref_t ref;510    } a;511    uint16_t offset; /* offset from start of grant */512    uint16_t length; /* size within the grant */513#define GNTTAB_CACHE_CLEAN          (1u<<0)514#define GNTTAB_CACHE_INVAL          (1u<<1)515#define GNTTAB_CACHE_SOURCE_GREF    (1u<<31)516    uint32_t op;517};518DEFINE_GUEST_HANDLE_STRUCT(gnttab_cache_flush);519 520/*521 * Bitfield values for gnttab_map_grant_ref.flags.522 */523 /* Map the grant entry for access by I/O devices. */524#define _GNTMAP_device_map      (0)525#define GNTMAP_device_map       (1<<_GNTMAP_device_map)526 /* Map the grant entry for access by host CPUs. */527#define _GNTMAP_host_map        (1)528#define GNTMAP_host_map         (1<<_GNTMAP_host_map)529 /* Accesses to the granted frame will be restricted to read-only access. */530#define _GNTMAP_readonly        (2)531#define GNTMAP_readonly         (1<<_GNTMAP_readonly)532 /*533  * GNTMAP_host_map subflag:534  *  0 => The host mapping is usable only by the guest OS.535  *  1 => The host mapping is usable by guest OS + current application.536  */537#define _GNTMAP_application_map (3)538#define GNTMAP_application_map  (1<<_GNTMAP_application_map)539 540 /*541  * GNTMAP_contains_pte subflag:542  *  0 => This map request contains a host virtual address.543  *  1 => This map request contains the machine addess of the PTE to update.544  */545#define _GNTMAP_contains_pte    (4)546#define GNTMAP_contains_pte     (1<<_GNTMAP_contains_pte)547 548/*549 * Bits to be placed in guest kernel available PTE bits (architecture550 * dependent; only supported when XENFEAT_gnttab_map_avail_bits is set).551 */552#define _GNTMAP_guest_avail0    (16)553#define GNTMAP_guest_avail_mask ((uint32_t)~0 << _GNTMAP_guest_avail0)554 555/*556 * Values for error status returns. All errors are -ve.557 */558#define GNTST_okay             (0)  /* Normal return.                        */559#define GNTST_general_error    (-1) /* General undefined error.              */560#define GNTST_bad_domain       (-2) /* Unrecognsed domain id.                */561#define GNTST_bad_gntref       (-3) /* Unrecognised or inappropriate gntref. */562#define GNTST_bad_handle       (-4) /* Unrecognised or inappropriate handle. */563#define GNTST_bad_virt_addr    (-5) /* Inappropriate virtual address to map. */564#define GNTST_bad_dev_addr     (-6) /* Inappropriate device address to unmap.*/565#define GNTST_no_device_space  (-7) /* Out of space in I/O MMU.              */566#define GNTST_permission_denied (-8) /* Not enough privilege for operation.  */567#define GNTST_bad_page         (-9) /* Specified page was invalid for op.    */568#define GNTST_bad_copy_arg    (-10) /* copy arguments cross page boundary.   */569#define GNTST_address_too_big (-11) /* transfer page address too large.      */570#define GNTST_eagain          (-12) /* Operation not done; try again.        */571#define GNTST_no_space        (-13) /* Out of space (handles etc).           */572 573#define GNTTABOP_error_msgs {                   \574    "okay",                                     \575    "undefined error",                          \576    "unrecognised domain id",                   \577    "invalid grant reference",                  \578    "invalid mapping handle",                   \579    "invalid virtual address",                  \580    "invalid device address",                   \581    "no spare translation slot in the I/O MMU", \582    "permission denied",                        \583    "bad page",                                 \584    "copy arguments cross page boundary",       \585    "page address size too large",              \586    "operation not done; try again",            \587    "out of space",                             \588}589 590#endif /* __XEN_PUBLIC_GRANT_TABLE_H__ */591