33
33
#include "vmci_defs.h"
34
34
#include "vmci_call_defs.h"
36
/* Max size of a single tx buffer. */
37
37
#define VPAGECHANNEL_MAX_TX_BUF_SIZE (1 << 14)
38
38
#define VPAGECHANNEL_MAX_PAGES_PER_TX_BUFFER \
39
39
(VPAGECHANNEL_MAX_TX_BUF_SIZE / PAGE_SIZE + 1)
43
* \brief Get a pointer to the elements in a packet.
45
* Returns a pointer to the elements at the end of a page channel packet.
47
* \see VPageChannelElem
48
* \see VPageChannelPacket
41
51
#define VPAGECHANNEL_PACKET_ELEMS(packet) \
42
52
(VPageChannelElem *)((char *)(packet) + \
43
53
sizeof(VPageChannelPacket) + \
57
* \brief Get a pointer to the message in a packet.
59
* Returns a pointer to the message embedded in a page channel packet.
61
* \see VPageChannelPacket
45
64
#define VPAGECHANNEL_PACKET_MESSAGE(packet) \
46
65
(char *)((char *)(packet) + sizeof(VPageChannelPacket))
68
* \brief Notify client directly, and do not read packets.
70
* This flag indicates that the channel should invoke the client's receive
71
* callback directly when any packets are available. If not specified, then
72
* when a notification is received, packets are read from the channel and the
73
* callback invoked for each one separately.
75
* \note Not applicable to VMKernel.
77
* \see VPageChannel_CreateInVM()
80
#define VPAGECHANNEL_FLAGS_NOTIFY_ONLY 0x1
83
* \brief Invoke client's receive callback in delayed context.
85
* This flag indicates that all callbacks run in a delayed context, and the
86
* caller and callback are allowed to block. If not specified, then callbacks
87
* run in interrupt context and the channel will not block, and the caller
88
* is not allowed to block.
90
* \note Not applicable to VMKernel.
92
* \see VPageChannel_CreateInVM()
95
#define VPAGECHANNEL_FLAGS_RECV_DELAYED 0x2
98
* \brief Send from an atomic context.
100
* This flag indicates that the client wishes to call Send() from an atomic
101
* context and that the channel should not block. If the channel is not
102
* allowed to block, then the channel's pages are permanently mapped and
103
* pinned. Note that this will limit the total size of the channel to
104
* VMCI_MAX_PINNED_QP_MEMORY.
106
* \note Not applicable to VMKernel.
108
* \see VPageChannel_CreateInVM()
111
#define VPAGECHANNEL_FLAGS_SEND_WHILE_ATOMIC 0x4
114
* \brief An element describing a data range.
116
* Describes a data range, starting at a base address and for a given
117
* length, i.e., an element of a scatter-gather list. Indicates physical
118
* address for the guest and machine address for hypervisor. Can be passed
119
* via packets or buffers.
121
* \note Structure is packed.
123
* \see VPageChannelPacket
124
* \see VPageChanelBuffer
50
128
#include "vmware_pack_begin.h"
51
129
struct VPageChannelElem {
53
uint64 pa; // For guest
54
uint64 ma; // For hypervisor
131
/** \brief Physical address for guest. */
134
/** \brief Machine address for hypervisor. */
138
/** \brief Length of range. */
58
141
#include "vmware_pack_end.h"
145
* \brief Page channel page types.
147
* The various types of page channel packets.
149
* \see VPageChannelPacket
152
/** \brief Data packet. */
62
153
VPCPacket_Data = 1,
63
VPCPacket_Completion_Notify, // Hypervisor to guest only.
64
VPCPacket_GuestConnect, // Connect to hypervisor. Internal use only.
65
VPCPacket_HyperConnect, // Complete connection handshake. Internal.
66
VPCPacket_RequestBuffer, // Request buffers. Internal use only.
67
VPCPacket_SetRecvBuffer, // Set buffers. Internal use only.
155
/** \brief Completion notification, from hypervisor to guest. */
156
VPCPacket_Completion_Notify,
159
/** \brief Connect to hypervisor, internal. */
160
VPCPacket_GuestConnect,
162
/** \brief Complete connection handshake, internal. */
163
VPCPacket_HyperConnect,
165
/** \brief Request buffers, internal. */
166
VPCPacket_RequestBuffer,
168
/** \brief Set buffers, internal. */
169
VPCPacket_SetRecvBuffer,
171
/** \brief Hypervisor channel disconnect, internal. */
172
VPCPacket_HyperDisconnect,
174
/** \brief Guest channel ACK hypervisor disconnect, internal. */
175
VPCPacket_GuestDisconnect,
68
177
} VPageChannelPacketType;
180
* \brief Page channel packet structure.
182
* A packet structure for passing control/data between guest and hypervisor.
183
* Can optionally contain a message and also a number of elements.
185
* \note Structure is packed.
187
* \see VPageChannelPacketType
71
190
#include "vmware_pack_begin.h"
72
191
struct VPageChannelPacket {
192
/** \brief Type of packet. */
73
193
VPageChannelPacketType type;
195
/** \brief Length of optional message. */
198
/** \brief Number of optional elements in packet. */
77
* Followed by msgLen of message and numElems of VPageChannelElem.
201
/** \brief Followed by msgLen of message and numElems VPageChannelElem. */
80
203
#include "vmware_pack_end.h"
81
204
VPageChannelPacket;
207
* \brief Page channel buffer structure.
209
* A buffer of elements (a scatter-gather list).
211
* \note Structure is packed.
213
* \see VPageChannelElem
84
217
#include "vmware_pack_begin.h"
85
218
struct VPageChannelBuffer {
219
/** \brief Number of elements. */
222
/** \brief First element. */
87
223
VPageChannelElem elems[1];
89
* Followed by numElems - 1 of VPageChannelElem.
225
/** \brief Followed by numElems - 1 of VPageChannelElem. */
92
227
#include "vmware_pack_end.h"
93
228
VPageChannelBuffer;
96
232
#include "vmware_pack_begin.h"
97
233
struct VPageChannelGuestConnectMessage {
235
/** \brief Guest channel's datagram handle for control channel. */
98
236
VMCIHandle dgHandle;
238
/** \brief Guest channel's queuepair handle. */
99
239
VMCIHandle qpHandle;
241
/** \brief Size of producer queue in queuepair in bytes. */
100
242
uint64 produceQSize;
244
/** \brief Size of consumer queue in queuepair in bytes. */
101
245
uint64 consumeQSize;
247
/** \brief Guest channel's doorbell handle. */
102
248
VMCIHandle doorbellHandle;
104
250
#include "vmware_pack_end.h"
108
254
#include "vmware_pack_begin.h"
109
255
struct VPageChannelHyperConnectMessage {
256
/** \brief Hypervisor's doorbell handle. */
110
257
VMCIHandle doorbellHandle;
112
259
#include "vmware_pack_end.h"
113
260
VPageChannelHyperConnectMessage;
261
/** \endcond PRIVATE */
264
typedef enum VPageChannelState {
266
VPCState_Unconnected,
269
VPCState_Disconnecting,
270
VPCState_Disconnected,
272
/** \endcond PRIVATE */
275
* \brief Opaque page channel type.
115
278
struct VPageChannel;
116
279
typedef struct VPageChannel VPageChannel;
282
* \brief Client receive callback type.
284
* Type of receive callback, invoked when there are data packets in the
285
* channel. The client provides a callback with this type to
286
* VPageChannel_CreateInVM(). If VPAGECHANNEL_FLAGS_NOTIFY_ONLY is specified
287
* in the channel creation flags, then \c packet is \c NULL; otherwise,
288
* \c packet points to a channel packet.
290
* \see VPageChannel_CreateInVM()
291
* \see VPageChannelPacket
118
294
typedef void (*VPageChannelRecvCB)(void *clientData,
119
295
VPageChannelPacket *packet);
122
298
#if !defined(VMKERNEL)
301
* \brief Client element allocation callback type.
303
* Type of element allocation callback, invoked when the channel needs
304
* elements. The client provides a callback of this type to
305
* VPageChannel_CreateInVM().
307
* \see VPageChannel_CreateInVM()
308
* \see VPageChannelElem
309
* \see VPageChannelFreeElemFn
124
312
typedef int (*VPageChannelAllocElemFn)(void *clientData,
125
313
VPageChannelElem *elems,
317
* \brief Client element release callback type.
319
* Type of element release callback, invoked when the channel releases
320
* elements. The client provides a callback of this type to
321
* VPageChannel_CreateInVM().
323
* \see VPageChannel_CreateInVM()
324
* \see VPageChannelElem
325
* \see VPageChannelAllocElemFn
128
328
typedef void (*VPageChannelFreeElemFn)(void *clientData,
129
329
VPageChannelElem *elems,
333
************************************************************************
334
* VPageChannel_CreateInVM */ /**
336
* \brief Create guest page channel.
338
* Creates a page channel in the guest. The channel should be released
339
* with VPageChannel_Destroy().
341
* \note Only applicable in the guest.
343
* \see VPageChannel_CreateInVMK()
344
* \see VPageChannel_Destroy()
346
* \param[out] channel Pointer to a newly constructed page
347
* channel if successful.
348
* \param[in] resourceId Resource ID on which the channel should
349
* register its control channel.
350
* \param[in] peerResourceId Resource ID of peer's control channel.
351
* \param[in] produceQSize Size of producer queue in queuepair in
353
* \param[in] consumeQSize Size of consumer queue in queuepair in
355
* \param[in] flags Channel flags.
356
* \param[in] recvCB Client's receive callback.
357
* \param[in] clientRecvData Client data for client's receive
359
* \param[in] elemAlloc Element allocation callback for
360
* allocating page ranges (scatter-gather
362
* \param[in] allocClientData Client data for element allocation
364
* \param[in] elemFree Element release callback for elements.
365
* \param[in] freeClientData Client data for element release
367
* \param[in] defRecvBufs Default number of elements sent to
368
* hypervisor channel.
369
* \param[in] maxRecvBufs Maximum number of elements that can be
370
* sent to the hypervisor channel.
372
* \retval VMCI_SUCCESS Creation succeeded, \c *channel contains
373
* a pointer to a valid channel.
374
* \retval other Failure.
376
************************************************************************
132
379
int VPageChannel_CreateInVM(VPageChannel **channel,
133
380
VMCIId resourceId,
134
381
VMCIId peerResourceId,
135
382
uint64 produceQSize,
136
383
uint64 consumeQSize,
137
385
VPageChannelRecvCB recvCB,
138
386
void *clientRecvData,
140
387
VPageChannelAllocElemFn elemAlloc,
141
388
void *allocClientData,
142
389
VPageChannelFreeElemFn elemFree,
143
390
void *freeClientData,
144
int defaultRecvBuffers,
147
394
#else // VMKERNEL
397
* \brief Type of VM memory access off callback.
399
* This callback is invoked when the memory of the VM containing the peer
400
* endpoint becomes inaccessible, for example due to a crash. When this
401
* occurs, the client should unmap any guest pages and cleanup any state.
402
* This callback runs in a blockable context. The client is not allowed to
403
* call VPageChannel_Destroy() from inside the callback, or it will deadlock,
404
* since that function will wait for the callback to complete.
406
* \note Only applicable on VMKernel.
408
* \see VPageChannel_CreateInVMK()
411
typedef void (*VPageChannelMemAccessOffCB)(void *clientData);
414
************************************************************************
415
* VPageChannel_CreateInVMK */ /**
417
* \brief Create a page channel in VMKernel.
419
* Creates a page channel. The channel should be released with
420
* VPageChannel_Destroy().
422
* \note Only applicable on VMKernel.
424
* \see VPageChannel_CreateInVM()
425
* \see VPageChannel_Destroy()
427
* \param[out] channel Pointer to a newly constructed page
428
* channel if successful.
429
* \param[in] resourceId Resource ID on which to register
431
* \param[in] recvCB Client's receive callback.
432
* \param[in] clientRecvData Client data for receive callback.
433
* \param[in] memAccessOffCB Client's mem access off callback.
434
* \param[in] memAccessOffData Client data for mem access off.
436
* \retval VMCI_SUCCESS Creation succeeded, \c *channel
437
* contains a pointer to a valid channel.
438
* \retval other Failure.
440
***********************************************************************
149
443
int VPageChannel_CreateInVMK(VPageChannel **channel,
150
444
VMCIId resourceId,
151
445
VPageChannelRecvCB recvCB,
152
void *clientRecvData);
446
void *clientRecvData,
447
VPageChannelMemAccessOffCB memAccessOffCB,
448
void *memAccessOffData);
451
************************************************************************
452
* VPageChannel_ReserveBuffers */ /**
454
* \brief Reserve guest elements.
456
* Reserve sufficient guest elements to cover the given length. The
457
* buffers can then be posted to the guest. This allocates both the
458
* buffer and the elements within the buffer.
460
* \note Only applicable on VMKernel.
462
* \see VPageChannel_ReleaseBuffers()
464
* \param[in] channel Page channel.
465
* \param[in] dataLen Length to reserve in bytes.
466
* \param[out] buffer Pointer to a buffer containing elements to cover
467
* the given length if successful.
469
* \retval VMCI_SUCCESS Reservation succeeded, \c *buffer contains
470
* a pointer to a valid buffer.
471
* \retval other Failure.
473
************************************************************************
154
476
int VPageChannel_ReserveBuffers(VPageChannel *channel,
156
478
VPageChannelBuffer **buffer);
481
************************************************************************
482
* VPageChannel_ReleaseBuffers */ /**
484
* \brief Release guest elements.
486
* \note Only applicable on VMKernel.
488
* \see VPageChannel_ReserveBuffers()
490
* Release guest elements previous reserved with
491
* VPageChannel_ReserveBuffers(). If the buffers were sent to the guest,
492
* then only the buffer itself should be released, i.e.,
493
* \c returnToFreePool should be \c FALSE; the guest will release the
494
* buffers on completion. Otherwise, if for some reason they are not
495
* sent after reserving them, then \c returnToFreePool should be set to
498
* \param[in] channel Page channel.
499
* \param[in] buffer Buffer to be released.
500
* \param[in] returnToFreePool If \c TRUE, then release the elements
501
* of the buffer along with the buffer
502
* itself. If \c FALSE, then release only
503
* the buffer pointer itself.
505
************************************************************************
157
508
void VPageChannel_ReleaseBuffers(VPageChannel *channel,
158
509
VPageChannelBuffer *buffer,
159
510
Bool returnToFreePool);
162
* This function is called when the client is finished using the
163
* scatter-gather list of a packet. This will generate a notification to the
164
* guest to pass the ownership of buffers back to the guest. This can also be
165
* used to read back the data from hypervisor and send it the to guest.
513
************************************************************************
514
* VPageChannel_CompletionNotify */ /**
516
* \brief Notify channel of completion.
518
* This function is called when the client is finished using the elements
519
* (scatter-gather list) of a packet. This will generated a notification
520
* to the guest to pass ownership of the buffers back to the guest. This
521
* can also be used to read back the data from the hypervisor and send
524
* \note Only applicable on VMKernel.
526
* \see VPageChannel_ReserveBuffers
528
* \param[in] channel Channel on which I/O is complete.
529
* \param[in] message Optional message to send to guest.
530
* \param[in] len Length of optional message.
531
* \param[in] buffer Buffer used for I/O.
533
************************************************************************
168
536
int VPageChannel_CompletionNotify(VPageChannel *channel,
181
594
#endif // VMKERNEL
597
************************************************************************
598
* VPageChannel_Destroy */ /**
600
* \brief Destroy the given channel.
602
* Destroy the given channel. This will disconnect from the peer
603
* channel (if connected) and release all resources.
605
* \see VPageChannel_CreateInVMK
606
* \see VPageChannel_CreateInVM
608
* \param[in] channel The channel to be destroyed.
610
************************************************************************
187
613
void VPageChannel_Destroy(VPageChannel *channel);
616
************************************************************************
617
* VPageChannel_Send */ /**
619
* \brief Send a packet to the channel's peer.
621
* Send a packet to the channel's peer. A message and a number of
622
* elements may optionally be sent. If the send is successful, the
623
* elements are owned by the peer and only the buffer itself should
624
* be released, but not the elements within. If the send fails, the
625
* client should release the buffer and the elements.
627
* \see VPageChannel_SendPacket
629
* \param[in] channel Channel on which to send.
630
* \param[in] type Type of packet to send.
631
* \param[in] message Optional message to send.
632
* \param[in] len Length of optional message.
633
* \param[in] buffer Buffer (of elements) to send.
635
* \retval VMCI_SUCCESS Packet successfully sent, buffer elements
637
* \retval other Failure to send, client should release
640
************************************************************************
188
643
int VPageChannel_Send(VPageChannel *channel,
189
644
VPageChannelPacketType type,
192
647
VPageChannelBuffer *buffer);
650
************************************************************************
651
* VPageChannel_SendPacket */ /**
653
* \brief Send the given packet to the channel's peer.
655
* Send a client-constructed packet to the channel's peer. If the
656
* send is successful, any elements in the packet are owned by the
657
* peer. Otherwise, the client retains ownership.
659
* \see VPageChannel_Send
661
* \param[in] channel Channel on which to send.
662
* \param[in] packet Packet to be sent.
664
* \retval VMCI_SUCCESS Packet successfully sent, buffer elements
666
* \retval other Failure to send, client should release
669
************************************************************************
193
672
int VPageChannel_SendPacket(VPageChannel *channel,
194
673
VPageChannelPacket *packet);
676
************************************************************************
677
* VPageChannel_PollRecvQ */ /**
679
* \brief Poll the channel's receive queue for packets.
681
* Poll the channel's receive queue for packets from the peer. If any
682
* packets are available, the channel's receive callback will be invoked.
684
* \param[in] channel Channel to poll.
686
************************************************************************
195
689
void VPageChannel_PollRecvQ(VPageChannel *channel);
199
*-----------------------------------------------------------------------------
201
* VPageChannelPacket_BufferLen --
203
* Calculate the length of the given packet.
206
* The length of the given packet in bytes.
211
*-----------------------------------------------------------------------------
692
************************************************************************
693
* VPageChannel_BufferLen */ /**
695
* \brief Determine the length of a packet.
697
* Determine the length of the given packet in bytes.
699
* \param[in] packet Packet for which length is to be determined.
701
* \retval bytes Size of the packet in bytes.
703
************************************************************************
214
706
static INLINE size_t