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