1*3a9fd824SRoger Pau Monné /****************************************************************************** 2*3a9fd824SRoger Pau Monné * Argo : Hypervisor-Mediated data eXchange 3*3a9fd824SRoger Pau Monné * 4*3a9fd824SRoger Pau Monné * Derived from v4v, the version 2 of v2v. 5*3a9fd824SRoger Pau Monné * 6*3a9fd824SRoger Pau Monné * Copyright (c) 2010, Citrix Systems 7*3a9fd824SRoger Pau Monné * Copyright (c) 2018-2019, BAE Systems 8*3a9fd824SRoger Pau Monné * 9*3a9fd824SRoger Pau Monné * Permission is hereby granted, free of charge, to any person obtaining a copy 10*3a9fd824SRoger Pau Monné * of this software and associated documentation files (the "Software"), to 11*3a9fd824SRoger Pau Monné * deal in the Software without restriction, including without limitation the 12*3a9fd824SRoger Pau Monné * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 13*3a9fd824SRoger Pau Monné * sell copies of the Software, and to permit persons to whom the Software is 14*3a9fd824SRoger Pau Monné * furnished to do so, subject to the following conditions: 15*3a9fd824SRoger Pau Monné * 16*3a9fd824SRoger Pau Monné * The above copyright notice and this permission notice shall be included in 17*3a9fd824SRoger Pau Monné * all copies or substantial portions of the Software. 18*3a9fd824SRoger Pau Monné * 19*3a9fd824SRoger Pau Monné * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20*3a9fd824SRoger Pau Monné * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21*3a9fd824SRoger Pau Monné * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22*3a9fd824SRoger Pau Monné * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23*3a9fd824SRoger Pau Monné * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 24*3a9fd824SRoger Pau Monné * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 25*3a9fd824SRoger Pau Monné * DEALINGS IN THE SOFTWARE. 26*3a9fd824SRoger Pau Monné * 27*3a9fd824SRoger Pau Monné */ 28*3a9fd824SRoger Pau Monné 29*3a9fd824SRoger Pau Monné #ifndef __XEN_PUBLIC_ARGO_H__ 30*3a9fd824SRoger Pau Monné #define __XEN_PUBLIC_ARGO_H__ 31*3a9fd824SRoger Pau Monné 32*3a9fd824SRoger Pau Monné #include "xen.h" 33*3a9fd824SRoger Pau Monné 34*3a9fd824SRoger Pau Monné #define XEN_ARGO_DOMID_ANY DOMID_INVALID 35*3a9fd824SRoger Pau Monné 36*3a9fd824SRoger Pau Monné /* The maximum size of an Argo ring is defined to be: 16MB (0x1000000 bytes). */ 37*3a9fd824SRoger Pau Monné #define XEN_ARGO_MAX_RING_SIZE (0x1000000ULL) 38*3a9fd824SRoger Pau Monné 39*3a9fd824SRoger Pau Monné /* Fixed-width type for "argo port" number. Nothing to do with evtchns. */ 40*3a9fd824SRoger Pau Monné typedef uint32_t xen_argo_port_t; 41*3a9fd824SRoger Pau Monné 42*3a9fd824SRoger Pau Monné /* gfn type: 64-bit fixed-width on all architectures */ 43*3a9fd824SRoger Pau Monné typedef uint64_t xen_argo_gfn_t; 44*3a9fd824SRoger Pau Monné 45*3a9fd824SRoger Pau Monné /* 46*3a9fd824SRoger Pau Monné * XEN_ARGO_MAXIOV : maximum number of iovs accepted in a single sendv. 47*3a9fd824SRoger Pau Monné * Caution is required if this value is increased: this determines the size of 48*3a9fd824SRoger Pau Monné * an array of xen_argo_iov_t structs on the hypervisor stack, so could cause 49*3a9fd824SRoger Pau Monné * stack overflow if the value is too large. 50*3a9fd824SRoger Pau Monné * The Linux Argo driver never passes more than two iovs. 51*3a9fd824SRoger Pau Monné */ 52*3a9fd824SRoger Pau Monné #define XEN_ARGO_MAXIOV 8U 53*3a9fd824SRoger Pau Monné 54*3a9fd824SRoger Pau Monné typedef struct xen_argo_iov 55*3a9fd824SRoger Pau Monné { 56*3a9fd824SRoger Pau Monné XEN_GUEST_HANDLE(uint8) iov_hnd; 57*3a9fd824SRoger Pau Monné uint32_t iov_len; 58*3a9fd824SRoger Pau Monné uint32_t pad; 59*3a9fd824SRoger Pau Monné } xen_argo_iov_t; 60*3a9fd824SRoger Pau Monné 61*3a9fd824SRoger Pau Monné typedef struct xen_argo_addr 62*3a9fd824SRoger Pau Monné { 63*3a9fd824SRoger Pau Monné xen_argo_port_t aport; 64*3a9fd824SRoger Pau Monné domid_t domain_id; 65*3a9fd824SRoger Pau Monné uint16_t pad; 66*3a9fd824SRoger Pau Monné } xen_argo_addr_t; 67*3a9fd824SRoger Pau Monné 68*3a9fd824SRoger Pau Monné typedef struct xen_argo_send_addr 69*3a9fd824SRoger Pau Monné { 70*3a9fd824SRoger Pau Monné xen_argo_addr_t src; 71*3a9fd824SRoger Pau Monné xen_argo_addr_t dst; 72*3a9fd824SRoger Pau Monné } xen_argo_send_addr_t; 73*3a9fd824SRoger Pau Monné 74*3a9fd824SRoger Pau Monné typedef struct xen_argo_ring 75*3a9fd824SRoger Pau Monné { 76*3a9fd824SRoger Pau Monné /* Guests should use atomic operations to access rx_ptr */ 77*3a9fd824SRoger Pau Monné uint32_t rx_ptr; 78*3a9fd824SRoger Pau Monné /* Guests should use atomic operations to access tx_ptr */ 79*3a9fd824SRoger Pau Monné uint32_t tx_ptr; 80*3a9fd824SRoger Pau Monné /* 81*3a9fd824SRoger Pau Monné * Header space reserved for later use. Align the start of the ring to a 82*3a9fd824SRoger Pau Monné * multiple of the message slot size. 83*3a9fd824SRoger Pau Monné */ 84*3a9fd824SRoger Pau Monné uint8_t reserved[56]; 85*3a9fd824SRoger Pau Monné uint8_t ring[XEN_FLEX_ARRAY_DIM]; 86*3a9fd824SRoger Pau Monné } xen_argo_ring_t; 87*3a9fd824SRoger Pau Monné 88*3a9fd824SRoger Pau Monné typedef struct xen_argo_register_ring 89*3a9fd824SRoger Pau Monné { 90*3a9fd824SRoger Pau Monné xen_argo_port_t aport; 91*3a9fd824SRoger Pau Monné domid_t partner_id; 92*3a9fd824SRoger Pau Monné uint16_t pad; 93*3a9fd824SRoger Pau Monné uint32_t len; 94*3a9fd824SRoger Pau Monné } xen_argo_register_ring_t; 95*3a9fd824SRoger Pau Monné 96*3a9fd824SRoger Pau Monné typedef struct xen_argo_unregister_ring 97*3a9fd824SRoger Pau Monné { 98*3a9fd824SRoger Pau Monné xen_argo_port_t aport; 99*3a9fd824SRoger Pau Monné domid_t partner_id; 100*3a9fd824SRoger Pau Monné uint16_t pad; 101*3a9fd824SRoger Pau Monné } xen_argo_unregister_ring_t; 102*3a9fd824SRoger Pau Monné 103*3a9fd824SRoger Pau Monné /* Messages on the ring are padded to a multiple of this size. */ 104*3a9fd824SRoger Pau Monné #define XEN_ARGO_MSG_SLOT_SIZE 0x10 105*3a9fd824SRoger Pau Monné 106*3a9fd824SRoger Pau Monné /* 107*3a9fd824SRoger Pau Monné * Notify flags 108*3a9fd824SRoger Pau Monné */ 109*3a9fd824SRoger Pau Monné /* Ring exists */ 110*3a9fd824SRoger Pau Monné #define XEN_ARGO_RING_EXISTS (1U << 0) 111*3a9fd824SRoger Pau Monné /* Ring is shared, not unicast */ 112*3a9fd824SRoger Pau Monné #define XEN_ARGO_RING_SHARED (1U << 1) 113*3a9fd824SRoger Pau Monné /* Ring is empty */ 114*3a9fd824SRoger Pau Monné #define XEN_ARGO_RING_EMPTY (1U << 2) 115*3a9fd824SRoger Pau Monné /* Sufficient space to queue space_required bytes might exist */ 116*3a9fd824SRoger Pau Monné #define XEN_ARGO_RING_SUFFICIENT (1U << 3) 117*3a9fd824SRoger Pau Monné /* Insufficient ring size for space_required bytes */ 118*3a9fd824SRoger Pau Monné #define XEN_ARGO_RING_EMSGSIZE (1U << 4) 119*3a9fd824SRoger Pau Monné /* Too many domains waiting for available space signals for this ring */ 120*3a9fd824SRoger Pau Monné #define XEN_ARGO_RING_EBUSY (1U << 5) 121*3a9fd824SRoger Pau Monné 122*3a9fd824SRoger Pau Monné typedef struct xen_argo_ring_data_ent 123*3a9fd824SRoger Pau Monné { 124*3a9fd824SRoger Pau Monné xen_argo_addr_t ring; 125*3a9fd824SRoger Pau Monné uint16_t flags; 126*3a9fd824SRoger Pau Monné uint16_t pad; 127*3a9fd824SRoger Pau Monné uint32_t space_required; 128*3a9fd824SRoger Pau Monné uint32_t max_message_size; 129*3a9fd824SRoger Pau Monné } xen_argo_ring_data_ent_t; 130*3a9fd824SRoger Pau Monné 131*3a9fd824SRoger Pau Monné typedef struct xen_argo_ring_data 132*3a9fd824SRoger Pau Monné { 133*3a9fd824SRoger Pau Monné uint32_t nent; 134*3a9fd824SRoger Pau Monné uint32_t pad; 135*3a9fd824SRoger Pau Monné xen_argo_ring_data_ent_t data[XEN_FLEX_ARRAY_DIM]; 136*3a9fd824SRoger Pau Monné } xen_argo_ring_data_t; 137*3a9fd824SRoger Pau Monné 138*3a9fd824SRoger Pau Monné struct xen_argo_ring_message_header 139*3a9fd824SRoger Pau Monné { 140*3a9fd824SRoger Pau Monné uint32_t len; 141*3a9fd824SRoger Pau Monné xen_argo_addr_t source; 142*3a9fd824SRoger Pau Monné uint32_t message_type; 143*3a9fd824SRoger Pau Monné uint8_t data[XEN_FLEX_ARRAY_DIM]; 144*3a9fd824SRoger Pau Monné }; 145*3a9fd824SRoger Pau Monné 146*3a9fd824SRoger Pau Monné /* 147*3a9fd824SRoger Pau Monné * Hypercall operations 148*3a9fd824SRoger Pau Monné */ 149*3a9fd824SRoger Pau Monné 150*3a9fd824SRoger Pau Monné /* 151*3a9fd824SRoger Pau Monné * XEN_ARGO_OP_register_ring 152*3a9fd824SRoger Pau Monné * 153*3a9fd824SRoger Pau Monné * Register a ring using the guest-supplied memory pages. 154*3a9fd824SRoger Pau Monné * Also used to reregister an existing ring (eg. after resume from hibernate). 155*3a9fd824SRoger Pau Monné * 156*3a9fd824SRoger Pau Monné * The first argument struct indicates the port number for the ring to register 157*3a9fd824SRoger Pau Monné * and the partner domain, if any, that is to be allowed to send to the ring. 158*3a9fd824SRoger Pau Monné * A wildcard (XEN_ARGO_DOMID_ANY) may be supplied instead of a partner domid, 159*3a9fd824SRoger Pau Monné * and if the hypervisor has wildcard sender rings enabled, this will allow 160*3a9fd824SRoger Pau Monné * any domain (XSM notwithstanding) to send to the ring. 161*3a9fd824SRoger Pau Monné * 162*3a9fd824SRoger Pau Monné * The second argument is an array of guest frame numbers and the third argument 163*3a9fd824SRoger Pau Monné * indicates the size of the array. This operation only supports 4K-sized pages. 164*3a9fd824SRoger Pau Monné * 165*3a9fd824SRoger Pau Monné * arg1: XEN_GUEST_HANDLE(xen_argo_register_ring_t) 166*3a9fd824SRoger Pau Monné * arg2: XEN_GUEST_HANDLE(xen_argo_gfn_t) 167*3a9fd824SRoger Pau Monné * arg3: unsigned long npages 168*3a9fd824SRoger Pau Monné * arg4: unsigned long flags (32-bit value) 169*3a9fd824SRoger Pau Monné */ 170*3a9fd824SRoger Pau Monné #define XEN_ARGO_OP_register_ring 1 171*3a9fd824SRoger Pau Monné 172*3a9fd824SRoger Pau Monné /* Register op flags */ 173*3a9fd824SRoger Pau Monné /* 174*3a9fd824SRoger Pau Monné * Fail exist: 175*3a9fd824SRoger Pau Monné * If set, reject attempts to (re)register an existing established ring. 176*3a9fd824SRoger Pau Monné * If clear, reregistration occurs if the ring exists, with the new ring 177*3a9fd824SRoger Pau Monné * taking the place of the old, preserving tx_ptr if it remains valid. 178*3a9fd824SRoger Pau Monné */ 179*3a9fd824SRoger Pau Monné #define XEN_ARGO_REGISTER_FLAG_FAIL_EXIST 0x1 180*3a9fd824SRoger Pau Monné 181*3a9fd824SRoger Pau Monné #ifdef __XEN__ 182*3a9fd824SRoger Pau Monné /* Mask for all defined flags. */ 183*3a9fd824SRoger Pau Monné #define XEN_ARGO_REGISTER_FLAG_MASK XEN_ARGO_REGISTER_FLAG_FAIL_EXIST 184*3a9fd824SRoger Pau Monné #endif 185*3a9fd824SRoger Pau Monné 186*3a9fd824SRoger Pau Monné /* 187*3a9fd824SRoger Pau Monné * XEN_ARGO_OP_unregister_ring 188*3a9fd824SRoger Pau Monné * 189*3a9fd824SRoger Pau Monné * Unregister a previously-registered ring, ending communication. 190*3a9fd824SRoger Pau Monné * 191*3a9fd824SRoger Pau Monné * arg1: XEN_GUEST_HANDLE(xen_argo_unregister_ring_t) 192*3a9fd824SRoger Pau Monné * arg2: NULL 193*3a9fd824SRoger Pau Monné * arg3: 0 (ZERO) 194*3a9fd824SRoger Pau Monné * arg4: 0 (ZERO) 195*3a9fd824SRoger Pau Monné */ 196*3a9fd824SRoger Pau Monné #define XEN_ARGO_OP_unregister_ring 2 197*3a9fd824SRoger Pau Monné 198*3a9fd824SRoger Pau Monné /* 199*3a9fd824SRoger Pau Monné * XEN_ARGO_OP_sendv 200*3a9fd824SRoger Pau Monné * 201*3a9fd824SRoger Pau Monné * Send a list of buffers contained in iovs. 202*3a9fd824SRoger Pau Monné * 203*3a9fd824SRoger Pau Monné * The send address struct specifies the source and destination addresses 204*3a9fd824SRoger Pau Monné * for the message being sent, which are used to find the destination ring: 205*3a9fd824SRoger Pau Monné * Xen first looks for a most-specific match with a registered ring with 206*3a9fd824SRoger Pau Monné * (id.addr == dst) and (id.partner == sending_domain) ; 207*3a9fd824SRoger Pau Monné * if that fails, it then looks for a wildcard match (aka multicast receiver) 208*3a9fd824SRoger Pau Monné * where (id.addr == dst) and (id.partner == DOMID_ANY). 209*3a9fd824SRoger Pau Monné * 210*3a9fd824SRoger Pau Monné * For each iov entry, send iov_len bytes from iov_base to the destination ring. 211*3a9fd824SRoger Pau Monné * If insufficient space exists in the destination ring, it will return -EAGAIN 212*3a9fd824SRoger Pau Monné * and Xen will notify the caller when sufficient space becomes available. 213*3a9fd824SRoger Pau Monné * 214*3a9fd824SRoger Pau Monné * The message type is a 32-bit data field available to communicate message 215*3a9fd824SRoger Pau Monné * context data (eg. kernel-to-kernel, rather than application layer). 216*3a9fd824SRoger Pau Monné * 217*3a9fd824SRoger Pau Monné * arg1: XEN_GUEST_HANDLE(xen_argo_send_addr_t) source and dest addresses 218*3a9fd824SRoger Pau Monné * arg2: XEN_GUEST_HANDLE(xen_argo_iov_t) iovs 219*3a9fd824SRoger Pau Monné * arg3: unsigned long niov 220*3a9fd824SRoger Pau Monné * arg4: unsigned long message type (32-bit value) 221*3a9fd824SRoger Pau Monné */ 222*3a9fd824SRoger Pau Monné #define XEN_ARGO_OP_sendv 3 223*3a9fd824SRoger Pau Monné 224*3a9fd824SRoger Pau Monné /* 225*3a9fd824SRoger Pau Monné * XEN_ARGO_OP_notify 226*3a9fd824SRoger Pau Monné * 227*3a9fd824SRoger Pau Monné * Asks Xen for information about other rings in the system. 228*3a9fd824SRoger Pau Monné * 229*3a9fd824SRoger Pau Monné * ent->ring is the xen_argo_addr_t of the ring you want information on. 230*3a9fd824SRoger Pau Monné * Uses the same ring matching rules as XEN_ARGO_OP_sendv. 231*3a9fd824SRoger Pau Monné * 232*3a9fd824SRoger Pau Monné * ent->space_required : if this field is not null then Xen will check 233*3a9fd824SRoger Pau Monné * that there is space in the destination ring for this many bytes of payload. 234*3a9fd824SRoger Pau Monné * If the ring is too small for the requested space_required, it will set the 235*3a9fd824SRoger Pau Monné * XEN_ARGO_RING_EMSGSIZE flag on return. 236*3a9fd824SRoger Pau Monné * If sufficient space is available, it will set XEN_ARGO_RING_SUFFICIENT 237*3a9fd824SRoger Pau Monné * and CANCEL any pending notification for that ent->ring; otherwise it 238*3a9fd824SRoger Pau Monné * will schedule a notification event and the flag will not be set. 239*3a9fd824SRoger Pau Monné * 240*3a9fd824SRoger Pau Monné * These flags are set by Xen when notify replies: 241*3a9fd824SRoger Pau Monné * XEN_ARGO_RING_EXISTS ring exists 242*3a9fd824SRoger Pau Monné * XEN_ARGO_RING_SHARED ring is registered for wildcard partner 243*3a9fd824SRoger Pau Monné * XEN_ARGO_RING_EMPTY ring is empty 244*3a9fd824SRoger Pau Monné * XEN_ARGO_RING_SUFFICIENT sufficient space for space_required is there 245*3a9fd824SRoger Pau Monné * XEN_ARGO_RING_EMSGSIZE space_required is too large for the ring size 246*3a9fd824SRoger Pau Monné * XEN_ARGO_RING_EBUSY too many domains waiting for available space signals 247*3a9fd824SRoger Pau Monné * 248*3a9fd824SRoger Pau Monné * arg1: XEN_GUEST_HANDLE(xen_argo_ring_data_t) ring_data (may be NULL) 249*3a9fd824SRoger Pau Monné * arg2: NULL 250*3a9fd824SRoger Pau Monné * arg3: 0 (ZERO) 251*3a9fd824SRoger Pau Monné * arg4: 0 (ZERO) 252*3a9fd824SRoger Pau Monné */ 253*3a9fd824SRoger Pau Monné #define XEN_ARGO_OP_notify 4 254*3a9fd824SRoger Pau Monné 255*3a9fd824SRoger Pau Monné #endif 256