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 */
24struct 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 */
67struct 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 */
77struct 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 */
87struct 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 */
97struct 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 */
107struct 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 */
116struct 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 */
125struct 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
135typedef 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
143static inline void *
144vmci_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 */
155struct vmci_event_payload_context {
156	vmci_id			context_id;	/* 4 bytes. */
157	uint32_t		_pad;
158};
159
160struct 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 */
173struct 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 */
186struct 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
199static inline void *
200vmci_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 */
228struct 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
239struct vmci_queue_pair_detach_msg {
240	struct vmci_datagram	hdr;
241	struct vmci_handle	handle;
242};
243
244#endif /* !_VMCI_CALL_DEFS_H_ */
245