xref: /freebsd/sys/dev/vmware/vmci/vmci_call_defs.h (revision aa1a8ff2d6dbc51ef058f46f3db5a8bb77967145)
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 *
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 *
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