1*8ac98aedSDavid Woodhouse /* SPDX-License-Identifier: MIT */ 2a3434a2dSAnthony PERARD /****************************************************************************** 3a3434a2dSAnthony PERARD * grant_table.h 4a3434a2dSAnthony PERARD * 5a3434a2dSAnthony PERARD * Interface for granting foreign access to page frames, and receiving 6a3434a2dSAnthony PERARD * page-ownership transfers. 7a3434a2dSAnthony PERARD * 8a3434a2dSAnthony PERARD * Copyright (c) 2004, K A Fraser 9a3434a2dSAnthony PERARD */ 10a3434a2dSAnthony PERARD 11a3434a2dSAnthony PERARD #ifndef __XEN_PUBLIC_GRANT_TABLE_H__ 12a3434a2dSAnthony PERARD #define __XEN_PUBLIC_GRANT_TABLE_H__ 13a3434a2dSAnthony PERARD 1450c88402SJoao Martins #include "xen.h" 1550c88402SJoao Martins 1650c88402SJoao Martins /* 1750c88402SJoao Martins * `incontents 150 gnttab Grant Tables 1850c88402SJoao Martins * 1950c88402SJoao Martins * Xen's grant tables provide a generic mechanism to memory sharing 2050c88402SJoao Martins * between domains. This shared memory interface underpins the split 2150c88402SJoao Martins * device drivers for block and network IO. 2250c88402SJoao Martins * 2350c88402SJoao Martins * Each domain has its own grant table. This is a data structure that 2450c88402SJoao Martins * is shared with Xen; it allows the domain to tell Xen what kind of 2550c88402SJoao Martins * permissions other domains have on its pages. Entries in the grant 2650c88402SJoao Martins * table are identified by grant references. A grant reference is an 2750c88402SJoao Martins * integer, which indexes into the grant table. It acts as a 2850c88402SJoao Martins * capability which the grantee can use to perform operations on the 2950c88402SJoao Martins * granter's memory. 3050c88402SJoao Martins * 3150c88402SJoao Martins * This capability-based system allows shared-memory communications 3250c88402SJoao Martins * between unprivileged domains. A grant reference also encapsulates 3350c88402SJoao Martins * the details of a shared page, removing the need for a domain to 3450c88402SJoao Martins * know the real machine address of a page it is sharing. This makes 3550c88402SJoao Martins * it possible to share memory correctly with domains running in 3650c88402SJoao Martins * fully virtualised memory. 3750c88402SJoao Martins */ 3850c88402SJoao Martins 3950c88402SJoao Martins /*********************************** 4050c88402SJoao Martins * GRANT TABLE REPRESENTATION 4150c88402SJoao Martins */ 4250c88402SJoao Martins 4350c88402SJoao Martins /* Some rough guidelines on accessing and updating grant-table entries 4450c88402SJoao Martins * in a concurrency-safe manner. For more information, Linux contains a 4550c88402SJoao Martins * reference implementation for guest OSes (drivers/xen/grant_table.c, see 4650c88402SJoao Martins * http://git.kernel.org/?p=linux/kernel/git/torvalds/linux.git;a=blob;f=drivers/xen/grant-table.c;hb=HEAD 4750c88402SJoao Martins * 4850c88402SJoao Martins * NB. WMB is a no-op on current-generation x86 processors. However, a 4950c88402SJoao Martins * compiler barrier will still be required. 5050c88402SJoao Martins * 5150c88402SJoao Martins * Introducing a valid entry into the grant table: 5250c88402SJoao Martins * 1. Write ent->domid. 5350c88402SJoao Martins * 2. Write ent->frame: 5450c88402SJoao Martins * GTF_permit_access: Frame to which access is permitted. 5550c88402SJoao Martins * GTF_accept_transfer: Pseudo-phys frame slot being filled by new 5650c88402SJoao Martins * frame, or zero if none. 5750c88402SJoao Martins * 3. Write memory barrier (WMB). 5850c88402SJoao Martins * 4. Write ent->flags, inc. valid type. 5950c88402SJoao Martins * 6050c88402SJoao Martins * Invalidating an unused GTF_permit_access entry: 6150c88402SJoao Martins * 1. flags = ent->flags. 6250c88402SJoao Martins * 2. Observe that !(flags & (GTF_reading|GTF_writing)). 6350c88402SJoao Martins * 3. Check result of SMP-safe CMPXCHG(&ent->flags, flags, 0). 6450c88402SJoao Martins * NB. No need for WMB as reuse of entry is control-dependent on success of 6550c88402SJoao Martins * step 3, and all architectures guarantee ordering of ctrl-dep writes. 6650c88402SJoao Martins * 6750c88402SJoao Martins * Invalidating an in-use GTF_permit_access entry: 6850c88402SJoao Martins * This cannot be done directly. Request assistance from the domain controller 6950c88402SJoao Martins * which can set a timeout on the use of a grant entry and take necessary 7050c88402SJoao Martins * action. (NB. This is not yet implemented!). 7150c88402SJoao Martins * 7250c88402SJoao Martins * Invalidating an unused GTF_accept_transfer entry: 7350c88402SJoao Martins * 1. flags = ent->flags. 7450c88402SJoao Martins * 2. Observe that !(flags & GTF_transfer_committed). [*] 7550c88402SJoao Martins * 3. Check result of SMP-safe CMPXCHG(&ent->flags, flags, 0). 7650c88402SJoao Martins * NB. No need for WMB as reuse of entry is control-dependent on success of 7750c88402SJoao Martins * step 3, and all architectures guarantee ordering of ctrl-dep writes. 7850c88402SJoao Martins * [*] If GTF_transfer_committed is set then the grant entry is 'committed'. 7950c88402SJoao Martins * The guest must /not/ modify the grant entry until the address of the 8050c88402SJoao Martins * transferred frame is written. It is safe for the guest to spin waiting 8150c88402SJoao Martins * for this to occur (detect by observing GTF_transfer_completed in 8250c88402SJoao Martins * ent->flags). 8350c88402SJoao Martins * 8450c88402SJoao Martins * Invalidating a committed GTF_accept_transfer entry: 8550c88402SJoao Martins * 1. Wait for (ent->flags & GTF_transfer_completed). 8650c88402SJoao Martins * 8750c88402SJoao Martins * Changing a GTF_permit_access from writable to read-only: 8850c88402SJoao Martins * Use SMP-safe CMPXCHG to set GTF_readonly, while checking !GTF_writing. 8950c88402SJoao Martins * 9050c88402SJoao Martins * Changing a GTF_permit_access from read-only to writable: 9150c88402SJoao Martins * Use SMP-safe bit-setting instruction. 9250c88402SJoao Martins */ 9350c88402SJoao Martins 94a3434a2dSAnthony PERARD /* 95a3434a2dSAnthony PERARD * Reference to a grant entry in a specified domain's grant table. 96a3434a2dSAnthony PERARD */ 97a3434a2dSAnthony PERARD typedef uint32_t grant_ref_t; 98a3434a2dSAnthony PERARD 9950c88402SJoao Martins /* 10050c88402SJoao Martins * A grant table comprises a packed array of grant entries in one or more 10150c88402SJoao Martins * page frames shared between Xen and a guest. 10250c88402SJoao Martins * [XEN]: This field is written by Xen and read by the sharing guest. 10350c88402SJoao Martins * [GST]: This field is written by the guest and read by Xen. 10450c88402SJoao Martins */ 10550c88402SJoao Martins 10650c88402SJoao Martins /* 10750c88402SJoao Martins * Version 1 of the grant table entry structure is maintained largely for 10850c88402SJoao Martins * backwards compatibility. New guests are recommended to support using 10950c88402SJoao Martins * version 2 to overcome version 1 limitations, but to default to version 1. 11050c88402SJoao Martins */ 11150c88402SJoao Martins #if __XEN_INTERFACE_VERSION__ < 0x0003020a 11250c88402SJoao Martins #define grant_entry_v1 grant_entry 11350c88402SJoao Martins #define grant_entry_v1_t grant_entry_t 11450c88402SJoao Martins #endif 11550c88402SJoao Martins struct grant_entry_v1 { 11650c88402SJoao Martins /* GTF_xxx: various type and flag information. [XEN,GST] */ 11750c88402SJoao Martins uint16_t flags; 11850c88402SJoao Martins /* The domain being granted foreign privileges. [GST] */ 11950c88402SJoao Martins domid_t domid; 12050c88402SJoao Martins /* 12150c88402SJoao Martins * GTF_permit_access: GFN that @domid is allowed to map and access. [GST] 12250c88402SJoao Martins * GTF_accept_transfer: GFN that @domid is allowed to transfer into. [GST] 12350c88402SJoao Martins * GTF_transfer_completed: MFN whose ownership transferred by @domid 12450c88402SJoao Martins * (non-translated guests only). [XEN] 12550c88402SJoao Martins */ 12650c88402SJoao Martins uint32_t frame; 12750c88402SJoao Martins }; 12850c88402SJoao Martins typedef struct grant_entry_v1 grant_entry_v1_t; 12950c88402SJoao Martins 13050c88402SJoao Martins /* The first few grant table entries will be preserved across grant table 13150c88402SJoao Martins * version changes and may be pre-populated at domain creation by tools. 13250c88402SJoao Martins */ 13350c88402SJoao Martins #define GNTTAB_NR_RESERVED_ENTRIES 8 13450c88402SJoao Martins #define GNTTAB_RESERVED_CONSOLE 0 13550c88402SJoao Martins #define GNTTAB_RESERVED_XENSTORE 1 13650c88402SJoao Martins 13750c88402SJoao Martins /* 13850c88402SJoao Martins * Type of grant entry. 13950c88402SJoao Martins * GTF_invalid: This grant entry grants no privileges. 14050c88402SJoao Martins * GTF_permit_access: Allow @domid to map/access @frame. 14150c88402SJoao Martins * GTF_accept_transfer: Allow @domid to transfer ownership of one page frame 14250c88402SJoao Martins * to this guest. Xen writes the page number to @frame. 14350c88402SJoao Martins * GTF_transitive: Allow @domid to transitively access a subrange of 14450c88402SJoao Martins * @trans_grant in @trans_domid. No mappings are allowed. 14550c88402SJoao Martins */ 14650c88402SJoao Martins #define GTF_invalid (0U<<0) 14750c88402SJoao Martins #define GTF_permit_access (1U<<0) 14850c88402SJoao Martins #define GTF_accept_transfer (2U<<0) 14950c88402SJoao Martins #define GTF_transitive (3U<<0) 15050c88402SJoao Martins #define GTF_type_mask (3U<<0) 15150c88402SJoao Martins 15250c88402SJoao Martins /* 15350c88402SJoao Martins * Subflags for GTF_permit_access and GTF_transitive. 15450c88402SJoao Martins * GTF_readonly: Restrict @domid to read-only mappings and accesses. [GST] 15550c88402SJoao Martins * GTF_reading: Grant entry is currently mapped for reading by @domid. [XEN] 15650c88402SJoao Martins * GTF_writing: Grant entry is currently mapped for writing by @domid. [XEN] 15750c88402SJoao Martins * Further subflags for GTF_permit_access only. 15850c88402SJoao Martins * GTF_PAT, GTF_PWT, GTF_PCD: (x86) cache attribute flags to be used for 15950c88402SJoao Martins * mappings of the grant [GST] 16050c88402SJoao Martins * GTF_sub_page: Grant access to only a subrange of the page. @domid 16150c88402SJoao Martins * will only be allowed to copy from the grant, and not 16250c88402SJoao Martins * map it. [GST] 16350c88402SJoao Martins */ 16450c88402SJoao Martins #define _GTF_readonly (2) 16550c88402SJoao Martins #define GTF_readonly (1U<<_GTF_readonly) 16650c88402SJoao Martins #define _GTF_reading (3) 16750c88402SJoao Martins #define GTF_reading (1U<<_GTF_reading) 16850c88402SJoao Martins #define _GTF_writing (4) 16950c88402SJoao Martins #define GTF_writing (1U<<_GTF_writing) 17050c88402SJoao Martins #define _GTF_PWT (5) 17150c88402SJoao Martins #define GTF_PWT (1U<<_GTF_PWT) 17250c88402SJoao Martins #define _GTF_PCD (6) 17350c88402SJoao Martins #define GTF_PCD (1U<<_GTF_PCD) 17450c88402SJoao Martins #define _GTF_PAT (7) 17550c88402SJoao Martins #define GTF_PAT (1U<<_GTF_PAT) 17650c88402SJoao Martins #define _GTF_sub_page (8) 17750c88402SJoao Martins #define GTF_sub_page (1U<<_GTF_sub_page) 17850c88402SJoao Martins 17950c88402SJoao Martins /* 18050c88402SJoao Martins * Subflags for GTF_accept_transfer: 18150c88402SJoao Martins * GTF_transfer_committed: Xen sets this flag to indicate that it is committed 18250c88402SJoao Martins * to transferring ownership of a page frame. When a guest sees this flag 18350c88402SJoao Martins * it must /not/ modify the grant entry until GTF_transfer_completed is 18450c88402SJoao Martins * set by Xen. 18550c88402SJoao Martins * GTF_transfer_completed: It is safe for the guest to spin-wait on this flag 18650c88402SJoao Martins * after reading GTF_transfer_committed. Xen will always write the frame 18750c88402SJoao Martins * address, followed by ORing this flag, in a timely manner. 18850c88402SJoao Martins */ 18950c88402SJoao Martins #define _GTF_transfer_committed (2) 19050c88402SJoao Martins #define GTF_transfer_committed (1U<<_GTF_transfer_committed) 19150c88402SJoao Martins #define _GTF_transfer_completed (3) 19250c88402SJoao Martins #define GTF_transfer_completed (1U<<_GTF_transfer_completed) 19350c88402SJoao Martins 19450c88402SJoao Martins /* 19550c88402SJoao Martins * Version 2 grant table entries. These fulfil the same role as 19650c88402SJoao Martins * version 1 entries, but can represent more complicated operations. 19750c88402SJoao Martins * Any given domain will have either a version 1 or a version 2 table, 19850c88402SJoao Martins * and every entry in the table will be the same version. 19950c88402SJoao Martins * 20050c88402SJoao Martins * The interface by which domains use grant references does not depend 20150c88402SJoao Martins * on the grant table version in use by the other domain. 20250c88402SJoao Martins */ 20350c88402SJoao Martins #if __XEN_INTERFACE_VERSION__ >= 0x0003020a 20450c88402SJoao Martins /* 20550c88402SJoao Martins * Version 1 and version 2 grant entries share a common prefix. The 20650c88402SJoao Martins * fields of the prefix are documented as part of struct 20750c88402SJoao Martins * grant_entry_v1. 20850c88402SJoao Martins */ 20950c88402SJoao Martins struct grant_entry_header { 21050c88402SJoao Martins uint16_t flags; 21150c88402SJoao Martins domid_t domid; 21250c88402SJoao Martins }; 21350c88402SJoao Martins typedef struct grant_entry_header grant_entry_header_t; 21450c88402SJoao Martins 21550c88402SJoao Martins /* 21650c88402SJoao Martins * Version 2 of the grant entry structure. 21750c88402SJoao Martins */ 21850c88402SJoao Martins union grant_entry_v2 { 21950c88402SJoao Martins grant_entry_header_t hdr; 22050c88402SJoao Martins 22150c88402SJoao Martins /* 22250c88402SJoao Martins * This member is used for V1-style full page grants, where either: 22350c88402SJoao Martins * 22450c88402SJoao Martins * -- hdr.type is GTF_accept_transfer, or 22550c88402SJoao Martins * -- hdr.type is GTF_permit_access and GTF_sub_page is not set. 22650c88402SJoao Martins * 22750c88402SJoao Martins * In that case, the frame field has the same semantics as the 22850c88402SJoao Martins * field of the same name in the V1 entry structure. 22950c88402SJoao Martins */ 23050c88402SJoao Martins struct { 23150c88402SJoao Martins grant_entry_header_t hdr; 23250c88402SJoao Martins uint32_t pad0; 23350c88402SJoao Martins uint64_t frame; 23450c88402SJoao Martins } full_page; 23550c88402SJoao Martins 23650c88402SJoao Martins /* 23750c88402SJoao Martins * If the grant type is GTF_grant_access and GTF_sub_page is set, 23850c88402SJoao Martins * @domid is allowed to access bytes [@page_off,@page_off+@length) 23950c88402SJoao Martins * in frame @frame. 24050c88402SJoao Martins */ 24150c88402SJoao Martins struct { 24250c88402SJoao Martins grant_entry_header_t hdr; 24350c88402SJoao Martins uint16_t page_off; 24450c88402SJoao Martins uint16_t length; 24550c88402SJoao Martins uint64_t frame; 24650c88402SJoao Martins } sub_page; 24750c88402SJoao Martins 24850c88402SJoao Martins /* 24950c88402SJoao Martins * If the grant is GTF_transitive, @domid is allowed to use the 25050c88402SJoao Martins * grant @gref in domain @trans_domid, as if it was the local 25150c88402SJoao Martins * domain. Obviously, the transitive access must be compatible 25250c88402SJoao Martins * with the original grant. 25350c88402SJoao Martins * 25450c88402SJoao Martins * The current version of Xen does not allow transitive grants 25550c88402SJoao Martins * to be mapped. 25650c88402SJoao Martins */ 25750c88402SJoao Martins struct { 25850c88402SJoao Martins grant_entry_header_t hdr; 25950c88402SJoao Martins domid_t trans_domid; 26050c88402SJoao Martins uint16_t pad0; 26150c88402SJoao Martins grant_ref_t gref; 26250c88402SJoao Martins } transitive; 26350c88402SJoao Martins 26450c88402SJoao Martins uint32_t __spacer[4]; /* Pad to a power of two */ 26550c88402SJoao Martins }; 26650c88402SJoao Martins typedef union grant_entry_v2 grant_entry_v2_t; 26750c88402SJoao Martins 26850c88402SJoao Martins typedef uint16_t grant_status_t; 26950c88402SJoao Martins 27050c88402SJoao Martins #endif /* __XEN_INTERFACE_VERSION__ */ 27150c88402SJoao Martins 27250c88402SJoao Martins /*********************************** 27350c88402SJoao Martins * GRANT TABLE QUERIES AND USES 27450c88402SJoao Martins */ 27550c88402SJoao Martins 27650c88402SJoao Martins /* ` enum neg_errnoval 27750c88402SJoao Martins * ` HYPERVISOR_grant_table_op(enum grant_table_op cmd, 27850c88402SJoao Martins * ` void *args, 27950c88402SJoao Martins * ` unsigned int count) 28050c88402SJoao Martins * ` 28150c88402SJoao Martins * 28250c88402SJoao Martins * @args points to an array of a per-command data structure. The array 28350c88402SJoao Martins * has @count members 28450c88402SJoao Martins */ 28550c88402SJoao Martins 28650c88402SJoao Martins /* ` enum grant_table_op { // GNTTABOP_* => struct gnttab_* */ 28750c88402SJoao Martins #define GNTTABOP_map_grant_ref 0 28850c88402SJoao Martins #define GNTTABOP_unmap_grant_ref 1 28950c88402SJoao Martins #define GNTTABOP_setup_table 2 29050c88402SJoao Martins #define GNTTABOP_dump_table 3 29150c88402SJoao Martins #define GNTTABOP_transfer 4 29250c88402SJoao Martins #define GNTTABOP_copy 5 29350c88402SJoao Martins #define GNTTABOP_query_size 6 29450c88402SJoao Martins #define GNTTABOP_unmap_and_replace 7 29550c88402SJoao Martins #if __XEN_INTERFACE_VERSION__ >= 0x0003020a 29650c88402SJoao Martins #define GNTTABOP_set_version 8 29750c88402SJoao Martins #define GNTTABOP_get_status_frames 9 29850c88402SJoao Martins #define GNTTABOP_get_version 10 29950c88402SJoao Martins #define GNTTABOP_swap_grant_ref 11 30050c88402SJoao Martins #define GNTTABOP_cache_flush 12 30150c88402SJoao Martins #endif /* __XEN_INTERFACE_VERSION__ */ 30250c88402SJoao Martins /* ` } */ 30350c88402SJoao Martins 30450c88402SJoao Martins /* 30550c88402SJoao Martins * Handle to track a mapping created via a grant reference. 30650c88402SJoao Martins */ 30750c88402SJoao Martins typedef uint32_t grant_handle_t; 30850c88402SJoao Martins 30950c88402SJoao Martins /* 31050c88402SJoao Martins * GNTTABOP_map_grant_ref: Map the grant entry (<dom>,<ref>) for access 31150c88402SJoao Martins * by devices and/or host CPUs. If successful, <handle> is a tracking number 31250c88402SJoao Martins * that must be presented later to destroy the mapping(s). On error, <status> 31350c88402SJoao Martins * is a negative status code. 31450c88402SJoao Martins * NOTES: 31550c88402SJoao Martins * 1. If GNTMAP_device_map is specified then <dev_bus_addr> is the address 31650c88402SJoao Martins * via which I/O devices may access the granted frame. 31750c88402SJoao Martins * 2. If GNTMAP_host_map is specified then a mapping will be added at 31850c88402SJoao Martins * either a host virtual address in the current address space, or at 31950c88402SJoao Martins * a PTE at the specified machine address. The type of mapping to 32050c88402SJoao Martins * perform is selected through the GNTMAP_contains_pte flag, and the 32150c88402SJoao Martins * address is specified in <host_addr>. 32250c88402SJoao Martins * 3. Mappings should only be destroyed via GNTTABOP_unmap_grant_ref. If a 32350c88402SJoao Martins * host mapping is destroyed by other means then it is *NOT* guaranteed 32450c88402SJoao Martins * to be accounted to the correct grant reference! 32550c88402SJoao Martins */ 32650c88402SJoao Martins struct gnttab_map_grant_ref { 32750c88402SJoao Martins /* IN parameters. */ 32850c88402SJoao Martins uint64_t host_addr; 32950c88402SJoao Martins uint32_t flags; /* GNTMAP_* */ 33050c88402SJoao Martins grant_ref_t ref; 33150c88402SJoao Martins domid_t dom; 33250c88402SJoao Martins /* OUT parameters. */ 33350c88402SJoao Martins int16_t status; /* => enum grant_status */ 33450c88402SJoao Martins grant_handle_t handle; 33550c88402SJoao Martins uint64_t dev_bus_addr; 33650c88402SJoao Martins }; 33750c88402SJoao Martins typedef struct gnttab_map_grant_ref gnttab_map_grant_ref_t; 33850c88402SJoao Martins DEFINE_XEN_GUEST_HANDLE(gnttab_map_grant_ref_t); 33950c88402SJoao Martins 34050c88402SJoao Martins /* 34150c88402SJoao Martins * GNTTABOP_unmap_grant_ref: Destroy one or more grant-reference mappings 34250c88402SJoao Martins * tracked by <handle>. If <host_addr> or <dev_bus_addr> is zero, that 34350c88402SJoao Martins * field is ignored. If non-zero, they must refer to a device/host mapping 34450c88402SJoao Martins * that is tracked by <handle> 34550c88402SJoao Martins * NOTES: 34650c88402SJoao Martins * 1. The call may fail in an undefined manner if either mapping is not 34750c88402SJoao Martins * tracked by <handle>. 34850c88402SJoao Martins * 3. After executing a batch of unmaps, it is guaranteed that no stale 34950c88402SJoao Martins * mappings will remain in the device or host TLBs. 35050c88402SJoao Martins */ 35150c88402SJoao Martins struct gnttab_unmap_grant_ref { 35250c88402SJoao Martins /* IN parameters. */ 35350c88402SJoao Martins uint64_t host_addr; 35450c88402SJoao Martins uint64_t dev_bus_addr; 35550c88402SJoao Martins grant_handle_t handle; 35650c88402SJoao Martins /* OUT parameters. */ 35750c88402SJoao Martins int16_t status; /* => enum grant_status */ 35850c88402SJoao Martins }; 35950c88402SJoao Martins typedef struct gnttab_unmap_grant_ref gnttab_unmap_grant_ref_t; 36050c88402SJoao Martins DEFINE_XEN_GUEST_HANDLE(gnttab_unmap_grant_ref_t); 36150c88402SJoao Martins 36250c88402SJoao Martins /* 36350c88402SJoao Martins * GNTTABOP_setup_table: Set up a grant table for <dom> comprising at least 36450c88402SJoao Martins * <nr_frames> pages. The frame addresses are written to the <frame_list>. 36550c88402SJoao Martins * Only <nr_frames> addresses are written, even if the table is larger. 36650c88402SJoao Martins * NOTES: 36750c88402SJoao Martins * 1. <dom> may be specified as DOMID_SELF. 36850c88402SJoao Martins * 2. Only a sufficiently-privileged domain may specify <dom> != DOMID_SELF. 36950c88402SJoao Martins * 3. Xen may not support more than a single grant-table page per domain. 37050c88402SJoao Martins */ 37150c88402SJoao Martins struct gnttab_setup_table { 37250c88402SJoao Martins /* IN parameters. */ 37350c88402SJoao Martins domid_t dom; 37450c88402SJoao Martins uint32_t nr_frames; 37550c88402SJoao Martins /* OUT parameters. */ 37650c88402SJoao Martins int16_t status; /* => enum grant_status */ 37750c88402SJoao Martins #if __XEN_INTERFACE_VERSION__ < 0x00040300 37850c88402SJoao Martins XEN_GUEST_HANDLE(ulong) frame_list; 37950c88402SJoao Martins #else 38050c88402SJoao Martins XEN_GUEST_HANDLE(xen_pfn_t) frame_list; 38150c88402SJoao Martins #endif 38250c88402SJoao Martins }; 38350c88402SJoao Martins typedef struct gnttab_setup_table gnttab_setup_table_t; 38450c88402SJoao Martins DEFINE_XEN_GUEST_HANDLE(gnttab_setup_table_t); 38550c88402SJoao Martins 38650c88402SJoao Martins /* 38750c88402SJoao Martins * GNTTABOP_dump_table: Dump the contents of the grant table to the 38850c88402SJoao Martins * xen console. Debugging use only. 38950c88402SJoao Martins */ 39050c88402SJoao Martins struct gnttab_dump_table { 39150c88402SJoao Martins /* IN parameters. */ 39250c88402SJoao Martins domid_t dom; 39350c88402SJoao Martins /* OUT parameters. */ 39450c88402SJoao Martins int16_t status; /* => enum grant_status */ 39550c88402SJoao Martins }; 39650c88402SJoao Martins typedef struct gnttab_dump_table gnttab_dump_table_t; 39750c88402SJoao Martins DEFINE_XEN_GUEST_HANDLE(gnttab_dump_table_t); 39850c88402SJoao Martins 39950c88402SJoao Martins /* 40050c88402SJoao Martins * GNTTABOP_transfer: Transfer <frame> to a foreign domain. The foreign domain 40150c88402SJoao Martins * has previously registered its interest in the transfer via <domid, ref>. 40250c88402SJoao Martins * 40350c88402SJoao Martins * Note that, even if the transfer fails, the specified page no longer belongs 40450c88402SJoao Martins * to the calling domain *unless* the error is GNTST_bad_page. 40550c88402SJoao Martins * 40650c88402SJoao Martins * Note further that only PV guests can use this operation. 40750c88402SJoao Martins */ 40850c88402SJoao Martins struct gnttab_transfer { 40950c88402SJoao Martins /* IN parameters. */ 41050c88402SJoao Martins xen_pfn_t mfn; 41150c88402SJoao Martins domid_t domid; 41250c88402SJoao Martins grant_ref_t ref; 41350c88402SJoao Martins /* OUT parameters. */ 41450c88402SJoao Martins int16_t status; 41550c88402SJoao Martins }; 41650c88402SJoao Martins typedef struct gnttab_transfer gnttab_transfer_t; 41750c88402SJoao Martins DEFINE_XEN_GUEST_HANDLE(gnttab_transfer_t); 41850c88402SJoao Martins 41950c88402SJoao Martins 42050c88402SJoao Martins /* 42150c88402SJoao Martins * GNTTABOP_copy: Hypervisor based copy 42250c88402SJoao Martins * source and destinations can be eithers MFNs or, for foreign domains, 42350c88402SJoao Martins * grant references. the foreign domain has to grant read/write access 42450c88402SJoao Martins * in its grant table. 42550c88402SJoao Martins * 42650c88402SJoao Martins * The flags specify what type source and destinations are (either MFN 42750c88402SJoao Martins * or grant reference). 42850c88402SJoao Martins * 42950c88402SJoao Martins * Note that this can also be used to copy data between two domains 43050c88402SJoao Martins * via a third party if the source and destination domains had previously 43150c88402SJoao Martins * grant appropriate access to their pages to the third party. 43250c88402SJoao Martins * 43350c88402SJoao Martins * source_offset specifies an offset in the source frame, dest_offset 43450c88402SJoao Martins * the offset in the target frame and len specifies the number of 43550c88402SJoao Martins * bytes to be copied. 43650c88402SJoao Martins */ 43750c88402SJoao Martins 43850c88402SJoao Martins #define _GNTCOPY_source_gref (0) 43950c88402SJoao Martins #define GNTCOPY_source_gref (1<<_GNTCOPY_source_gref) 44050c88402SJoao Martins #define _GNTCOPY_dest_gref (1) 44150c88402SJoao Martins #define GNTCOPY_dest_gref (1<<_GNTCOPY_dest_gref) 44250c88402SJoao Martins 44350c88402SJoao Martins struct gnttab_copy { 44450c88402SJoao Martins /* IN parameters. */ 44550c88402SJoao Martins struct gnttab_copy_ptr { 44650c88402SJoao Martins union { 44750c88402SJoao Martins grant_ref_t ref; 44850c88402SJoao Martins xen_pfn_t gmfn; 44950c88402SJoao Martins } u; 45050c88402SJoao Martins domid_t domid; 45150c88402SJoao Martins uint16_t offset; 45250c88402SJoao Martins } source, dest; 45350c88402SJoao Martins uint16_t len; 45450c88402SJoao Martins uint16_t flags; /* GNTCOPY_* */ 45550c88402SJoao Martins /* OUT parameters. */ 45650c88402SJoao Martins int16_t status; 45750c88402SJoao Martins }; 45850c88402SJoao Martins typedef struct gnttab_copy gnttab_copy_t; 45950c88402SJoao Martins DEFINE_XEN_GUEST_HANDLE(gnttab_copy_t); 46050c88402SJoao Martins 46150c88402SJoao Martins /* 46250c88402SJoao Martins * GNTTABOP_query_size: Query the current and maximum sizes of the shared 46350c88402SJoao Martins * grant table. 46450c88402SJoao Martins * NOTES: 46550c88402SJoao Martins * 1. <dom> may be specified as DOMID_SELF. 46650c88402SJoao Martins * 2. Only a sufficiently-privileged domain may specify <dom> != DOMID_SELF. 46750c88402SJoao Martins */ 46850c88402SJoao Martins struct gnttab_query_size { 46950c88402SJoao Martins /* IN parameters. */ 47050c88402SJoao Martins domid_t dom; 47150c88402SJoao Martins /* OUT parameters. */ 47250c88402SJoao Martins uint32_t nr_frames; 47350c88402SJoao Martins uint32_t max_nr_frames; 47450c88402SJoao Martins int16_t status; /* => enum grant_status */ 47550c88402SJoao Martins }; 47650c88402SJoao Martins typedef struct gnttab_query_size gnttab_query_size_t; 47750c88402SJoao Martins DEFINE_XEN_GUEST_HANDLE(gnttab_query_size_t); 47850c88402SJoao Martins 47950c88402SJoao Martins /* 48050c88402SJoao Martins * GNTTABOP_unmap_and_replace: Destroy one or more grant-reference mappings 48150c88402SJoao Martins * tracked by <handle> but atomically replace the page table entry with one 48250c88402SJoao Martins * pointing to the machine address under <new_addr>. <new_addr> will be 48350c88402SJoao Martins * redirected to the null entry. 48450c88402SJoao Martins * NOTES: 48550c88402SJoao Martins * 1. The call may fail in an undefined manner if either mapping is not 48650c88402SJoao Martins * tracked by <handle>. 48750c88402SJoao Martins * 2. After executing a batch of unmaps, it is guaranteed that no stale 48850c88402SJoao Martins * mappings will remain in the device or host TLBs. 48950c88402SJoao Martins */ 49050c88402SJoao Martins struct gnttab_unmap_and_replace { 49150c88402SJoao Martins /* IN parameters. */ 49250c88402SJoao Martins uint64_t host_addr; 49350c88402SJoao Martins uint64_t new_addr; 49450c88402SJoao Martins grant_handle_t handle; 49550c88402SJoao Martins /* OUT parameters. */ 49650c88402SJoao Martins int16_t status; /* => enum grant_status */ 49750c88402SJoao Martins }; 49850c88402SJoao Martins typedef struct gnttab_unmap_and_replace gnttab_unmap_and_replace_t; 49950c88402SJoao Martins DEFINE_XEN_GUEST_HANDLE(gnttab_unmap_and_replace_t); 50050c88402SJoao Martins 50150c88402SJoao Martins #if __XEN_INTERFACE_VERSION__ >= 0x0003020a 50250c88402SJoao Martins /* 50350c88402SJoao Martins * GNTTABOP_set_version: Request a particular version of the grant 50450c88402SJoao Martins * table shared table structure. This operation may be used to toggle 50550c88402SJoao Martins * between different versions, but must be performed while no grants 50650c88402SJoao Martins * are active. The only defined versions are 1 and 2. 50750c88402SJoao Martins */ 50850c88402SJoao Martins struct gnttab_set_version { 50950c88402SJoao Martins /* IN/OUT parameters */ 51050c88402SJoao Martins uint32_t version; 51150c88402SJoao Martins }; 51250c88402SJoao Martins typedef struct gnttab_set_version gnttab_set_version_t; 51350c88402SJoao Martins DEFINE_XEN_GUEST_HANDLE(gnttab_set_version_t); 51450c88402SJoao Martins 51550c88402SJoao Martins 51650c88402SJoao Martins /* 51750c88402SJoao Martins * GNTTABOP_get_status_frames: Get the list of frames used to store grant 51850c88402SJoao Martins * status for <dom>. In grant format version 2, the status is separated 51950c88402SJoao Martins * from the other shared grant fields to allow more efficient synchronization 52050c88402SJoao Martins * using barriers instead of atomic cmpexch operations. 52150c88402SJoao Martins * <nr_frames> specify the size of vector <frame_list>. 52250c88402SJoao Martins * The frame addresses are returned in the <frame_list>. 52350c88402SJoao Martins * Only <nr_frames> addresses are returned, even if the table is larger. 52450c88402SJoao Martins * NOTES: 52550c88402SJoao Martins * 1. <dom> may be specified as DOMID_SELF. 52650c88402SJoao Martins * 2. Only a sufficiently-privileged domain may specify <dom> != DOMID_SELF. 52750c88402SJoao Martins */ 52850c88402SJoao Martins struct gnttab_get_status_frames { 52950c88402SJoao Martins /* IN parameters. */ 53050c88402SJoao Martins uint32_t nr_frames; 53150c88402SJoao Martins domid_t dom; 53250c88402SJoao Martins /* OUT parameters. */ 53350c88402SJoao Martins int16_t status; /* => enum grant_status */ 53450c88402SJoao Martins XEN_GUEST_HANDLE(uint64_t) frame_list; 53550c88402SJoao Martins }; 53650c88402SJoao Martins typedef struct gnttab_get_status_frames gnttab_get_status_frames_t; 53750c88402SJoao Martins DEFINE_XEN_GUEST_HANDLE(gnttab_get_status_frames_t); 53850c88402SJoao Martins 53950c88402SJoao Martins /* 54050c88402SJoao Martins * GNTTABOP_get_version: Get the grant table version which is in 54150c88402SJoao Martins * effect for domain <dom>. 54250c88402SJoao Martins */ 54350c88402SJoao Martins struct gnttab_get_version { 54450c88402SJoao Martins /* IN parameters */ 54550c88402SJoao Martins domid_t dom; 54650c88402SJoao Martins uint16_t pad; 54750c88402SJoao Martins /* OUT parameters */ 54850c88402SJoao Martins uint32_t version; 54950c88402SJoao Martins }; 55050c88402SJoao Martins typedef struct gnttab_get_version gnttab_get_version_t; 55150c88402SJoao Martins DEFINE_XEN_GUEST_HANDLE(gnttab_get_version_t); 55250c88402SJoao Martins 55350c88402SJoao Martins /* 55450c88402SJoao Martins * GNTTABOP_swap_grant_ref: Swap the contents of two grant entries. 55550c88402SJoao Martins */ 55650c88402SJoao Martins struct gnttab_swap_grant_ref { 55750c88402SJoao Martins /* IN parameters */ 55850c88402SJoao Martins grant_ref_t ref_a; 55950c88402SJoao Martins grant_ref_t ref_b; 56050c88402SJoao Martins /* OUT parameters */ 56150c88402SJoao Martins int16_t status; /* => enum grant_status */ 56250c88402SJoao Martins }; 56350c88402SJoao Martins typedef struct gnttab_swap_grant_ref gnttab_swap_grant_ref_t; 56450c88402SJoao Martins DEFINE_XEN_GUEST_HANDLE(gnttab_swap_grant_ref_t); 56550c88402SJoao Martins 56650c88402SJoao Martins /* 56750c88402SJoao Martins * Issue one or more cache maintenance operations on a portion of a 56850c88402SJoao Martins * page granted to the calling domain by a foreign domain. 56950c88402SJoao Martins */ 57050c88402SJoao Martins struct gnttab_cache_flush { 57150c88402SJoao Martins union { 57250c88402SJoao Martins uint64_t dev_bus_addr; 57350c88402SJoao Martins grant_ref_t ref; 57450c88402SJoao Martins } a; 57550c88402SJoao Martins uint16_t offset; /* offset from start of grant */ 57650c88402SJoao Martins uint16_t length; /* size within the grant */ 57750c88402SJoao Martins #define GNTTAB_CACHE_CLEAN (1u<<0) 57850c88402SJoao Martins #define GNTTAB_CACHE_INVAL (1u<<1) 57950c88402SJoao Martins #define GNTTAB_CACHE_SOURCE_GREF (1u<<31) 58050c88402SJoao Martins uint32_t op; 58150c88402SJoao Martins }; 58250c88402SJoao Martins typedef struct gnttab_cache_flush gnttab_cache_flush_t; 58350c88402SJoao Martins DEFINE_XEN_GUEST_HANDLE(gnttab_cache_flush_t); 58450c88402SJoao Martins 58550c88402SJoao Martins #endif /* __XEN_INTERFACE_VERSION__ */ 58650c88402SJoao Martins 58750c88402SJoao Martins /* 58850c88402SJoao Martins * Bitfield values for gnttab_map_grant_ref.flags. 58950c88402SJoao Martins */ 59050c88402SJoao Martins /* Map the grant entry for access by I/O devices. */ 59150c88402SJoao Martins #define _GNTMAP_device_map (0) 59250c88402SJoao Martins #define GNTMAP_device_map (1<<_GNTMAP_device_map) 59350c88402SJoao Martins /* Map the grant entry for access by host CPUs. */ 59450c88402SJoao Martins #define _GNTMAP_host_map (1) 59550c88402SJoao Martins #define GNTMAP_host_map (1<<_GNTMAP_host_map) 59650c88402SJoao Martins /* Accesses to the granted frame will be restricted to read-only access. */ 59750c88402SJoao Martins #define _GNTMAP_readonly (2) 59850c88402SJoao Martins #define GNTMAP_readonly (1<<_GNTMAP_readonly) 59950c88402SJoao Martins /* 60050c88402SJoao Martins * GNTMAP_host_map subflag: 60150c88402SJoao Martins * 0 => The host mapping is usable only by the guest OS. 60250c88402SJoao Martins * 1 => The host mapping is usable by guest OS + current application. 60350c88402SJoao Martins */ 60450c88402SJoao Martins #define _GNTMAP_application_map (3) 60550c88402SJoao Martins #define GNTMAP_application_map (1<<_GNTMAP_application_map) 60650c88402SJoao Martins 60750c88402SJoao Martins /* 60850c88402SJoao Martins * GNTMAP_contains_pte subflag: 60950c88402SJoao Martins * 0 => This map request contains a host virtual address. 61050c88402SJoao Martins * 1 => This map request contains the machine addess of the PTE to update. 61150c88402SJoao Martins */ 61250c88402SJoao Martins #define _GNTMAP_contains_pte (4) 61350c88402SJoao Martins #define GNTMAP_contains_pte (1<<_GNTMAP_contains_pte) 61450c88402SJoao Martins 61550c88402SJoao Martins /* 61650c88402SJoao Martins * Bits to be placed in guest kernel available PTE bits (architecture 61750c88402SJoao Martins * dependent; only supported when XENFEAT_gnttab_map_avail_bits is set). 61850c88402SJoao Martins */ 61950c88402SJoao Martins #define _GNTMAP_guest_avail0 (16) 62050c88402SJoao Martins #define GNTMAP_guest_avail_mask ((uint32_t)~0 << _GNTMAP_guest_avail0) 62150c88402SJoao Martins 62250c88402SJoao Martins /* 62350c88402SJoao Martins * Values for error status returns. All errors are -ve. 62450c88402SJoao Martins */ 62550c88402SJoao Martins /* ` enum grant_status { */ 62650c88402SJoao Martins #define GNTST_okay (0) /* Normal return. */ 62750c88402SJoao Martins #define GNTST_general_error (-1) /* General undefined error. */ 62850c88402SJoao Martins #define GNTST_bad_domain (-2) /* Unrecognsed domain id. */ 62950c88402SJoao Martins #define GNTST_bad_gntref (-3) /* Unrecognised or inappropriate gntref. */ 63050c88402SJoao Martins #define GNTST_bad_handle (-4) /* Unrecognised or inappropriate handle. */ 63150c88402SJoao Martins #define GNTST_bad_virt_addr (-5) /* Inappropriate virtual address to map. */ 63250c88402SJoao Martins #define GNTST_bad_dev_addr (-6) /* Inappropriate device address to unmap.*/ 63350c88402SJoao Martins #define GNTST_no_device_space (-7) /* Out of space in I/O MMU. */ 63450c88402SJoao Martins #define GNTST_permission_denied (-8) /* Not enough privilege for operation. */ 63550c88402SJoao Martins #define GNTST_bad_page (-9) /* Specified page was invalid for op. */ 63650c88402SJoao Martins #define GNTST_bad_copy_arg (-10) /* copy arguments cross page boundary. */ 63750c88402SJoao Martins #define GNTST_address_too_big (-11) /* transfer page address too large. */ 63850c88402SJoao Martins #define GNTST_eagain (-12) /* Operation not done; try again. */ 63950c88402SJoao Martins #define GNTST_no_space (-13) /* Out of space (handles etc). */ 64050c88402SJoao Martins /* ` } */ 64150c88402SJoao Martins 64250c88402SJoao Martins #define GNTTABOP_error_msgs { \ 64350c88402SJoao Martins "okay", \ 64450c88402SJoao Martins "undefined error", \ 64550c88402SJoao Martins "unrecognised domain id", \ 64650c88402SJoao Martins "invalid grant reference", \ 64750c88402SJoao Martins "invalid mapping handle", \ 64850c88402SJoao Martins "invalid virtual address", \ 64950c88402SJoao Martins "invalid device address", \ 65050c88402SJoao Martins "no spare translation slot in the I/O MMU", \ 65150c88402SJoao Martins "permission denied", \ 65250c88402SJoao Martins "bad page", \ 65350c88402SJoao Martins "copy arguments cross page boundary", \ 65450c88402SJoao Martins "page address size too large", \ 65550c88402SJoao Martins "operation not done; try again", \ 65650c88402SJoao Martins "out of space", \ 65750c88402SJoao Martins } 65850c88402SJoao Martins 659a3434a2dSAnthony PERARD #endif /* __XEN_PUBLIC_GRANT_TABLE_H__ */ 66050c88402SJoao Martins 66150c88402SJoao Martins /* 66250c88402SJoao Martins * Local variables: 66350c88402SJoao Martins * mode: C 66450c88402SJoao Martins * c-file-style: "BSD" 66550c88402SJoao Martins * c-basic-offset: 4 66650c88402SJoao Martins * tab-width: 4 66750c88402SJoao Martins * indent-tabs-mode: nil 66850c88402SJoao Martins * End: 66950c88402SJoao Martins */ 670