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