1*4882a593Smuzhiyun /****************************************************************************** 2*4882a593Smuzhiyun * grant_table.h 3*4882a593Smuzhiyun * 4*4882a593Smuzhiyun * Interface for granting foreign access to page frames, and receiving 5*4882a593Smuzhiyun * page-ownership transfers. 6*4882a593Smuzhiyun * 7*4882a593Smuzhiyun * Permission is hereby granted, free of charge, to any person obtaining a copy 8*4882a593Smuzhiyun * of this software and associated documentation files (the "Software"), to 9*4882a593Smuzhiyun * deal in the Software without restriction, including without limitation the 10*4882a593Smuzhiyun * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 11*4882a593Smuzhiyun * sell copies of the Software, and to permit persons to whom the Software is 12*4882a593Smuzhiyun * furnished to do so, subject to the following conditions: 13*4882a593Smuzhiyun * 14*4882a593Smuzhiyun * The above copyright notice and this permission notice shall be included in 15*4882a593Smuzhiyun * all copies or substantial portions of the Software. 16*4882a593Smuzhiyun * 17*4882a593Smuzhiyun * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18*4882a593Smuzhiyun * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19*4882a593Smuzhiyun * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20*4882a593Smuzhiyun * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21*4882a593Smuzhiyun * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22*4882a593Smuzhiyun * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 23*4882a593Smuzhiyun * DEALINGS IN THE SOFTWARE. 24*4882a593Smuzhiyun * 25*4882a593Smuzhiyun * Copyright (c) 2004, K A Fraser 26*4882a593Smuzhiyun */ 27*4882a593Smuzhiyun 28*4882a593Smuzhiyun #ifndef __XEN_PUBLIC_GRANT_TABLE_H__ 29*4882a593Smuzhiyun #define __XEN_PUBLIC_GRANT_TABLE_H__ 30*4882a593Smuzhiyun 31*4882a593Smuzhiyun #include <xen/interface/xen.h> 32*4882a593Smuzhiyun 33*4882a593Smuzhiyun /*********************************** 34*4882a593Smuzhiyun * GRANT TABLE REPRESENTATION 35*4882a593Smuzhiyun */ 36*4882a593Smuzhiyun 37*4882a593Smuzhiyun /* Some rough guidelines on accessing and updating grant-table entries 38*4882a593Smuzhiyun * in a concurrency-safe manner. For more information, Linux contains a 39*4882a593Smuzhiyun * reference implementation for guest OSes (arch/xen/kernel/grant_table.c). 40*4882a593Smuzhiyun * 41*4882a593Smuzhiyun * NB. WMB is a no-op on current-generation x86 processors. However, a 42*4882a593Smuzhiyun * compiler barrier will still be required. 43*4882a593Smuzhiyun * 44*4882a593Smuzhiyun * Introducing a valid entry into the grant table: 45*4882a593Smuzhiyun * 1. Write ent->domid. 46*4882a593Smuzhiyun * 2. Write ent->frame: 47*4882a593Smuzhiyun * GTF_permit_access: Frame to which access is permitted. 48*4882a593Smuzhiyun * GTF_accept_transfer: Pseudo-phys frame slot being filled by new 49*4882a593Smuzhiyun * frame, or zero if none. 50*4882a593Smuzhiyun * 3. Write memory barrier (WMB). 51*4882a593Smuzhiyun * 4. Write ent->flags, inc. valid type. 52*4882a593Smuzhiyun * 53*4882a593Smuzhiyun * Invalidating an unused GTF_permit_access entry: 54*4882a593Smuzhiyun * 1. flags = ent->flags. 55*4882a593Smuzhiyun * 2. Observe that !(flags & (GTF_reading|GTF_writing)). 56*4882a593Smuzhiyun * 3. Check result of SMP-safe CMPXCHG(&ent->flags, flags, 0). 57*4882a593Smuzhiyun * NB. No need for WMB as reuse of entry is control-dependent on success of 58*4882a593Smuzhiyun * step 3, and all architectures guarantee ordering of ctrl-dep writes. 59*4882a593Smuzhiyun * 60*4882a593Smuzhiyun * Invalidating an in-use GTF_permit_access entry: 61*4882a593Smuzhiyun * This cannot be done directly. Request assistance from the domain controller 62*4882a593Smuzhiyun * which can set a timeout on the use of a grant entry and take necessary 63*4882a593Smuzhiyun * action. (NB. This is not yet implemented!). 64*4882a593Smuzhiyun * 65*4882a593Smuzhiyun * Invalidating an unused GTF_accept_transfer entry: 66*4882a593Smuzhiyun * 1. flags = ent->flags. 67*4882a593Smuzhiyun * 2. Observe that !(flags & GTF_transfer_committed). [*] 68*4882a593Smuzhiyun * 3. Check result of SMP-safe CMPXCHG(&ent->flags, flags, 0). 69*4882a593Smuzhiyun * NB. No need for WMB as reuse of entry is control-dependent on success of 70*4882a593Smuzhiyun * step 3, and all architectures guarantee ordering of ctrl-dep writes. 71*4882a593Smuzhiyun * [*] If GTF_transfer_committed is set then the grant entry is 'committed'. 72*4882a593Smuzhiyun * The guest must /not/ modify the grant entry until the address of the 73*4882a593Smuzhiyun * transferred frame is written. It is safe for the guest to spin waiting 74*4882a593Smuzhiyun * for this to occur (detect by observing GTF_transfer_completed in 75*4882a593Smuzhiyun * ent->flags). 76*4882a593Smuzhiyun * 77*4882a593Smuzhiyun * Invalidating a committed GTF_accept_transfer entry: 78*4882a593Smuzhiyun * 1. Wait for (ent->flags & GTF_transfer_completed). 79*4882a593Smuzhiyun * 80*4882a593Smuzhiyun * Changing a GTF_permit_access from writable to read-only: 81*4882a593Smuzhiyun * Use SMP-safe CMPXCHG to set GTF_readonly, while checking !GTF_writing. 82*4882a593Smuzhiyun * 83*4882a593Smuzhiyun * Changing a GTF_permit_access from read-only to writable: 84*4882a593Smuzhiyun * Use SMP-safe bit-setting instruction. 85*4882a593Smuzhiyun */ 86*4882a593Smuzhiyun 87*4882a593Smuzhiyun /* 88*4882a593Smuzhiyun * Reference to a grant entry in a specified domain's grant table. 89*4882a593Smuzhiyun */ 90*4882a593Smuzhiyun typedef uint32_t grant_ref_t; 91*4882a593Smuzhiyun 92*4882a593Smuzhiyun /* 93*4882a593Smuzhiyun * A grant table comprises a packed array of grant entries in one or more 94*4882a593Smuzhiyun * page frames shared between Xen and a guest. 95*4882a593Smuzhiyun * [XEN]: This field is written by Xen and read by the sharing guest. 96*4882a593Smuzhiyun * [GST]: This field is written by the guest and read by Xen. 97*4882a593Smuzhiyun */ 98*4882a593Smuzhiyun 99*4882a593Smuzhiyun /* 100*4882a593Smuzhiyun * Version 1 of the grant table entry structure is maintained purely 101*4882a593Smuzhiyun * for backwards compatibility. New guests should use version 2. 102*4882a593Smuzhiyun */ 103*4882a593Smuzhiyun struct grant_entry_v1 { 104*4882a593Smuzhiyun /* GTF_xxx: various type and flag information. [XEN,GST] */ 105*4882a593Smuzhiyun uint16_t flags; 106*4882a593Smuzhiyun /* The domain being granted foreign privileges. [GST] */ 107*4882a593Smuzhiyun domid_t domid; 108*4882a593Smuzhiyun /* 109*4882a593Smuzhiyun * GTF_permit_access: Frame that @domid is allowed to map and access. [GST] 110*4882a593Smuzhiyun * GTF_accept_transfer: Frame whose ownership transferred by @domid. [XEN] 111*4882a593Smuzhiyun */ 112*4882a593Smuzhiyun uint32_t frame; 113*4882a593Smuzhiyun }; 114*4882a593Smuzhiyun 115*4882a593Smuzhiyun /* 116*4882a593Smuzhiyun * Type of grant entry. 117*4882a593Smuzhiyun * GTF_invalid: This grant entry grants no privileges. 118*4882a593Smuzhiyun * GTF_permit_access: Allow @domid to map/access @frame. 119*4882a593Smuzhiyun * GTF_accept_transfer: Allow @domid to transfer ownership of one page frame 120*4882a593Smuzhiyun * to this guest. Xen writes the page number to @frame. 121*4882a593Smuzhiyun * GTF_transitive: Allow @domid to transitively access a subrange of 122*4882a593Smuzhiyun * @trans_grant in @trans_domid. No mappings are allowed. 123*4882a593Smuzhiyun */ 124*4882a593Smuzhiyun #define GTF_invalid (0U<<0) 125*4882a593Smuzhiyun #define GTF_permit_access (1U<<0) 126*4882a593Smuzhiyun #define GTF_accept_transfer (2U<<0) 127*4882a593Smuzhiyun #define GTF_transitive (3U<<0) 128*4882a593Smuzhiyun #define GTF_type_mask (3U<<0) 129*4882a593Smuzhiyun 130*4882a593Smuzhiyun /* 131*4882a593Smuzhiyun * Subflags for GTF_permit_access. 132*4882a593Smuzhiyun * GTF_readonly: Restrict @domid to read-only mappings and accesses. [GST] 133*4882a593Smuzhiyun * GTF_reading: Grant entry is currently mapped for reading by @domid. [XEN] 134*4882a593Smuzhiyun * GTF_writing: Grant entry is currently mapped for writing by @domid. [XEN] 135*4882a593Smuzhiyun * GTF_sub_page: Grant access to only a subrange of the page. @domid 136*4882a593Smuzhiyun * will only be allowed to copy from the grant, and not 137*4882a593Smuzhiyun * map it. [GST] 138*4882a593Smuzhiyun */ 139*4882a593Smuzhiyun #define _GTF_readonly (2) 140*4882a593Smuzhiyun #define GTF_readonly (1U<<_GTF_readonly) 141*4882a593Smuzhiyun #define _GTF_reading (3) 142*4882a593Smuzhiyun #define GTF_reading (1U<<_GTF_reading) 143*4882a593Smuzhiyun #define _GTF_writing (4) 144*4882a593Smuzhiyun #define GTF_writing (1U<<_GTF_writing) 145*4882a593Smuzhiyun #define _GTF_sub_page (8) 146*4882a593Smuzhiyun #define GTF_sub_page (1U<<_GTF_sub_page) 147*4882a593Smuzhiyun 148*4882a593Smuzhiyun /* 149*4882a593Smuzhiyun * Subflags for GTF_accept_transfer: 150*4882a593Smuzhiyun * GTF_transfer_committed: Xen sets this flag to indicate that it is committed 151*4882a593Smuzhiyun * to transferring ownership of a page frame. When a guest sees this flag 152*4882a593Smuzhiyun * it must /not/ modify the grant entry until GTF_transfer_completed is 153*4882a593Smuzhiyun * set by Xen. 154*4882a593Smuzhiyun * GTF_transfer_completed: It is safe for the guest to spin-wait on this flag 155*4882a593Smuzhiyun * after reading GTF_transfer_committed. Xen will always write the frame 156*4882a593Smuzhiyun * address, followed by ORing this flag, in a timely manner. 157*4882a593Smuzhiyun */ 158*4882a593Smuzhiyun #define _GTF_transfer_committed (2) 159*4882a593Smuzhiyun #define GTF_transfer_committed (1U<<_GTF_transfer_committed) 160*4882a593Smuzhiyun #define _GTF_transfer_completed (3) 161*4882a593Smuzhiyun #define GTF_transfer_completed (1U<<_GTF_transfer_completed) 162*4882a593Smuzhiyun 163*4882a593Smuzhiyun /* 164*4882a593Smuzhiyun * Version 2 grant table entries. These fulfil the same role as 165*4882a593Smuzhiyun * version 1 entries, but can represent more complicated operations. 166*4882a593Smuzhiyun * Any given domain will have either a version 1 or a version 2 table, 167*4882a593Smuzhiyun * and every entry in the table will be the same version. 168*4882a593Smuzhiyun * 169*4882a593Smuzhiyun * The interface by which domains use grant references does not depend 170*4882a593Smuzhiyun * on the grant table version in use by the other domain. 171*4882a593Smuzhiyun */ 172*4882a593Smuzhiyun 173*4882a593Smuzhiyun /* 174*4882a593Smuzhiyun * Version 1 and version 2 grant entries share a common prefix. The 175*4882a593Smuzhiyun * fields of the prefix are documented as part of struct 176*4882a593Smuzhiyun * grant_entry_v1. 177*4882a593Smuzhiyun */ 178*4882a593Smuzhiyun struct grant_entry_header { 179*4882a593Smuzhiyun uint16_t flags; 180*4882a593Smuzhiyun domid_t domid; 181*4882a593Smuzhiyun }; 182*4882a593Smuzhiyun 183*4882a593Smuzhiyun /* 184*4882a593Smuzhiyun * Version 2 of the grant entry structure, here is a union because three 185*4882a593Smuzhiyun * different types are suppotted: full_page, sub_page and transitive. 186*4882a593Smuzhiyun */ 187*4882a593Smuzhiyun union grant_entry_v2 { 188*4882a593Smuzhiyun struct grant_entry_header hdr; 189*4882a593Smuzhiyun 190*4882a593Smuzhiyun /* 191*4882a593Smuzhiyun * This member is used for V1-style full page grants, where either: 192*4882a593Smuzhiyun * 193*4882a593Smuzhiyun * -- hdr.type is GTF_accept_transfer, or 194*4882a593Smuzhiyun * -- hdr.type is GTF_permit_access and GTF_sub_page is not set. 195*4882a593Smuzhiyun * 196*4882a593Smuzhiyun * In that case, the frame field has the same semantics as the 197*4882a593Smuzhiyun * field of the same name in the V1 entry structure. 198*4882a593Smuzhiyun */ 199*4882a593Smuzhiyun struct { 200*4882a593Smuzhiyun struct grant_entry_header hdr; 201*4882a593Smuzhiyun uint32_t pad0; 202*4882a593Smuzhiyun uint64_t frame; 203*4882a593Smuzhiyun } full_page; 204*4882a593Smuzhiyun 205*4882a593Smuzhiyun /* 206*4882a593Smuzhiyun * If the grant type is GTF_grant_access and GTF_sub_page is set, 207*4882a593Smuzhiyun * @domid is allowed to access bytes [@page_off,@page_off+@length) 208*4882a593Smuzhiyun * in frame @frame. 209*4882a593Smuzhiyun */ 210*4882a593Smuzhiyun struct { 211*4882a593Smuzhiyun struct grant_entry_header hdr; 212*4882a593Smuzhiyun uint16_t page_off; 213*4882a593Smuzhiyun uint16_t length; 214*4882a593Smuzhiyun uint64_t frame; 215*4882a593Smuzhiyun } sub_page; 216*4882a593Smuzhiyun 217*4882a593Smuzhiyun /* 218*4882a593Smuzhiyun * If the grant is GTF_transitive, @domid is allowed to use the 219*4882a593Smuzhiyun * grant @gref in domain @trans_domid, as if it was the local 220*4882a593Smuzhiyun * domain. Obviously, the transitive access must be compatible 221*4882a593Smuzhiyun * with the original grant. 222*4882a593Smuzhiyun */ 223*4882a593Smuzhiyun struct { 224*4882a593Smuzhiyun struct grant_entry_header hdr; 225*4882a593Smuzhiyun domid_t trans_domid; 226*4882a593Smuzhiyun uint16_t pad0; 227*4882a593Smuzhiyun grant_ref_t gref; 228*4882a593Smuzhiyun } transitive; 229*4882a593Smuzhiyun 230*4882a593Smuzhiyun uint32_t __spacer[4]; /* Pad to a power of two */ 231*4882a593Smuzhiyun }; 232*4882a593Smuzhiyun 233*4882a593Smuzhiyun typedef uint16_t grant_status_t; 234*4882a593Smuzhiyun 235*4882a593Smuzhiyun /*********************************** 236*4882a593Smuzhiyun * GRANT TABLE QUERIES AND USES 237*4882a593Smuzhiyun */ 238*4882a593Smuzhiyun 239*4882a593Smuzhiyun /* 240*4882a593Smuzhiyun * Handle to track a mapping created via a grant reference. 241*4882a593Smuzhiyun */ 242*4882a593Smuzhiyun typedef uint32_t grant_handle_t; 243*4882a593Smuzhiyun 244*4882a593Smuzhiyun /* 245*4882a593Smuzhiyun * GNTTABOP_map_grant_ref: Map the grant entry (<dom>,<ref>) for access 246*4882a593Smuzhiyun * by devices and/or host CPUs. If successful, <handle> is a tracking number 247*4882a593Smuzhiyun * that must be presented later to destroy the mapping(s). On error, <handle> 248*4882a593Smuzhiyun * is a negative status code. 249*4882a593Smuzhiyun * NOTES: 250*4882a593Smuzhiyun * 1. If GNTMAP_device_map is specified then <dev_bus_addr> is the address 251*4882a593Smuzhiyun * via which I/O devices may access the granted frame. 252*4882a593Smuzhiyun * 2. If GNTMAP_host_map is specified then a mapping will be added at 253*4882a593Smuzhiyun * either a host virtual address in the current address space, or at 254*4882a593Smuzhiyun * a PTE at the specified machine address. The type of mapping to 255*4882a593Smuzhiyun * perform is selected through the GNTMAP_contains_pte flag, and the 256*4882a593Smuzhiyun * address is specified in <host_addr>. 257*4882a593Smuzhiyun * 3. Mappings should only be destroyed via GNTTABOP_unmap_grant_ref. If a 258*4882a593Smuzhiyun * host mapping is destroyed by other means then it is *NOT* guaranteed 259*4882a593Smuzhiyun * to be accounted to the correct grant reference! 260*4882a593Smuzhiyun */ 261*4882a593Smuzhiyun #define GNTTABOP_map_grant_ref 0 262*4882a593Smuzhiyun struct gnttab_map_grant_ref { 263*4882a593Smuzhiyun /* IN parameters. */ 264*4882a593Smuzhiyun uint64_t host_addr; 265*4882a593Smuzhiyun uint32_t flags; /* GNTMAP_* */ 266*4882a593Smuzhiyun grant_ref_t ref; 267*4882a593Smuzhiyun domid_t dom; 268*4882a593Smuzhiyun /* OUT parameters. */ 269*4882a593Smuzhiyun int16_t status; /* GNTST_* */ 270*4882a593Smuzhiyun grant_handle_t handle; 271*4882a593Smuzhiyun uint64_t dev_bus_addr; 272*4882a593Smuzhiyun }; 273*4882a593Smuzhiyun DEFINE_GUEST_HANDLE_STRUCT(gnttab_map_grant_ref); 274*4882a593Smuzhiyun 275*4882a593Smuzhiyun /* 276*4882a593Smuzhiyun * GNTTABOP_unmap_grant_ref: Destroy one or more grant-reference mappings 277*4882a593Smuzhiyun * tracked by <handle>. If <host_addr> or <dev_bus_addr> is zero, that 278*4882a593Smuzhiyun * field is ignored. If non-zero, they must refer to a device/host mapping 279*4882a593Smuzhiyun * that is tracked by <handle> 280*4882a593Smuzhiyun * NOTES: 281*4882a593Smuzhiyun * 1. The call may fail in an undefined manner if either mapping is not 282*4882a593Smuzhiyun * tracked by <handle>. 283*4882a593Smuzhiyun * 3. After executing a batch of unmaps, it is guaranteed that no stale 284*4882a593Smuzhiyun * mappings will remain in the device or host TLBs. 285*4882a593Smuzhiyun */ 286*4882a593Smuzhiyun #define GNTTABOP_unmap_grant_ref 1 287*4882a593Smuzhiyun struct gnttab_unmap_grant_ref { 288*4882a593Smuzhiyun /* IN parameters. */ 289*4882a593Smuzhiyun uint64_t host_addr; 290*4882a593Smuzhiyun uint64_t dev_bus_addr; 291*4882a593Smuzhiyun grant_handle_t handle; 292*4882a593Smuzhiyun /* OUT parameters. */ 293*4882a593Smuzhiyun int16_t status; /* GNTST_* */ 294*4882a593Smuzhiyun }; 295*4882a593Smuzhiyun DEFINE_GUEST_HANDLE_STRUCT(gnttab_unmap_grant_ref); 296*4882a593Smuzhiyun 297*4882a593Smuzhiyun /* 298*4882a593Smuzhiyun * GNTTABOP_setup_table: Set up a grant table for <dom> comprising at least 299*4882a593Smuzhiyun * <nr_frames> pages. The frame addresses are written to the <frame_list>. 300*4882a593Smuzhiyun * Only <nr_frames> addresses are written, even if the table is larger. 301*4882a593Smuzhiyun * NOTES: 302*4882a593Smuzhiyun * 1. <dom> may be specified as DOMID_SELF. 303*4882a593Smuzhiyun * 2. Only a sufficiently-privileged domain may specify <dom> != DOMID_SELF. 304*4882a593Smuzhiyun * 3. Xen may not support more than a single grant-table page per domain. 305*4882a593Smuzhiyun */ 306*4882a593Smuzhiyun #define GNTTABOP_setup_table 2 307*4882a593Smuzhiyun struct gnttab_setup_table { 308*4882a593Smuzhiyun /* IN parameters. */ 309*4882a593Smuzhiyun domid_t dom; 310*4882a593Smuzhiyun uint32_t nr_frames; 311*4882a593Smuzhiyun /* OUT parameters. */ 312*4882a593Smuzhiyun int16_t status; /* GNTST_* */ 313*4882a593Smuzhiyun GUEST_HANDLE(xen_pfn_t) frame_list; 314*4882a593Smuzhiyun }; 315*4882a593Smuzhiyun DEFINE_GUEST_HANDLE_STRUCT(gnttab_setup_table); 316*4882a593Smuzhiyun 317*4882a593Smuzhiyun /* 318*4882a593Smuzhiyun * GNTTABOP_dump_table: Dump the contents of the grant table to the 319*4882a593Smuzhiyun * xen console. Debugging use only. 320*4882a593Smuzhiyun */ 321*4882a593Smuzhiyun #define GNTTABOP_dump_table 3 322*4882a593Smuzhiyun struct gnttab_dump_table { 323*4882a593Smuzhiyun /* IN parameters. */ 324*4882a593Smuzhiyun domid_t dom; 325*4882a593Smuzhiyun /* OUT parameters. */ 326*4882a593Smuzhiyun int16_t status; /* GNTST_* */ 327*4882a593Smuzhiyun }; 328*4882a593Smuzhiyun DEFINE_GUEST_HANDLE_STRUCT(gnttab_dump_table); 329*4882a593Smuzhiyun 330*4882a593Smuzhiyun /* 331*4882a593Smuzhiyun * GNTTABOP_transfer_grant_ref: Transfer <frame> to a foreign domain. The 332*4882a593Smuzhiyun * foreign domain has previously registered its interest in the transfer via 333*4882a593Smuzhiyun * <domid, ref>. 334*4882a593Smuzhiyun * 335*4882a593Smuzhiyun * Note that, even if the transfer fails, the specified page no longer belongs 336*4882a593Smuzhiyun * to the calling domain *unless* the error is GNTST_bad_page. 337*4882a593Smuzhiyun */ 338*4882a593Smuzhiyun #define GNTTABOP_transfer 4 339*4882a593Smuzhiyun struct gnttab_transfer { 340*4882a593Smuzhiyun /* IN parameters. */ 341*4882a593Smuzhiyun xen_pfn_t mfn; 342*4882a593Smuzhiyun domid_t domid; 343*4882a593Smuzhiyun grant_ref_t ref; 344*4882a593Smuzhiyun /* OUT parameters. */ 345*4882a593Smuzhiyun int16_t status; 346*4882a593Smuzhiyun }; 347*4882a593Smuzhiyun DEFINE_GUEST_HANDLE_STRUCT(gnttab_transfer); 348*4882a593Smuzhiyun 349*4882a593Smuzhiyun /* 350*4882a593Smuzhiyun * GNTTABOP_copy: Hypervisor based copy 351*4882a593Smuzhiyun * source and destinations can be eithers MFNs or, for foreign domains, 352*4882a593Smuzhiyun * grant references. the foreign domain has to grant read/write access 353*4882a593Smuzhiyun * in its grant table. 354*4882a593Smuzhiyun * 355*4882a593Smuzhiyun * The flags specify what type source and destinations are (either MFN 356*4882a593Smuzhiyun * or grant reference). 357*4882a593Smuzhiyun * 358*4882a593Smuzhiyun * Note that this can also be used to copy data between two domains 359*4882a593Smuzhiyun * via a third party if the source and destination domains had previously 360*4882a593Smuzhiyun * grant appropriate access to their pages to the third party. 361*4882a593Smuzhiyun * 362*4882a593Smuzhiyun * source_offset specifies an offset in the source frame, dest_offset 363*4882a593Smuzhiyun * the offset in the target frame and len specifies the number of 364*4882a593Smuzhiyun * bytes to be copied. 365*4882a593Smuzhiyun */ 366*4882a593Smuzhiyun 367*4882a593Smuzhiyun #define _GNTCOPY_source_gref (0) 368*4882a593Smuzhiyun #define GNTCOPY_source_gref (1<<_GNTCOPY_source_gref) 369*4882a593Smuzhiyun #define _GNTCOPY_dest_gref (1) 370*4882a593Smuzhiyun #define GNTCOPY_dest_gref (1<<_GNTCOPY_dest_gref) 371*4882a593Smuzhiyun 372*4882a593Smuzhiyun #define GNTTABOP_copy 5 373*4882a593Smuzhiyun struct gnttab_copy { 374*4882a593Smuzhiyun /* IN parameters. */ 375*4882a593Smuzhiyun struct { 376*4882a593Smuzhiyun union { 377*4882a593Smuzhiyun grant_ref_t ref; 378*4882a593Smuzhiyun xen_pfn_t gmfn; 379*4882a593Smuzhiyun } u; 380*4882a593Smuzhiyun domid_t domid; 381*4882a593Smuzhiyun uint16_t offset; 382*4882a593Smuzhiyun } source, dest; 383*4882a593Smuzhiyun uint16_t len; 384*4882a593Smuzhiyun uint16_t flags; /* GNTCOPY_* */ 385*4882a593Smuzhiyun /* OUT parameters. */ 386*4882a593Smuzhiyun int16_t status; 387*4882a593Smuzhiyun }; 388*4882a593Smuzhiyun DEFINE_GUEST_HANDLE_STRUCT(gnttab_copy); 389*4882a593Smuzhiyun 390*4882a593Smuzhiyun /* 391*4882a593Smuzhiyun * GNTTABOP_query_size: Query the current and maximum sizes of the shared 392*4882a593Smuzhiyun * grant table. 393*4882a593Smuzhiyun * NOTES: 394*4882a593Smuzhiyun * 1. <dom> may be specified as DOMID_SELF. 395*4882a593Smuzhiyun * 2. Only a sufficiently-privileged domain may specify <dom> != DOMID_SELF. 396*4882a593Smuzhiyun */ 397*4882a593Smuzhiyun #define GNTTABOP_query_size 6 398*4882a593Smuzhiyun struct gnttab_query_size { 399*4882a593Smuzhiyun /* IN parameters. */ 400*4882a593Smuzhiyun domid_t dom; 401*4882a593Smuzhiyun /* OUT parameters. */ 402*4882a593Smuzhiyun uint32_t nr_frames; 403*4882a593Smuzhiyun uint32_t max_nr_frames; 404*4882a593Smuzhiyun int16_t status; /* GNTST_* */ 405*4882a593Smuzhiyun }; 406*4882a593Smuzhiyun DEFINE_GUEST_HANDLE_STRUCT(gnttab_query_size); 407*4882a593Smuzhiyun 408*4882a593Smuzhiyun /* 409*4882a593Smuzhiyun * GNTTABOP_unmap_and_replace: Destroy one or more grant-reference mappings 410*4882a593Smuzhiyun * tracked by <handle> but atomically replace the page table entry with one 411*4882a593Smuzhiyun * pointing to the machine address under <new_addr>. <new_addr> will be 412*4882a593Smuzhiyun * redirected to the null entry. 413*4882a593Smuzhiyun * NOTES: 414*4882a593Smuzhiyun * 1. The call may fail in an undefined manner if either mapping is not 415*4882a593Smuzhiyun * tracked by <handle>. 416*4882a593Smuzhiyun * 2. After executing a batch of unmaps, it is guaranteed that no stale 417*4882a593Smuzhiyun * mappings will remain in the device or host TLBs. 418*4882a593Smuzhiyun */ 419*4882a593Smuzhiyun #define GNTTABOP_unmap_and_replace 7 420*4882a593Smuzhiyun struct gnttab_unmap_and_replace { 421*4882a593Smuzhiyun /* IN parameters. */ 422*4882a593Smuzhiyun uint64_t host_addr; 423*4882a593Smuzhiyun uint64_t new_addr; 424*4882a593Smuzhiyun grant_handle_t handle; 425*4882a593Smuzhiyun /* OUT parameters. */ 426*4882a593Smuzhiyun int16_t status; /* GNTST_* */ 427*4882a593Smuzhiyun }; 428*4882a593Smuzhiyun DEFINE_GUEST_HANDLE_STRUCT(gnttab_unmap_and_replace); 429*4882a593Smuzhiyun 430*4882a593Smuzhiyun /* 431*4882a593Smuzhiyun * GNTTABOP_set_version: Request a particular version of the grant 432*4882a593Smuzhiyun * table shared table structure. This operation can only be performed 433*4882a593Smuzhiyun * once in any given domain. It must be performed before any grants 434*4882a593Smuzhiyun * are activated; otherwise, the domain will be stuck with version 1. 435*4882a593Smuzhiyun * The only defined versions are 1 and 2. 436*4882a593Smuzhiyun */ 437*4882a593Smuzhiyun #define GNTTABOP_set_version 8 438*4882a593Smuzhiyun struct gnttab_set_version { 439*4882a593Smuzhiyun /* IN parameters */ 440*4882a593Smuzhiyun uint32_t version; 441*4882a593Smuzhiyun }; 442*4882a593Smuzhiyun DEFINE_GUEST_HANDLE_STRUCT(gnttab_set_version); 443*4882a593Smuzhiyun 444*4882a593Smuzhiyun /* 445*4882a593Smuzhiyun * GNTTABOP_get_status_frames: Get the list of frames used to store grant 446*4882a593Smuzhiyun * status for <dom>. In grant format version 2, the status is separated 447*4882a593Smuzhiyun * from the other shared grant fields to allow more efficient synchronization 448*4882a593Smuzhiyun * using barriers instead of atomic cmpexch operations. 449*4882a593Smuzhiyun * <nr_frames> specify the size of vector <frame_list>. 450*4882a593Smuzhiyun * The frame addresses are returned in the <frame_list>. 451*4882a593Smuzhiyun * Only <nr_frames> addresses are returned, even if the table is larger. 452*4882a593Smuzhiyun * NOTES: 453*4882a593Smuzhiyun * 1. <dom> may be specified as DOMID_SELF. 454*4882a593Smuzhiyun * 2. Only a sufficiently-privileged domain may specify <dom> != DOMID_SELF. 455*4882a593Smuzhiyun */ 456*4882a593Smuzhiyun #define GNTTABOP_get_status_frames 9 457*4882a593Smuzhiyun struct gnttab_get_status_frames { 458*4882a593Smuzhiyun /* IN parameters. */ 459*4882a593Smuzhiyun uint32_t nr_frames; 460*4882a593Smuzhiyun domid_t dom; 461*4882a593Smuzhiyun /* OUT parameters. */ 462*4882a593Smuzhiyun int16_t status; /* GNTST_* */ 463*4882a593Smuzhiyun GUEST_HANDLE(uint64_t) frame_list; 464*4882a593Smuzhiyun }; 465*4882a593Smuzhiyun DEFINE_GUEST_HANDLE_STRUCT(gnttab_get_status_frames); 466*4882a593Smuzhiyun 467*4882a593Smuzhiyun /* 468*4882a593Smuzhiyun * GNTTABOP_get_version: Get the grant table version which is in 469*4882a593Smuzhiyun * effect for domain <dom>. 470*4882a593Smuzhiyun */ 471*4882a593Smuzhiyun #define GNTTABOP_get_version 10 472*4882a593Smuzhiyun struct gnttab_get_version { 473*4882a593Smuzhiyun /* IN parameters */ 474*4882a593Smuzhiyun domid_t dom; 475*4882a593Smuzhiyun uint16_t pad; 476*4882a593Smuzhiyun /* OUT parameters */ 477*4882a593Smuzhiyun uint32_t version; 478*4882a593Smuzhiyun }; 479*4882a593Smuzhiyun DEFINE_GUEST_HANDLE_STRUCT(gnttab_get_version); 480*4882a593Smuzhiyun 481*4882a593Smuzhiyun /* 482*4882a593Smuzhiyun * Issue one or more cache maintenance operations on a portion of a 483*4882a593Smuzhiyun * page granted to the calling domain by a foreign domain. 484*4882a593Smuzhiyun */ 485*4882a593Smuzhiyun #define GNTTABOP_cache_flush 12 486*4882a593Smuzhiyun struct gnttab_cache_flush { 487*4882a593Smuzhiyun union { 488*4882a593Smuzhiyun uint64_t dev_bus_addr; 489*4882a593Smuzhiyun grant_ref_t ref; 490*4882a593Smuzhiyun } a; 491*4882a593Smuzhiyun uint16_t offset; /* offset from start of grant */ 492*4882a593Smuzhiyun uint16_t length; /* size within the grant */ 493*4882a593Smuzhiyun #define GNTTAB_CACHE_CLEAN (1<<0) 494*4882a593Smuzhiyun #define GNTTAB_CACHE_INVAL (1<<1) 495*4882a593Smuzhiyun #define GNTTAB_CACHE_SOURCE_GREF (1<<31) 496*4882a593Smuzhiyun uint32_t op; 497*4882a593Smuzhiyun }; 498*4882a593Smuzhiyun DEFINE_GUEST_HANDLE_STRUCT(gnttab_cache_flush); 499*4882a593Smuzhiyun 500*4882a593Smuzhiyun /* 501*4882a593Smuzhiyun * Bitfield values for update_pin_status.flags. 502*4882a593Smuzhiyun */ 503*4882a593Smuzhiyun /* Map the grant entry for access by I/O devices. */ 504*4882a593Smuzhiyun #define _GNTMAP_device_map (0) 505*4882a593Smuzhiyun #define GNTMAP_device_map (1<<_GNTMAP_device_map) 506*4882a593Smuzhiyun /* Map the grant entry for access by host CPUs. */ 507*4882a593Smuzhiyun #define _GNTMAP_host_map (1) 508*4882a593Smuzhiyun #define GNTMAP_host_map (1<<_GNTMAP_host_map) 509*4882a593Smuzhiyun /* Accesses to the granted frame will be restricted to read-only access. */ 510*4882a593Smuzhiyun #define _GNTMAP_readonly (2) 511*4882a593Smuzhiyun #define GNTMAP_readonly (1<<_GNTMAP_readonly) 512*4882a593Smuzhiyun /* 513*4882a593Smuzhiyun * GNTMAP_host_map subflag: 514*4882a593Smuzhiyun * 0 => The host mapping is usable only by the guest OS. 515*4882a593Smuzhiyun * 1 => The host mapping is usable by guest OS + current application. 516*4882a593Smuzhiyun */ 517*4882a593Smuzhiyun #define _GNTMAP_application_map (3) 518*4882a593Smuzhiyun #define GNTMAP_application_map (1<<_GNTMAP_application_map) 519*4882a593Smuzhiyun 520*4882a593Smuzhiyun /* 521*4882a593Smuzhiyun * GNTMAP_contains_pte subflag: 522*4882a593Smuzhiyun * 0 => This map request contains a host virtual address. 523*4882a593Smuzhiyun * 1 => This map request contains the machine addess of the PTE to update. 524*4882a593Smuzhiyun */ 525*4882a593Smuzhiyun #define _GNTMAP_contains_pte (4) 526*4882a593Smuzhiyun #define GNTMAP_contains_pte (1<<_GNTMAP_contains_pte) 527*4882a593Smuzhiyun 528*4882a593Smuzhiyun /* 529*4882a593Smuzhiyun * Bits to be placed in guest kernel available PTE bits (architecture 530*4882a593Smuzhiyun * dependent; only supported when XENFEAT_gnttab_map_avail_bits is set). 531*4882a593Smuzhiyun */ 532*4882a593Smuzhiyun #define _GNTMAP_guest_avail0 (16) 533*4882a593Smuzhiyun #define GNTMAP_guest_avail_mask ((uint32_t)~0 << _GNTMAP_guest_avail0) 534*4882a593Smuzhiyun 535*4882a593Smuzhiyun /* 536*4882a593Smuzhiyun * Values for error status returns. All errors are -ve. 537*4882a593Smuzhiyun */ 538*4882a593Smuzhiyun #define GNTST_okay (0) /* Normal return. */ 539*4882a593Smuzhiyun #define GNTST_general_error (-1) /* General undefined error. */ 540*4882a593Smuzhiyun #define GNTST_bad_domain (-2) /* Unrecognsed domain id. */ 541*4882a593Smuzhiyun #define GNTST_bad_gntref (-3) /* Unrecognised or inappropriate gntref. */ 542*4882a593Smuzhiyun #define GNTST_bad_handle (-4) /* Unrecognised or inappropriate handle. */ 543*4882a593Smuzhiyun #define GNTST_bad_virt_addr (-5) /* Inappropriate virtual address to map. */ 544*4882a593Smuzhiyun #define GNTST_bad_dev_addr (-6) /* Inappropriate device address to unmap.*/ 545*4882a593Smuzhiyun #define GNTST_no_device_space (-7) /* Out of space in I/O MMU. */ 546*4882a593Smuzhiyun #define GNTST_permission_denied (-8) /* Not enough privilege for operation. */ 547*4882a593Smuzhiyun #define GNTST_bad_page (-9) /* Specified page was invalid for op. */ 548*4882a593Smuzhiyun #define GNTST_bad_copy_arg (-10) /* copy arguments cross page boundary. */ 549*4882a593Smuzhiyun #define GNTST_address_too_big (-11) /* transfer page address too large. */ 550*4882a593Smuzhiyun #define GNTST_eagain (-12) /* Operation not done; try again. */ 551*4882a593Smuzhiyun 552*4882a593Smuzhiyun #define GNTTABOP_error_msgs { \ 553*4882a593Smuzhiyun "okay", \ 554*4882a593Smuzhiyun "undefined error", \ 555*4882a593Smuzhiyun "unrecognised domain id", \ 556*4882a593Smuzhiyun "invalid grant reference", \ 557*4882a593Smuzhiyun "invalid mapping handle", \ 558*4882a593Smuzhiyun "invalid virtual address", \ 559*4882a593Smuzhiyun "invalid device address", \ 560*4882a593Smuzhiyun "no spare translation slot in the I/O MMU", \ 561*4882a593Smuzhiyun "permission denied", \ 562*4882a593Smuzhiyun "bad page", \ 563*4882a593Smuzhiyun "copy arguments cross page boundary", \ 564*4882a593Smuzhiyun "page address size too large", \ 565*4882a593Smuzhiyun "operation not done; try again" \ 566*4882a593Smuzhiyun } 567*4882a593Smuzhiyun 568*4882a593Smuzhiyun #endif /* __XEN_PUBLIC_GRANT_TABLE_H__ */ 569