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