256 lines
8.3 KiB
C
256 lines
8.3 KiB
C
|
/******************************************************************************
|
||
|
* Argo : Hypervisor-Mediated data eXchange
|
||
|
*
|
||
|
* Derived from v4v, the version 2 of v2v.
|
||
|
*
|
||
|
* Copyright (c) 2010, Citrix Systems
|
||
|
* Copyright (c) 2018-2019, BAE Systems
|
||
|
*
|
||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||
|
* of this software and associated documentation files (the "Software"), to
|
||
|
* deal in the Software without restriction, including without limitation the
|
||
|
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||
|
* sell copies of the Software, and to permit persons to whom the Software is
|
||
|
* furnished to do so, subject to the following conditions:
|
||
|
*
|
||
|
* The above copyright notice and this permission notice shall be included in
|
||
|
* all copies or substantial portions of the Software.
|
||
|
*
|
||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||
|
* DEALINGS IN THE SOFTWARE.
|
||
|
*
|
||
|
*/
|
||
|
|
||
|
#ifndef __XEN_PUBLIC_ARGO_H__
|
||
|
#define __XEN_PUBLIC_ARGO_H__
|
||
|
|
||
|
#include "xen.h"
|
||
|
|
||
|
#define XEN_ARGO_DOMID_ANY DOMID_INVALID
|
||
|
|
||
|
/* The maximum size of an Argo ring is defined to be: 16MB (0x1000000 bytes). */
|
||
|
#define XEN_ARGO_MAX_RING_SIZE (0x1000000ULL)
|
||
|
|
||
|
/* Fixed-width type for "argo port" number. Nothing to do with evtchns. */
|
||
|
typedef uint32_t xen_argo_port_t;
|
||
|
|
||
|
/* gfn type: 64-bit fixed-width on all architectures */
|
||
|
typedef uint64_t xen_argo_gfn_t;
|
||
|
|
||
|
/*
|
||
|
* XEN_ARGO_MAXIOV : maximum number of iovs accepted in a single sendv.
|
||
|
* Caution is required if this value is increased: this determines the size of
|
||
|
* an array of xen_argo_iov_t structs on the hypervisor stack, so could cause
|
||
|
* stack overflow if the value is too large.
|
||
|
* The Linux Argo driver never passes more than two iovs.
|
||
|
*/
|
||
|
#define XEN_ARGO_MAXIOV 8U
|
||
|
|
||
|
typedef struct xen_argo_iov
|
||
|
{
|
||
|
XEN_GUEST_HANDLE(uint8) iov_hnd;
|
||
|
uint32_t iov_len;
|
||
|
uint32_t pad;
|
||
|
} xen_argo_iov_t;
|
||
|
|
||
|
typedef struct xen_argo_addr
|
||
|
{
|
||
|
xen_argo_port_t aport;
|
||
|
domid_t domain_id;
|
||
|
uint16_t pad;
|
||
|
} xen_argo_addr_t;
|
||
|
|
||
|
typedef struct xen_argo_send_addr
|
||
|
{
|
||
|
xen_argo_addr_t src;
|
||
|
xen_argo_addr_t dst;
|
||
|
} xen_argo_send_addr_t;
|
||
|
|
||
|
typedef struct xen_argo_ring
|
||
|
{
|
||
|
/* Guests should use atomic operations to access rx_ptr */
|
||
|
uint32_t rx_ptr;
|
||
|
/* Guests should use atomic operations to access tx_ptr */
|
||
|
uint32_t tx_ptr;
|
||
|
/*
|
||
|
* Header space reserved for later use. Align the start of the ring to a
|
||
|
* multiple of the message slot size.
|
||
|
*/
|
||
|
uint8_t reserved[56];
|
||
|
uint8_t ring[XEN_FLEX_ARRAY_DIM];
|
||
|
} xen_argo_ring_t;
|
||
|
|
||
|
typedef struct xen_argo_register_ring
|
||
|
{
|
||
|
xen_argo_port_t aport;
|
||
|
domid_t partner_id;
|
||
|
uint16_t pad;
|
||
|
uint32_t len;
|
||
|
} xen_argo_register_ring_t;
|
||
|
|
||
|
typedef struct xen_argo_unregister_ring
|
||
|
{
|
||
|
xen_argo_port_t aport;
|
||
|
domid_t partner_id;
|
||
|
uint16_t pad;
|
||
|
} xen_argo_unregister_ring_t;
|
||
|
|
||
|
/* Messages on the ring are padded to a multiple of this size. */
|
||
|
#define XEN_ARGO_MSG_SLOT_SIZE 0x10
|
||
|
|
||
|
/*
|
||
|
* Notify flags
|
||
|
*/
|
||
|
/* Ring exists */
|
||
|
#define XEN_ARGO_RING_EXISTS (1U << 0)
|
||
|
/* Ring is shared, not unicast */
|
||
|
#define XEN_ARGO_RING_SHARED (1U << 1)
|
||
|
/* Ring is empty */
|
||
|
#define XEN_ARGO_RING_EMPTY (1U << 2)
|
||
|
/* Sufficient space to queue space_required bytes might exist */
|
||
|
#define XEN_ARGO_RING_SUFFICIENT (1U << 3)
|
||
|
/* Insufficient ring size for space_required bytes */
|
||
|
#define XEN_ARGO_RING_EMSGSIZE (1U << 4)
|
||
|
/* Too many domains waiting for available space signals for this ring */
|
||
|
#define XEN_ARGO_RING_EBUSY (1U << 5)
|
||
|
|
||
|
typedef struct xen_argo_ring_data_ent
|
||
|
{
|
||
|
xen_argo_addr_t ring;
|
||
|
uint16_t flags;
|
||
|
uint16_t pad;
|
||
|
uint32_t space_required;
|
||
|
uint32_t max_message_size;
|
||
|
} xen_argo_ring_data_ent_t;
|
||
|
|
||
|
typedef struct xen_argo_ring_data
|
||
|
{
|
||
|
uint32_t nent;
|
||
|
uint32_t pad;
|
||
|
xen_argo_ring_data_ent_t data[XEN_FLEX_ARRAY_DIM];
|
||
|
} xen_argo_ring_data_t;
|
||
|
|
||
|
struct xen_argo_ring_message_header
|
||
|
{
|
||
|
uint32_t len;
|
||
|
xen_argo_addr_t source;
|
||
|
uint32_t message_type;
|
||
|
uint8_t data[XEN_FLEX_ARRAY_DIM];
|
||
|
};
|
||
|
|
||
|
/*
|
||
|
* Hypercall operations
|
||
|
*/
|
||
|
|
||
|
/*
|
||
|
* XEN_ARGO_OP_register_ring
|
||
|
*
|
||
|
* Register a ring using the guest-supplied memory pages.
|
||
|
* Also used to reregister an existing ring (eg. after resume from hibernate).
|
||
|
*
|
||
|
* The first argument struct indicates the port number for the ring to register
|
||
|
* and the partner domain, if any, that is to be allowed to send to the ring.
|
||
|
* A wildcard (XEN_ARGO_DOMID_ANY) may be supplied instead of a partner domid,
|
||
|
* and if the hypervisor has wildcard sender rings enabled, this will allow
|
||
|
* any domain (XSM notwithstanding) to send to the ring.
|
||
|
*
|
||
|
* The second argument is an array of guest frame numbers and the third argument
|
||
|
* indicates the size of the array. This operation only supports 4K-sized pages.
|
||
|
*
|
||
|
* arg1: XEN_GUEST_HANDLE(xen_argo_register_ring_t)
|
||
|
* arg2: XEN_GUEST_HANDLE(xen_argo_gfn_t)
|
||
|
* arg3: unsigned long npages
|
||
|
* arg4: unsigned long flags (32-bit value)
|
||
|
*/
|
||
|
#define XEN_ARGO_OP_register_ring 1
|
||
|
|
||
|
/* Register op flags */
|
||
|
/*
|
||
|
* Fail exist:
|
||
|
* If set, reject attempts to (re)register an existing established ring.
|
||
|
* If clear, reregistration occurs if the ring exists, with the new ring
|
||
|
* taking the place of the old, preserving tx_ptr if it remains valid.
|
||
|
*/
|
||
|
#define XEN_ARGO_REGISTER_FLAG_FAIL_EXIST 0x1
|
||
|
|
||
|
#ifdef __XEN__
|
||
|
/* Mask for all defined flags. */
|
||
|
#define XEN_ARGO_REGISTER_FLAG_MASK XEN_ARGO_REGISTER_FLAG_FAIL_EXIST
|
||
|
#endif
|
||
|
|
||
|
/*
|
||
|
* XEN_ARGO_OP_unregister_ring
|
||
|
*
|
||
|
* Unregister a previously-registered ring, ending communication.
|
||
|
*
|
||
|
* arg1: XEN_GUEST_HANDLE(xen_argo_unregister_ring_t)
|
||
|
* arg2: NULL
|
||
|
* arg3: 0 (ZERO)
|
||
|
* arg4: 0 (ZERO)
|
||
|
*/
|
||
|
#define XEN_ARGO_OP_unregister_ring 2
|
||
|
|
||
|
/*
|
||
|
* XEN_ARGO_OP_sendv
|
||
|
*
|
||
|
* Send a list of buffers contained in iovs.
|
||
|
*
|
||
|
* The send address struct specifies the source and destination addresses
|
||
|
* for the message being sent, which are used to find the destination ring:
|
||
|
* Xen first looks for a most-specific match with a registered ring with
|
||
|
* (id.addr == dst) and (id.partner == sending_domain) ;
|
||
|
* if that fails, it then looks for a wildcard match (aka multicast receiver)
|
||
|
* where (id.addr == dst) and (id.partner == DOMID_ANY).
|
||
|
*
|
||
|
* For each iov entry, send iov_len bytes from iov_base to the destination ring.
|
||
|
* If insufficient space exists in the destination ring, it will return -EAGAIN
|
||
|
* and Xen will notify the caller when sufficient space becomes available.
|
||
|
*
|
||
|
* The message type is a 32-bit data field available to communicate message
|
||
|
* context data (eg. kernel-to-kernel, rather than application layer).
|
||
|
*
|
||
|
* arg1: XEN_GUEST_HANDLE(xen_argo_send_addr_t) source and dest addresses
|
||
|
* arg2: XEN_GUEST_HANDLE(xen_argo_iov_t) iovs
|
||
|
* arg3: unsigned long niov
|
||
|
* arg4: unsigned long message type (32-bit value)
|
||
|
*/
|
||
|
#define XEN_ARGO_OP_sendv 3
|
||
|
|
||
|
/*
|
||
|
* XEN_ARGO_OP_notify
|
||
|
*
|
||
|
* Asks Xen for information about other rings in the system.
|
||
|
*
|
||
|
* ent->ring is the xen_argo_addr_t of the ring you want information on.
|
||
|
* Uses the same ring matching rules as XEN_ARGO_OP_sendv.
|
||
|
*
|
||
|
* ent->space_required : if this field is not null then Xen will check
|
||
|
* that there is space in the destination ring for this many bytes of payload.
|
||
|
* If the ring is too small for the requested space_required, it will set the
|
||
|
* XEN_ARGO_RING_EMSGSIZE flag on return.
|
||
|
* If sufficient space is available, it will set XEN_ARGO_RING_SUFFICIENT
|
||
|
* and CANCEL any pending notification for that ent->ring; otherwise it
|
||
|
* will schedule a notification event and the flag will not be set.
|
||
|
*
|
||
|
* These flags are set by Xen when notify replies:
|
||
|
* XEN_ARGO_RING_EXISTS ring exists
|
||
|
* XEN_ARGO_RING_SHARED ring is registered for wildcard partner
|
||
|
* XEN_ARGO_RING_EMPTY ring is empty
|
||
|
* XEN_ARGO_RING_SUFFICIENT sufficient space for space_required is there
|
||
|
* XEN_ARGO_RING_EMSGSIZE space_required is too large for the ring size
|
||
|
* XEN_ARGO_RING_EBUSY too many domains waiting for available space signals
|
||
|
*
|
||
|
* arg1: XEN_GUEST_HANDLE(xen_argo_ring_data_t) ring_data (may be NULL)
|
||
|
* arg2: NULL
|
||
|
* arg3: 0 (ZERO)
|
||
|
* arg4: 0 (ZERO)
|
||
|
*/
|
||
|
#define XEN_ARGO_OP_notify 4
|
||
|
|
||
|
#endif
|