1 /*-
2 * Copyright (c) 2018 VMware, Inc.
3 *
4 * SPDX-License-Identifier: (BSD-2-Clause OR GPL-2.0)
5 */
6
7 #ifndef _VMCI_CALL_DEFS_H_
8 #define _VMCI_CALL_DEFS_H_
9
10 #include "vmci_defs.h"
11
12 /*
13 * All structs here are an integral size of their largest member, ie. a struct
14 * with at least one 8-byte member will have a size that is an integral of 8.
15 * A struct which has a largest member of size 4 will have a size that is an
16 * integral of 4.
17 */
18
19 /*
20 * Base struct for vmci datagrams.
21 */
22 struct vmci_datagram {
23 struct vmci_handle dst;
24 struct vmci_handle src;
25 uint64_t payload_size;
26 };
27
28 /*
29 * Second flag is for creating a well-known handle instead of a per context
30 * handle. Next flag is for deferring datagram delivery, so that the
31 * datagram callback is invoked in a delayed context (not interrupt context).
32 */
33 #define VMCI_FLAG_DG_NONE 0
34 #define VMCI_FLAG_WELLKNOWN_DG_HND 0x1
35 #define VMCI_FLAG_ANYCID_DG_HND 0x2
36 #define VMCI_FLAG_DG_DELAYED_CB 0x4
37
38 /* Event callback should fire in a delayed context (not interrupt context.) */
39 #define VMCI_FLAG_EVENT_NONE 0
40 #define VMCI_FLAG_EVENT_DELAYED_CB 0x1
41
42 /*
43 * Maximum supported size of a VMCI datagram for routable datagrams.
44 * Datagrams going to the hypervisor are allowed to be larger.
45 */
46 #define VMCI_MAX_DG_SIZE \
47 (17 * 4096)
48 #define VMCI_MAX_DG_PAYLOAD_SIZE \
49 (VMCI_MAX_DG_SIZE - sizeof(struct vmci_datagram))
50 #define VMCI_DG_PAYLOAD(_dg) \
51 (void *)((char *)(_dg) + sizeof(struct vmci_datagram))
52 #define VMCI_DG_HEADERSIZE \
53 sizeof(struct vmci_datagram)
54 #define VMCI_DG_SIZE(_dg) \
55 (VMCI_DG_HEADERSIZE + (size_t)(_dg)->payload_size)
56 #define VMCI_DG_SIZE_ALIGNED(_dg) \
57 ((VMCI_DG_SIZE(_dg) + 7) & (size_t)~7)
58
59 /*
60 * Struct used for querying, via VMCI_RESOURCES_QUERY, the availability of
61 * hypervisor resources.
62 * Struct size is 16 bytes. All fields in struct are aligned to their natural
63 * alignment.
64 */
65 struct vmci_resources_query_hdr {
66 struct vmci_datagram hdr;
67 uint32_t num_resources;
68 uint32_t _padding;
69 };
70
71 /*
72 * Convenience struct for negotiating vectors. Must match layout of
73 * vmci_resource_query_hdr minus the struct vmci_datagram header.
74 */
75 struct vmci_resources_query_msg {
76 uint32_t num_resources;
77 uint32_t _padding;
78 vmci_resource resources[1];
79 };
80
81 /*
82 * Struct used for setting the notification bitmap. All fields in struct are
83 * aligned to their natural alignment.
84 */
85 struct vmci_notify_bitmap_set_msg {
86 struct vmci_datagram hdr;
87 PPN bitmap_ppn;
88 uint32_t _pad;
89 };
90
91 /*
92 * Struct used for linking a doorbell handle with an index in the notify
93 * bitmap. All fields in struct are aligned to their natural alignment.
94 */
95 struct vmci_doorbell_link_msg {
96 struct vmci_datagram hdr;
97 struct vmci_handle handle;
98 uint64_t notify_idx;
99 };
100
101 /*
102 * Struct used for unlinking a doorbell handle from an index in the notify
103 * bitmap. All fields in struct are aligned to their natural alignment.
104 */
105 struct vmci_doorbell_unlink_msg {
106 struct vmci_datagram hdr;
107 struct vmci_handle handle;
108 };
109
110 /*
111 * Struct used for generating a notification on a doorbell handle. All fields
112 * in struct are aligned to their natural alignment.
113 */
114 struct vmci_doorbell_notify_msg {
115 struct vmci_datagram hdr;
116 struct vmci_handle handle;
117 };
118
119 /*
120 * This struct is used to contain data for events. Size of this struct is a
121 * multiple of 8 bytes, and all fields are aligned to their natural alignment.
122 */
123 struct vmci_event_data {
124 vmci_event_type event; /* 4 bytes. */
125 uint32_t _pad;
126 /*
127 * Event payload is put here.
128 */
129 };
130
131 /* Callback needed for correctly waiting on events. */
132
133 typedef int
134 (*vmci_datagram_recv_cb)(void *client_data, struct vmci_datagram *msg);
135
136 /*
137 * We use the following inline function to access the payload data associated
138 * with an event data.
139 */
140
141 static inline void *
vmci_event_data_payload(struct vmci_event_data * ev_data)142 vmci_event_data_payload(struct vmci_event_data *ev_data)
143 {
144
145 return ((void *)((char *)ev_data + sizeof(*ev_data)));
146 }
147
148 /*
149 * Define the different VMCI_EVENT payload data types here. All structs must
150 * be a multiple of 8 bytes, and fields must be aligned to their natural
151 * alignment.
152 */
153 struct vmci_event_payload_context {
154 vmci_id context_id; /* 4 bytes. */
155 uint32_t _pad;
156 };
157
158 struct vmci_event_payload_qp {
159 /* QueuePair handle. */
160 struct vmci_handle handle;
161 /* Context id of attaching/detaching VM. */
162 vmci_id peer_id;
163 uint32_t _pad;
164 };
165
166 /*
167 * We define the following struct to get the size of the maximum event data
168 * the hypervisor may send to the guest. If adding a new event payload type
169 * above, add it to the following struct too (inside the union).
170 */
171 struct vmci_event_data_max {
172 struct vmci_event_data event_data;
173 union {
174 struct vmci_event_payload_context context_payload;
175 struct vmci_event_payload_qp qp_payload;
176 } ev_data_payload;
177 };
178
179 /*
180 * Struct used for VMCI_EVENT_SUBSCRIBE/UNSUBSCRIBE and VMCI_EVENT_HANDLER
181 * messages. Struct size is 32 bytes. All fields in struct are aligned to
182 * their natural alignment.
183 */
184 struct vmci_event_msg {
185 struct vmci_datagram hdr;
186 struct vmci_event_data event_data; /* Has event type & payload. */
187 /*
188 * Payload gets put here.
189 */
190 };
191
192 /*
193 * We use the following inline function to access the payload data associated
194 * with an event message.
195 */
196
197 static inline void *
vmci_event_msg_payload(struct vmci_event_msg * e_msg)198 vmci_event_msg_payload(struct vmci_event_msg *e_msg)
199 {
200
201 return (vmci_event_data_payload(&e_msg->event_data));
202 }
203
204 /* Flags for VMCI QueuePair API. */
205 #define VMCI_QPFLAG_ATTACH_ONLY \
206 0x1 /* Fail alloc if QP not created by peer. */
207 #define VMCI_QPFLAG_LOCAL \
208 0x2 /* Only allow attaches from local context. */
209 #define VMCI_QPFLAG_NONBLOCK \
210 0x4 /* Host won't block when guest is quiesced. */
211
212 /* For asymmetric queuepairs, update as new flags are added. */
213 #define VMCI_QP_ASYMM \
214 VMCI_QPFLAG_NONBLOCK
215 #define VMCI_QP_ASYMM_PEER \
216 (VMCI_QPFLAG_ATTACH_ONLY | VMCI_QP_ASYMM)
217
218 /* Update the following (bitwise OR flags) while adding new flags. */
219 #define VMCI_QP_ALL_FLAGS \
220 (VMCI_QPFLAG_ATTACH_ONLY | VMCI_QPFLAG_LOCAL | VMCI_QPFLAG_NONBLOCK)
221
222 /*
223 * Structs used for QueuePair alloc and detach messages. We align fields of
224 * these structs to 64 bit boundaries.
225 */
226 struct vmci_queue_pair_alloc_msg {
227 struct vmci_datagram hdr;
228 struct vmci_handle handle;
229 vmci_id peer; /* 32bit field. */
230 uint32_t flags;
231 uint64_t produce_size;
232 uint64_t consume_size;
233 uint64_t num_ppns;
234 /* List of PPNs placed here. */
235 };
236
237 struct vmci_queue_pair_detach_msg {
238 struct vmci_datagram hdr;
239 struct vmci_handle handle;
240 };
241
242 #endif /* !_VMCI_CALL_DEFS_H_ */
243