/*
* vmciPacket.c --
*
- * Implementation of VMCI packet for guest kernels.
+ * Implementation of vPageChannel for guest kernels.
*/
#include "vmci_kernel_if.h"
#include "vm_assert.h"
#include "vmci_defs.h"
-#include "vmci_packet.h"
+#include "vmci_page_channel.h"
#include "vmciDriver.h"
#include "vmciKernelAPI.h"
#error "Wrong platform."
#endif // !linux || VMKERNEL
-#define LGPFX "VMCIPacket: "
+#define LGPFX "vPageChannel: "
/*
* This threshold is to account for packets being in-flight. We can't keep
/*
- * Packet channel. This is opaque to clients.
+ * Page channel. This is opaque to clients.
*/
-struct VMCIPacketChannel {
+struct VPageChannel {
VMCIHandle dgHandle;
- VMCIPacketRecvCB recvCB;
+ VPageChannelRecvCB recvCB;
void *clientRecvData;
Bool notifyOnly;
- VMCIPacketAllocSgElemFn elemAllocFn;
+ VPageChannelAllocElemFn elemAllocFn;
void *allocClientData;
- VMCIPacketFreeSgElemFn elemFreeFn;
+ VPageChannelFreeElemFn elemFreeFn;
void *freeClientData;
/*
};
-static int VMCIPacketChannelSendControl(VMCIPacketChannel *channel,
- char *message,
- int len,
- VMCIPacketType type,
- int numElems,
- VMCISgElem *sgElems);
+static int VPageChannelSendControl(VPageChannel *channel,
+ char *message,
+ int len,
+ VPageChannelPacketType type,
+ int numElems,
+ VPageChannelElem *elems);
/*
*-----------------------------------------------------------------------------
*
- * VMCIPacketChannelAcquireSendLock
+ * VPageChannelAcquireSendLock
*
* Acquire the channel's send lock.
*
*/
static void
-VMCIPacketChannelAcquireSendLock(VMCIPacketChannel *channel) // IN
+VPageChannelAcquireSendLock(VPageChannel *channel) // IN
{
ASSERT(channel);
VMCIMutex_Acquire(&channel->qpSendMutex);
/*
*-----------------------------------------------------------------------------
*
- * VMCIPacketChannelReleaseSendLock
+ * VPageChannelReleaseSendLock
*
* Release the channel's send lock.
*
*/
static void
-VMCIPacketChannelReleaseSendLock(VMCIPacketChannel *channel) // IN
+VPageChannelReleaseSendLock(VPageChannel *channel) // IN
{
ASSERT(channel);
VMCIMutex_Release(&channel->qpSendMutex);
/*
*-----------------------------------------------------------------------------
*
- * VMCIPacketChannelAcquireRecvLock
+ * VPageChannelAcquireRecvLock
*
* Acquire the channel's receive lock.
*
*/
static void
-VMCIPacketChannelAcquireRecvLock(VMCIPacketChannel *channel) // IN
+VPageChannelAcquireRecvLock(VPageChannel *channel) // IN
{
ASSERT(channel);
VMCIMutex_Acquire(&channel->qpRecvMutex);
/*
*-----------------------------------------------------------------------------
*
- * VMCIPacketChannelReleaseRecvLock
+ * VPageChannelReleaseRecvLock
*
* Release the channel's receive lock.
*
*/
static void
-VMCIPacketChannelReleaseRecvLock(VMCIPacketChannel *channel) // IN
+VPageChannelReleaseRecvLock(VPageChannel *channel) // IN
{
ASSERT(channel);
VMCIMutex_Release(&channel->qpRecvMutex);
/*
*-----------------------------------------------------------------------------
*
- * VMCIPacketChannelSetRecvBuffers --
+ * VPageChannelSetRecvBuffers --
*
* Set the receiving buffers for the channel.
*
*/
static int
-VMCIPacketChannelSetRecvBuffers(VMCIPacketChannel *channel, // IN
- int numElems, // IN
- Bool byControl) // IN
+VPageChannelSetRecvBuffers(VPageChannel *channel, // IN
+ int numElems, // IN
+ Bool byControl) // IN
{
int retval;
int allocNum;
- size_t size = sizeof(VMCIPacket) + numElems * sizeof(VMCISgElem);
- VMCIPacket *packet;
- VMCISgElem *sgElems;
+ size_t size = sizeof(VPageChannelPacket) +
+ numElems * sizeof(VPageChannelElem);
+ VPageChannelElem *elems;
+ VPageChannelPacket *packet;
ASSERT(channel);
- packet = (VMCIPacket *)VMCI_AllocKernelMem(size, VMCI_MEMORY_ATOMIC);
+ packet = (VPageChannelPacket *)VMCI_AllocKernelMem(size, VMCI_MEMORY_ATOMIC);
if (packet == NULL) {
VMCI_WARNING((LGPFX"Failed to allocate packet (channel=%p) "
"(size=%"FMTSZ"u).\n",
return VMCI_ERROR_NO_MEM;
}
- packet->type = VMCIPacket_SetRecvBuffer;
+ packet->type = VPCPacket_SetRecvBuffer;
packet->msgLen = 0;
- packet->numSgElems = numElems;
+ packet->numElems = numElems;
- sgElems = VMCI_PACKET_SG_ELEMS(packet);
- allocNum = channel->elemAllocFn(channel->allocClientData, sgElems, numElems);
+ elems = VPAGECHANNEL_PACKET_ELEMS(packet);
+ allocNum = channel->elemAllocFn(channel->allocClientData, elems, numElems);
if (allocNum != numElems) {
VMCI_WARNING((LGPFX"Failed to allocate receive buffer (channel=%p) "
"(expected=%d) (actual=%d).\n",
}
if (byControl || !channel->qpConnected) {
- retval = VMCIPacketChannelSendControl(channel, NULL, 0,
- VMCIPacket_SetRecvBuffer,
- numElems, sgElems);
+ retval = VPageChannelSendControl(channel, NULL, 0,
+ VPCPacket_SetRecvBuffer,
+ numElems, elems);
} else {
- retval = VMCIPacketChannel_SendPacket(channel, packet);
+ retval = VPageChannel_SendPacket(channel, packet);
}
if (retval < VMCI_SUCCESS) {
VMCI_WARNING((LGPFX"Failed to set receive buffers (channel=%p) "
error:
if (packet != NULL) {
if (allocNum) {
- channel->elemFreeFn(channel->freeClientData, sgElems, allocNum);
+ channel->elemFreeFn(channel->freeClientData, elems, allocNum);
}
VMCI_FreeKernelMem(packet, size);
}
/*
*-----------------------------------------------------------------------------
*
- * VMCIPacketChannelRecvPacket --
+ * VPageChannelRecvPacket --
*
* Process a VMCI packet.
*
*/
static int
-VMCIPacketChannelRecvPacket(VMCIPacketChannel *channel, // IN
- VMCIPacket *packet) // IN
+VPageChannelRecvPacket(VPageChannel *channel, // IN
+ VPageChannelPacket *packet) // IN
{
int recvBufsTarget;
ASSERT(channel);
ASSERT(packet);
- if (packet->type != VMCIPacket_Data &&
- packet->type != VMCIPacket_Completion_Notify &&
- packet->type != VMCIPacket_RequestBuffer &&
- packet->type != VMCIPacket_HyperConnect) {
+ if (packet->type != VPCPacket_Data &&
+ packet->type != VPCPacket_Completion_Notify &&
+ packet->type != VPCPacket_RequestBuffer &&
+ packet->type != VPCPacket_HyperConnect) {
VMCI_WARNING((LGPFX"Received invalid packet (channel=%p) "
"(type=%d).\n",
channel,
"(elems=%d).\n",
channel,
packet->type,
- packet->numSgElems));
+ packet->numElems));
- if (packet->type == VMCIPacket_HyperConnect) {
- VMCIPacketHyperConnectMessage *message;
+ if (packet->type == VPCPacket_HyperConnect) {
+ VPageChannelHyperConnectMessage *message;
if (packet->msgLen < sizeof *message) {
VMCI_WARNING((LGPFX"Received invalid hypervisor connection message "
return VMCI_ERROR_INVALID_ARGS;
}
- message = (VMCIPacketHyperConnectMessage *)VMCI_PACKET_MESSAGE(packet);
+ message = (VPageChannelHyperConnectMessage *)
+ VPAGECHANNEL_PACKET_MESSAGE(packet);
channel->peerDoorbellHandle = message->doorbellHandle;
VMCI_DEBUG_LOG(10,
recvBufsTarget = channel->recvBufsTarget;
switch (packet->type) {
- case VMCIPacket_RequestBuffer:
+ case VPCPacket_RequestBuffer:
/*
* Increase the number of receive buffers by channel->defaultRecvBufs
* if the hypervisor requests it.
}
break;
- case VMCIPacket_Data:
+ case VPCPacket_Data:
channel->recvCB(channel->clientRecvData, packet);
- channel->curRecvBufs -= packet->numSgElems;
+ channel->curRecvBufs -= packet->numElems;
break;
- case VMCIPacket_Completion_Notify:
+ case VPCPacket_Completion_Notify:
channel->recvCB(channel->clientRecvData, packet);
break;
int numElems = recvBufsTarget + VMCI_PACKET_RECV_THRESHOLD -
channel->curRecvBufs;
- if (VMCIPacketChannelSetRecvBuffers(channel, numElems, FALSE) ==
+ if (VPageChannelSetRecvBuffers(channel, numElems, FALSE) ==
VMCI_SUCCESS) {
channel->recvBufsTarget = recvBufsTarget;
}
/*
*-----------------------------------------------------------------------------
*
- * VMCIPacketChannelDgRecvFunc --
+ * VPageChannelDgRecvFunc --
*
* Callback function to receive a VMCI packet. This is only used until
* the connection is made; after that, packets are received over the
*/
static int
-VMCIPacketChannelDgRecvFunc(void *clientData, // IN
- VMCIDatagram *dg) // IN
+VPageChannelDgRecvFunc(void *clientData, // IN
+ VMCIDatagram *dg) // IN
{
- VMCIPacketChannel *channel = (VMCIPacketChannel *)clientData;
+ VPageChannel *channel = (VPageChannel *)clientData;
ASSERT(channel);
ASSERT(dg);
return VMCI_ERROR_NO_ACCESS;
}
- if (dg->payloadSize < sizeof (VMCIPacket)) {
+ if (dg->payloadSize < sizeof (VPageChannelPacket)) {
VMCI_WARNING((LGPFX"Received invalid packet (channel=%p) "
"(size=%"FMT64"u).\n",
channel,
return VMCI_ERROR_INVALID_ARGS;
}
- return VMCIPacketChannelRecvPacket(channel, VMCI_DG_PAYLOAD(dg));
+ return VPageChannelRecvPacket(channel, VMCI_DG_PAYLOAD(dg));
}
*/
static void
-VMCIPacketDoDoorbellCallback(VMCIPacketChannel *channel) // IN/OUT
+VMCIPacketDoDoorbellCallback(VPageChannel *channel) // IN/OUT
{
Bool inUse;
- VMCIPacket packetHeader;
+ VPageChannelPacket packetHeader;
ASSERT(channel);
return;
}
- VMCIPacketChannelAcquireRecvLock(channel);
+ VPageChannelAcquireRecvLock(channel);
inUse = channel->inPoll;
channel->inPoll = TRUE;
- VMCIPacketChannelReleaseRecvLock(channel);
+ VPageChannelReleaseRecvLock(channel);
if (inUse) {
return;
retry:
while (VMCIQPair_ConsumeBufReady(channel->qpair) >= sizeof packetHeader) {
ssize_t retSize, totalSize;
- VMCIPacket *packet;
+ VPageChannelPacket *packet;
retSize = VMCIQPair_Peek(channel->qpair, &packetHeader,
sizeof packetHeader,
}
totalSize = sizeof packetHeader + packetHeader.msgLen +
- packetHeader.numSgElems * sizeof(VMCISgElem);
+ packetHeader.numElems * sizeof(VPageChannelElem);
retSize = VMCIQPair_ConsumeBufReady(channel->qpair);
if (retSize < totalSize) {
channel,
packetHeader.type,
packetHeader.msgLen,
- packetHeader.numSgElems,
+ packetHeader.numElems,
retSize,
totalSize));
break;
}
- packet = (VMCIPacket *)VMCI_AllocKernelMem(totalSize, VMCI_MEMORY_ATOMIC);
+ packet = (VPageChannelPacket *)
+ VMCI_AllocKernelMem(totalSize, VMCI_MEMORY_ATOMIC);
if (!packet) {
VMCI_WARNING((LGPFX"Failed to allocate packet (channel=%p) "
"(size=%"FMTSZ"d).\n",
break;
}
- VMCIPacketChannelRecvPacket(channel, packet);
+ VPageChannelRecvPacket(channel, packet);
VMCI_FreeKernelMem(packet, totalSize);
}
- VMCIPacketChannelAcquireRecvLock(channel);
+ VPageChannelAcquireRecvLock(channel);
/*
* The doorbell may have been notified between when we we finished reading
*/
if (VMCIQPair_ConsumeBufReady(channel->qpair) >= sizeof packetHeader) {
- VMCIPacketChannelReleaseRecvLock(channel);
+ VPageChannelReleaseRecvLock(channel);
goto retry;
}
channel->inPoll = FALSE;
- VMCIPacketChannelReleaseRecvLock(channel);
+ VPageChannelReleaseRecvLock(channel);
}
static void
VMCIPacketDoorbellCallback(void *clientData) // IN/OUT
{
- VMCIPacketChannel *channel = (VMCIPacketChannel *)clientData;
+ VPageChannel *channel = (VPageChannel *)clientData;
ASSERT(channel);
/*
*----------------------------------------------------------------------------
*
- * VMCIPacketChannelSendConnectionMessage --
+ * VPageChannelSendConnectionMessage --
*
* Send a connection control message to the hypervisor.
*
*/
static int
-VMCIPacketChannelSendConnectionMessage(VMCIPacketChannel *channel) // IN
+VPageChannelSendConnectionMessage(VPageChannel *channel) // IN
{
- VMCIPacketGuestConnectMessage message;
+ VPageChannelGuestConnectMessage message;
ASSERT(channel);
channel->qpHandle.context,
channel->qpHandle.resource));
- return VMCIPacketChannelSendControl(channel,
- (char *)&message, sizeof message,
- VMCIPacket_GuestConnect, 0, NULL);
+ return VPageChannelSendControl(channel,
+ (char *)&message, sizeof message,
+ VPCPacket_GuestConnect, 0, NULL);
}
* None.
*
* Side effects:
- * May modify VMCI packet channel state.
+ * May modify page channel state.
*
*----------------------------------------------------------------------------
*/
static void
-VMCIPacketChannelPeerAttachCB(VMCIId subId, // IN
- VMCI_EventData *eData, // IN
- void *clientData) // IN
+VPageChannelPeerAttachCB(VMCIId subId, // IN
+ VMCI_EventData *eData, // IN
+ void *clientData) // IN
{
- VMCIPacketChannel *channel;
+ VPageChannel *channel;
VMCIEventPayload_QP *ePayload;
ASSERT(eData);
ASSERT(clientData);
- channel = (VMCIPacketChannel *)clientData;
+ channel = (VPageChannel *)clientData;
ePayload = VMCIEventDataPayload(eData);
if (VMCI_HANDLE_EQUAL(channel->qpHandle, ePayload->handle)) {
* None.
*
* Side effects:
- * May modify VMCI packet channel state.
+ * May modify page channel state.
*
*----------------------------------------------------------------------------
*/
static void
-VMCIPacketChannelPeerDetachCB(VMCIId subId, // IN
- VMCI_EventData *eData, // IN
- void *clientData) // IN
+VPageChannelPeerDetachCB(VMCIId subId, // IN
+ VMCI_EventData *eData, // IN
+ void *clientData) // IN
{
- VMCIPacketChannel *channel;
+ VPageChannel *channel;
VMCIEventPayload_QP *ePayload;
ASSERT(eData);
ASSERT(clientData);
- channel = (VMCIPacketChannel *)clientData;
+ channel = (VPageChannel *)clientData;
ePayload = VMCIEventDataPayload(eData);
if (VMCI_HANDLE_EQUAL(channel->qpHandle, ePayload->handle)) {
/*
*----------------------------------------------------------------------------
*
- * VMCIPacketChannelDestroyQueuePair --
+ * VPageChannelDestroyQueuePair --
*
* Destroy the channel's queuepair, along with the event subscriptions.
*
* None.
*
* Side effects:
- * May modify VMCI packet channel state.
+ * May modify page channel state.
*
*----------------------------------------------------------------------------
*/
static void
-VMCIPacketChannelDestroyQueuePair(VMCIPacketChannel *channel) // IN/OUT
+VPageChannelDestroyQueuePair(VPageChannel *channel) // IN/OUT
{
ASSERT(channel);
/*
*----------------------------------------------------------------------------
*
- * VMCIPacketChannelCreateQueuePair --
+ * VPageChannelCreateQueuePair --
*
* Create queuepair for data communication.
*
* VMCI_SUCCESS if the queuepair is created, negative values on failure.
*
* Side effects:
- * May modify VMCI packet channel state.
+ * May modify page channel state.
*
*----------------------------------------------------------------------------
*/
static int
-VMCIPacketChannelCreateQueuePair(VMCIPacketChannel *channel) // IN/OUT
+VPageChannelCreateQueuePair(VPageChannel *channel) // IN/OUT
{
int err;
uint32 flags;
err = VMCIEvent_Subscribe(VMCI_EVENT_QP_PEER_ATTACH,
VMCI_FLAG_EVENT_NONE,
- VMCIPacketChannelPeerAttachCB,
+ VPageChannelPeerAttachCB,
channel, &channel->attachSubId);
if (err < VMCI_SUCCESS) {
VMCI_WARNING((LGPFX"Failed to subscribe to attach event "
err = VMCIEvent_Subscribe(VMCI_EVENT_QP_PEER_DETACH,
VMCI_FLAG_EVENT_NONE,
- VMCIPacketChannelPeerDetachCB,
+ VPageChannelPeerDetachCB,
channel, &channel->detachSubId);
if (err < VMCI_SUCCESS) {
VMCI_WARNING((LGPFX"Failed to subscribe to detach event "
return VMCI_SUCCESS;
error:
- VMCIPacketChannelDestroyQueuePair(channel);
+ VPageChannelDestroyQueuePair(channel);
return err;
}
/*
*-----------------------------------------------------------------------------
*
- * VMCIPacketChannel_CreateInVM --
+ * VPageChannel_CreateInVM --
*
- * Create a packet channel in the guest kernel.
+ * Create a page channel in the guest kernel.
*
* Results:
* VMCI_SUCCESS if created, negative errno value otherwise.
*/
int
-VMCIPacketChannel_CreateInVM(VMCIPacketChannel **channel, // IN/OUT
- VMCIId resourceId, // IN
- VMCIId peerResourceId, // IN
- uint64 produceQSize, // IN
- uint64 consumeQSize, // IN
- VMCIPacketRecvCB recvCB, // IN
- void *clientRecvData, // IN
- Bool notifyOnly, // IN
- VMCIPacketAllocSgElemFn elemAllocFn, // IN
- void *allocClientData, // IN
- VMCIPacketFreeSgElemFn elemFreeFn, // IN
- void *freeClientData, // IN
- int defaultRecvBuffers, // IN
- int maxRecvBuffers) // IN
+VPageChannel_CreateInVM(VPageChannel **channel, // IN/OUT
+ VMCIId resourceId, // IN
+ VMCIId peerResourceId, // IN
+ uint64 produceQSize, // IN
+ uint64 consumeQSize, // IN
+ VPageChannelRecvCB recvCB, // IN
+ void *clientRecvData, // IN
+ Bool notifyOnly, // IN
+ VPageChannelAllocElemFn elemAllocFn, // IN
+ void *allocClientData, // IN
+ VPageChannelFreeElemFn elemFreeFn, // IN
+ void *freeClientData, // IN
+ int defaultRecvBuffers, // IN
+ int maxRecvBuffers) // IN
{
int retval;
int flags;
- VMCIPacketChannel *packetChannel;
+ VPageChannel *pageChannel;
ASSERT(channel);
ASSERT(VMCI_INVALID_ID != resourceId);
ASSERT(VMCI_INVALID_ID != peerResourceId);
ASSERT(recvCB);
- packetChannel =
- VMCI_AllocKernelMem(sizeof *packetChannel, VMCI_MEMORY_NONPAGED);
- if (!packetChannel) {
+ pageChannel =
+ VMCI_AllocKernelMem(sizeof *pageChannel, VMCI_MEMORY_NONPAGED);
+ if (!pageChannel) {
return VMCI_ERROR_NO_MEM;
}
* XXX, we should support a default internal allocation function.
*/
- memset(packetChannel, 0, sizeof *packetChannel);
- packetChannel->dgHandle = VMCI_INVALID_HANDLE;
- packetChannel->attachSubId = VMCI_INVALID_ID;
- packetChannel->detachSubId = VMCI_INVALID_ID;
- packetChannel->qpHandle = VMCI_INVALID_HANDLE;
- packetChannel->qpair = NULL;
- packetChannel->doorbellHandle = VMCI_INVALID_HANDLE;
- packetChannel->peerDoorbellHandle = VMCI_INVALID_HANDLE;
- packetChannel->qpConnected = FALSE;
- packetChannel->recvCB = recvCB;
- packetChannel->clientRecvData = clientRecvData;
- packetChannel->notifyOnly = notifyOnly;
- packetChannel->elemAllocFn = elemAllocFn;
- packetChannel->allocClientData = allocClientData;
- packetChannel->elemFreeFn = elemFreeFn;
- packetChannel->freeClientData = freeClientData;
- packetChannel->resourceId = resourceId;
- packetChannel->peerDgHandle = VMCI_MAKE_HANDLE(VMCI_HOST_CONTEXT_ID,
+ memset(pageChannel, 0, sizeof *pageChannel);
+ pageChannel->dgHandle = VMCI_INVALID_HANDLE;
+ pageChannel->attachSubId = VMCI_INVALID_ID;
+ pageChannel->detachSubId = VMCI_INVALID_ID;
+ pageChannel->qpHandle = VMCI_INVALID_HANDLE;
+ pageChannel->qpair = NULL;
+ pageChannel->doorbellHandle = VMCI_INVALID_HANDLE;
+ pageChannel->peerDoorbellHandle = VMCI_INVALID_HANDLE;
+ pageChannel->qpConnected = FALSE;
+ pageChannel->recvCB = recvCB;
+ pageChannel->clientRecvData = clientRecvData;
+ pageChannel->notifyOnly = notifyOnly;
+ pageChannel->elemAllocFn = elemAllocFn;
+ pageChannel->allocClientData = allocClientData;
+ pageChannel->elemFreeFn = elemFreeFn;
+ pageChannel->freeClientData = freeClientData;
+ pageChannel->resourceId = resourceId;
+ pageChannel->peerDgHandle = VMCI_MAKE_HANDLE(VMCI_HOST_CONTEXT_ID,
peerResourceId);
- packetChannel->curRecvBufs = 0;
- packetChannel->recvBufsTarget = defaultRecvBuffers;
- packetChannel->defaultRecvBufs = defaultRecvBuffers;
- packetChannel->maxRecvBufs = maxRecvBuffers + VMCI_PACKET_RECV_THRESHOLD;
- packetChannel->produceQSize = produceQSize;
- packetChannel->consumeQSize = consumeQSize;
+ pageChannel->curRecvBufs = 0;
+ pageChannel->recvBufsTarget = defaultRecvBuffers;
+ pageChannel->defaultRecvBufs = defaultRecvBuffers;
+ pageChannel->maxRecvBufs = maxRecvBuffers + VMCI_PACKET_RECV_THRESHOLD;
+ pageChannel->produceQSize = produceQSize;
+ pageChannel->consumeQSize = consumeQSize;
/*
* Create a datagram handle over which we will connection handshake packets
flags = VMCI_FLAG_DG_DELAYED_CB;
retval = VMCIDatagram_CreateHnd(resourceId, flags,
- VMCIPacketChannelDgRecvFunc, packetChannel,
- &packetChannel->dgHandle);
+ VPageChannelDgRecvFunc, pageChannel,
+ &pageChannel->dgHandle);
if (retval < VMCI_SUCCESS) {
VMCI_WARNING((LGPFX"Failed to create datagram handle "
"(channel=%p) (err=%d).\n",
(LGPFX"Created datagram (channel=%p) "
"(handle=0x%x:0x%x).\n",
channel,
- packetChannel->dgHandle.context,
- packetChannel->dgHandle.resource));
+ pageChannel->dgHandle.context,
+ pageChannel->dgHandle.resource));
/*
* Create a doorbell handle. This is used by the peer to signal the
* arrival of packets in the queuepair.
*/
- retval = VMCIDoorbell_Create(&packetChannel->doorbellHandle,
+ retval = VMCIDoorbell_Create(&pageChannel->doorbellHandle,
VMCI_FLAG_DELAYED_CB,
VMCI_PRIVILEGE_FLAG_RESTRICTED,
- VMCIPacketDoorbellCallback, packetChannel);
+ VMCIPacketDoorbellCallback, pageChannel);
if (retval < VMCI_SUCCESS) {
VMCI_WARNING((LGPFX"Failed to create doorbell "
"(channel=%p) (err=%d).\n",
(LGPFX"Created doorbell (channel=%p) "
"(handle=0x%x:0x%x).\n",
channel,
- packetChannel->doorbellHandle.context,
- packetChannel->doorbellHandle.resource));
+ pageChannel->doorbellHandle.context,
+ pageChannel->doorbellHandle.resource));
/*
* Now create the queuepair, over which we can pass data packets.
*/
- retval = VMCIPacketChannelCreateQueuePair(packetChannel);
+ retval = VPageChannelCreateQueuePair(pageChannel);
if (retval < VMCI_SUCCESS) {
goto error;
}
if (defaultRecvBuffers) {
int numElems = defaultRecvBuffers + VMCI_PACKET_RECV_THRESHOLD;
- retval = VMCIPacketChannelSetRecvBuffers(packetChannel, numElems, TRUE);
+ retval = VPageChannelSetRecvBuffers(pageChannel, numElems, TRUE);
if (retval < VMCI_SUCCESS) {
goto error;
}
}
- retval = VMCIPacketChannelSendConnectionMessage(packetChannel);
+ retval = VPageChannelSendConnectionMessage(pageChannel);
if (retval < VMCI_SUCCESS) {
goto error;
}
VMCI_DEBUG_LOG(10,
(LGPFX"Created (channel=%p) (handle=0x%x:0x%x).\n",
- packetChannel,
- packetChannel->dgHandle.context,
- packetChannel->dgHandle.resource));
+ pageChannel,
+ pageChannel->dgHandle.context,
+ pageChannel->dgHandle.resource));
- *channel = packetChannel;
+ *channel = pageChannel;
return retval;
error:
- VMCIPacketChannel_Destroy(packetChannel);
+ VPageChannel_Destroy(pageChannel);
return retval;
}
-EXPORT_SYMBOL(VMCIPacketChannel_CreateInVM);
+EXPORT_SYMBOL(VPageChannel_CreateInVM);
/*
*-----------------------------------------------------------------------------
*
- * VMCIPacketChannel_Destroy --
+ * VPageChannel_Destroy --
*
- * Destroy the packet channel.
+ * Destroy the page channel.
*
* Results:
* None.
*/
void
-VMCIPacketChannel_Destroy(VMCIPacketChannel *channel) // IN/OUT
+VPageChannel_Destroy(VPageChannel *channel) // IN/OUT
{
ASSERT(channel);
- VMCIPacketChannelDestroyQueuePair(channel);
+ VPageChannelDestroyQueuePair(channel);
if (!VMCI_HANDLE_INVALID(channel->doorbellHandle)) {
VMCIDoorbell_Destroy(channel->doorbellHandle);
(LGPFX"Destroyed (channel=%p).\n",
channel));
}
-EXPORT_SYMBOL(VMCIPacketChannel_Destroy);
+EXPORT_SYMBOL(VPageChannel_Destroy);
/*
*/
static int
-VMCIPacketAllocDatagram(VMCIPacketChannel *channel, // IN
- size_t messageLen, // IN
- int numSgElems, // IN
- VMCIDatagram **outDg) // OUT
+VPageChannelAllocDatagram(VPageChannel *channel, // IN
+ size_t messageLen, // IN
+ int numElems, // IN
+ VMCIDatagram **outDg) // OUT
{
size_t size;
VMCIDatagram *dg;
*outDg = NULL;
- size = VMCI_DG_HEADERSIZE + sizeof(VMCIPacket) + messageLen +
- numSgElems * sizeof (VMCISgElem);
+ size = VMCI_DG_HEADERSIZE + sizeof(VPageChannelPacket) + messageLen +
+ numElems * sizeof (VPageChannelElem);
if (size > VMCI_MAX_DG_SIZE) {
VMCI_WARNING((LGPFX"Requested datagram size too large (channel=%p) "
/*
*-----------------------------------------------------------------------------
*
- * VMCIPacketChannelSendControl --
+ * VPageChannelSendControl --
*
* A packet is constructed to send the message and buffer to the guest
* via the control channel (datagram). This is only necessary until the
*/
static int
-VMCIPacketChannelSendControl(VMCIPacketChannel *channel, // IN
- char *message, // IN
- int len, // IN
- VMCIPacketType type, // IN
- int numSgElems, // IN
- VMCISgElem *sgElems) // IN
+VPageChannelSendControl(VPageChannel *channel, // IN
+ char *message, // IN
+ int len, // IN
+ VPageChannelPacketType type, // IN
+ int numElems, // IN
+ VPageChannelElem *elems) // IN
{
int retval;
- VMCIPacket *packet;
+ VPageChannelPacket *packet;
VMCIDatagram *dg;
ASSERT(channel);
- ASSERT(type == VMCIPacket_Data ||
- type == VMCIPacket_GuestConnect ||
- type == VMCIPacket_SetRecvBuffer);
+ ASSERT(type == VPCPacket_Data ||
+ type == VPCPacket_GuestConnect ||
+ type == VPCPacket_SetRecvBuffer);
dg = NULL;
- retval = VMCIPacketAllocDatagram(channel, len, numSgElems, &dg);
+ retval = VPageChannelAllocDatagram(channel, len, numElems, &dg);
if (retval < VMCI_SUCCESS) {
return retval;
}
- packet = (VMCIPacket *)VMCI_DG_PAYLOAD(dg);
+ packet = (VPageChannelPacket *)VMCI_DG_PAYLOAD(dg);
packet->type = type;
packet->msgLen = len;
- packet->numSgElems = numSgElems;
+ packet->numElems = numElems;
if (len) {
ASSERT(message);
- memcpy(VMCI_PACKET_MESSAGE(packet), message, len);
+ memcpy(VPAGECHANNEL_PACKET_MESSAGE(packet), message, len);
}
- if (numSgElems) {
- ASSERT(sgElems);
- memcpy(VMCI_PACKET_SG_ELEMS(packet), sgElems,
- numSgElems * sizeof (VMCISgElem));
+ if (numElems) {
+ ASSERT(elems);
+ memcpy(VPAGECHANNEL_PACKET_ELEMS(packet), elems,
+ numElems * sizeof (VPageChannelElem));
}
retval = VMCIDatagram_Send(dg);
/*
*-----------------------------------------------------------------------------
*
- * VMCIPacketChannel_SendPacket --
+ * VPageChannel_SendPacket --
*
* Send a VMCI packet to the hypervisor.
*
*/
int
-VMCIPacketChannel_SendPacket(VMCIPacketChannel *channel, // IN
- VMCIPacket *packet) // IN
+VPageChannel_SendPacket(VPageChannel *channel, // IN
+ VPageChannelPacket *packet) // IN
{
int retval;
ssize_t totalSize, sentSize, curSize;
ASSERT(packet);
- totalSize = sizeof(VMCIPacket) + packet->msgLen +
- packet->numSgElems * sizeof(VMCISgElem);
+ totalSize = sizeof(VPageChannelPacket) + packet->msgLen +
+ packet->numElems * sizeof(VPageChannelElem);
- VMCIPacketChannelAcquireSendLock(channel);
+ VPageChannelAcquireSendLock(channel);
freeSpace = VMCIQPair_ProduceFreeSpace(channel->qpair);
if (freeSpace < totalSize) {
}
}
- VMCIPacketChannelReleaseSendLock(channel);
+ VPageChannelReleaseSendLock(channel);
if (sentSize < totalSize) {
/*
return VMCI_SUCCESS;
unlock:
- VMCIPacketChannelReleaseSendLock(channel);
+ VPageChannelReleaseSendLock(channel);
error:
return retval;
}
-EXPORT_SYMBOL(VMCIPacketChannel_SendPacket);
+EXPORT_SYMBOL(VPageChannel_SendPacket);
/*
*-----------------------------------------------------------------------------
*
- * VMCIPacketChannel_Send --
+ * VPageChannel_Send --
*
- * VMCIPacket is constructed to send the message and buffer to the guest.
+ * A packet is constructed to send the message and buffer to the guest.
*
* XXX, this is now identical to the function of the same name in
* modules/vmkernel/vmci/vmciPacketVMK.c. We should share this code.
*/
int
-VMCIPacketChannel_Send(VMCIPacketChannel *channel, // IN/OUT
- VMCIPacketType type, // IN
- char *message, // IN
- int len, // IN
- VMCIPacketBuffer *buffer) // IN
+VPageChannel_Send(VPageChannel *channel, // IN/OUT
+ VPageChannelPacketType type, // IN
+ char *message, // IN
+ int len, // IN
+ VPageChannelBuffer *buffer) // IN
{
int retval;
- int numSgElems;
+ int numElems;
ssize_t totalSize;
- VMCIPacket *packet;
+ VPageChannelPacket *packet;
ASSERT(channel);
}
if (buffer) {
- numSgElems = buffer->numSgElems;
+ numElems = buffer->numElems;
} else {
- numSgElems = 0;
+ numElems = 0;
}
- totalSize = sizeof(VMCIPacket) + len + numSgElems * sizeof(VMCISgElem);
- packet = (VMCIPacket *)VMCI_AllocKernelMem(totalSize, VMCI_MEMORY_NORMAL);
+ totalSize = sizeof(VPageChannelPacket) + len +
+ numElems * sizeof(VPageChannelElem);
+ packet = (VPageChannelPacket *)
+ VMCI_AllocKernelMem(totalSize, VMCI_MEMORY_NORMAL);
if (!packet) {
VMCI_WARNING((LGPFX"Failed to allocate packet (channel=%p) "
"(size=%"FMTSZ"d).",
packet->type = type;
packet->msgLen = len;
- packet->numSgElems = numSgElems;
+ packet->numElems = numElems;
if (len) {
ASSERT(message);
- memcpy(VMCI_PACKET_MESSAGE(packet), message, len);
+ memcpy(VPAGECHANNEL_PACKET_MESSAGE(packet), message, len);
}
- if (numSgElems) {
+ if (numElems) {
ASSERT(buffer);
ASSERT(buffer->elems);
- memcpy(VMCI_PACKET_SG_ELEMS(packet), buffer->elems,
- numSgElems * sizeof (VMCISgElem));
+ memcpy(VPAGECHANNEL_PACKET_ELEMS(packet), buffer->elems,
+ numElems * sizeof (VPageChannelElem));
}
- retval = VMCIPacketChannel_SendPacket(channel, packet);
+ retval = VPageChannel_SendPacket(channel, packet);
VMCI_FreeKernelMem(packet, totalSize);
return retval;
}
-EXPORT_SYMBOL(VMCIPacketChannel_Send);
+EXPORT_SYMBOL(VPageChannel_Send);
/*
*-----------------------------------------------------------------------------
*
- * VMCIPacketChannel_PollTx --
+ * VPageChannel_PollTx --
*
* The caller does its own coalescing and notifies us that it starts tx.
*
*/
void
-VMCIPacketChannel_PollRecvQ(VMCIPacketChannel *channel) // IN
+VPageChannel_PollRecvQ(VPageChannel *channel) // IN
{
if (channel->qpConnected) {
VMCIPacketDoDoorbellCallback(channel);
}
}
-EXPORT_SYMBOL(VMCIPacketChannel_PollRecvQ);
+EXPORT_SYMBOL(VPageChannel_PollRecvQ);
+++ /dev/null
-/*********************************************************
- * Copyright (C) 2011 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-/*
- * vmci_packet.h --
- *
- * VMCI packet structure and functions.
- */
-
-#ifndef _VMCI_PACKET_H_
-#define _VMCI_PACKET_H_
-
-#define INCLUDE_ALLOW_MODULE
-#define INCLUDE_ALLOW_USERLEVEL
-#define INCLUDE_ALLOW_VMK_MODULE
-#define INCLUDE_ALLOW_VMKERNEL
-#include "includeCheck.h"
-
-#include "vmci_defs.h"
-#include "vmci_call_defs.h"
-
-/* Max size of a single tx buffer. */
-#define VMCI_PACKET_MAX_TX_BUF_SIZE (1 << 14)
-#define VMCI_PACKET_MAX_PAGES_PER_TX_BUFFER \
- (VMCI_PACKET_MAX_TX_BUF_SIZE / PAGE_SIZE + 1)
-
-#define VMCI_PACKET_SG_ELEMS(packet) \
- (VMCISgElem *)((char *)(packet) + sizeof(VMCIPacket) + packet->msgLen)
-#define VMCI_PACKET_MESSAGE(packet) \
- (char *)((char *)(packet) + sizeof(VMCIPacket))
-
-
-typedef
-#include "vmware_pack_begin.h"
-struct VMCISgElem {
- union {
- uint64 pa; // For guest
- uint64 ma; // For hypervisor
- };
- uint32 le;
-}
-#include "vmware_pack_end.h"
-VMCISgElem;
-
-typedef enum {
- VMCIPacket_Data = 1,
- VMCIPacket_Completion_Notify, // Hypervisor to guest only.
- VMCIPacket_GuestConnect, // Connect to hypervisor. Internal use only.
- VMCIPacket_HyperConnect, // Complete connection handshake. Internal.
- VMCIPacket_RequestBuffer, // Request buffers. Internal use only.
- VMCIPacket_SetRecvBuffer, // Set buffers. Internal use only.
-} VMCIPacketType;
-
-typedef
-#include "vmware_pack_begin.h"
-struct VMCIPacket {
- VMCIPacketType type;
- uint32 msgLen;
- uint32 numSgElems;
- /*
- * Followed by msgLen of message and numSgElems of VMCISgElem.
- */
-}
-#include "vmware_pack_end.h"
-VMCIPacket;
-
-typedef
-#include "vmware_pack_begin.h"
-struct VMCIPacketBuffer {
- uint32 numSgElems;
- VMCISgElem elems[1];
- /*
- * Followed by numSgElems - 1 of VMCISgElem.
- */
-}
-#include "vmware_pack_end.h"
-VMCIPacketBuffer;
-
-typedef
-#include "vmware_pack_begin.h"
-struct VMCIPacketGuestConnectMessage {
- VMCIHandle dgHandle;
- VMCIHandle qpHandle;
- uint64 produceQSize;
- uint64 consumeQSize;
- VMCIHandle doorbellHandle;
-}
-#include "vmware_pack_end.h"
-VMCIPacketGuestConnectMessage;
-
-typedef
-#include "vmware_pack_begin.h"
-struct VMCIPacketHyperConnectMessage {
- VMCIHandle doorbellHandle;
-}
-#include "vmware_pack_end.h"
-VMCIPacketHyperConnectMessage;
-
-struct VMCIPacketChannel;
-typedef struct VMCIPacketChannel VMCIPacketChannel;
-
-typedef void (*VMCIPacketRecvCB)(void *clientData, VMCIPacket *packet);
-
-
-#if !defined(VMKERNEL)
-
-typedef int (*VMCIPacketAllocSgElemFn)(void *clientData,
- VMCISgElem *sgElems,
- int numOfElems);
-
-typedef void (*VMCIPacketFreeSgElemFn)(void *clientData,
- VMCISgElem *sgElems,
- int numOfElems);
-
-int VMCIPacketChannel_CreateInVM(VMCIPacketChannel **channel,
- VMCIId resourceId,
- VMCIId peerResourceId,
- uint64 produceQSize,
- uint64 consumeQSize,
- VMCIPacketRecvCB recvCB,
- void *clientRecvData,
- Bool notifyOnly,
- VMCIPacketAllocSgElemFn elemAlloc,
- void *allocClientData,
- VMCIPacketFreeSgElemFn elemFree,
- void *freeClientData,
- int defaultRecvBuffers,
- int maxRecvBuffers);
-
-/*
- * Send a packet to the hypervisor. The message is copied and the buffers
- * represented by the scatter-gather list of (pa, le) are sent to the
- * hypervisor. The buffers belong to the hypervisor until it sends a completion
- * notification using VMCIPacketChannel_CompletionNotify().
- */
-
-int VMCIPacketChannel_SendInVM(VMCIPacketChannel *channel, VMCIPacket *packet);
-
-#else // VMKERNEL
-
-int VMCIPacketChannel_CreateInVMK(VMCIPacketChannel **channel,
- VMCIId resourceId,
- VMCIPacketRecvCB recvCB,
- void *clientRecvData);
-
-int VMCIPacketChannel_ReserveBuffers(VMCIPacketChannel *channel,
- size_t dataLen,
- VMCIPacketBuffer **buffer);
-void VMCIPacketChannel_ReleaseBuffers(VMCIPacketChannel *channel,
- VMCIPacketBuffer *buffer,
- Bool returnToFreePool);
-
-/*
- * This function is called when the client is finished using the
- * scatter-gather list of a packet. This will generate a notification to the
- * guest to pass the ownership of buffers back to the guest. This can also be
- * used to read back the data from hypervisor and send it the to guest.
- */
-
-int VMCIPacketChannel_CompletionNotify(VMCIPacketChannel *channel,
- char *message,
- int len,
- VMCIPacketBuffer *buffer);
-
-int VMCIPacketChannel_MapToMa(VMCIPacketChannel *channel,
- VMCISgElem paElem,
- VMCISgElem *maElems,
- uint32 numSgElems);
-int VMCIPacketChannel_UnmapMa(VMCIPacketChannel *channel,
- VMCIPacketBuffer *buffer,
- int numSgElems);
-
-#endif // VMKERNEL
-
-/*
- * Common functions.
- */
-
-void VMCIPacketChannel_Destroy(VMCIPacketChannel *channel);
-int VMCIPacketChannel_Send(VMCIPacketChannel *channel,
- VMCIPacketType type,
- char *message,
- int len,
- VMCIPacketBuffer *buffer);
-int VMCIPacketChannel_SendPacket(VMCIPacketChannel *channel,
- VMCIPacket *packet);
-void VMCIPacketChannel_PollRecvQ(VMCIPacketChannel *channel);
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * VMCIPacket_BufferLen --
- *
- * Calculate the length of the given packet.
- *
- * Results:
- * The length of the given packet in bytes.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-static INLINE size_t
-VMCIPacket_BufferLen(VMCIPacket *packet) // IN
-{
- size_t len, i;
- VMCISgElem *elems;
-
- ASSERT(packet);
-
- len = 0;
- elems = VMCI_PACKET_SG_ELEMS(packet);
- for (i = 0; i < packet->numSgElems; i++) {
- len += elems[i].le;
- }
-
- return len;
-}
-
-
-#if defined(linux) && !defined(VMKERNEL)
-#include "compat_pci.h"
-#define vmci_pci_map_page(_pg, _off, _sz, _dir) \
- pci_map_page(NULL, (_pg), (_off), (_sz), (_dir))
-#define vmci_pci_unmap_page(_dma, _sz, _dir) \
- pci_unmap_page(NULL, (_dma), (_sz), (_dir))
-#endif // linux && !VMKERNEL
-
-#endif // _VMCI_PACKET_H_
--- /dev/null
+/*********************************************************
+ * Copyright (C) 2011 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2 and no later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ *********************************************************/
+
+/*
+ * vmci_page_channel.h
+ *
+ * vPageChannel structure and functions.
+ */
+
+#ifndef _VMCI_PAGE_CHANNEL_H_
+#define _VMCI_PAGE_CHANNEL_H_
+
+#define INCLUDE_ALLOW_MODULE
+#define INCLUDE_ALLOW_VMK_MODULE
+#define INCLUDE_ALLOW_VMKERNEL
+#include "includeCheck.h"
+
+#include "vmci_defs.h"
+#include "vmci_call_defs.h"
+
+/* Max size of a single tx buffer. */
+#define VPAGECHANNEL_MAX_TX_BUF_SIZE (1 << 14)
+#define VPAGECHANNEL_MAX_PAGES_PER_TX_BUFFER \
+ (VPAGECHANNEL_MAX_TX_BUF_SIZE / PAGE_SIZE + 1)
+
+#define VPAGECHANNEL_PACKET_ELEMS(packet) \
+ (VPageChannelElem *)((char *)(packet) + \
+ sizeof(VPageChannelPacket) + \
+ packet->msgLen)
+#define VPAGECHANNEL_PACKET_MESSAGE(packet) \
+ (char *)((char *)(packet) + sizeof(VPageChannelPacket))
+
+
+typedef
+#include "vmware_pack_begin.h"
+struct VPageChannelElem {
+ union {
+ uint64 pa; // For guest
+ uint64 ma; // For hypervisor
+ };
+ uint32 le;
+}
+#include "vmware_pack_end.h"
+VPageChannelElem;
+
+typedef enum {
+ VPCPacket_Data = 1,
+ VPCPacket_Completion_Notify, // Hypervisor to guest only.
+ VPCPacket_GuestConnect, // Connect to hypervisor. Internal use only.
+ VPCPacket_HyperConnect, // Complete connection handshake. Internal.
+ VPCPacket_RequestBuffer, // Request buffers. Internal use only.
+ VPCPacket_SetRecvBuffer, // Set buffers. Internal use only.
+} VPageChannelPacketType;
+
+typedef
+#include "vmware_pack_begin.h"
+struct VPageChannelPacket {
+ VPageChannelPacketType type;
+ uint32 msgLen;
+ uint32 numElems;
+ /*
+ * Followed by msgLen of message and numElems of VPageChannelElem.
+ */
+}
+#include "vmware_pack_end.h"
+VPageChannelPacket;
+
+typedef
+#include "vmware_pack_begin.h"
+struct VPageChannelBuffer {
+ uint32 numElems;
+ VPageChannelElem elems[1];
+ /*
+ * Followed by numElems - 1 of VPageChannelElem.
+ */
+}
+#include "vmware_pack_end.h"
+VPageChannelBuffer;
+
+typedef
+#include "vmware_pack_begin.h"
+struct VPageChannelGuestConnectMessage {
+ VMCIHandle dgHandle;
+ VMCIHandle qpHandle;
+ uint64 produceQSize;
+ uint64 consumeQSize;
+ VMCIHandle doorbellHandle;
+}
+#include "vmware_pack_end.h"
+VPageChannelGuestConnectMessage;
+
+typedef
+#include "vmware_pack_begin.h"
+struct VPageChannelHyperConnectMessage {
+ VMCIHandle doorbellHandle;
+}
+#include "vmware_pack_end.h"
+VPageChannelHyperConnectMessage;
+
+struct VPageChannel;
+typedef struct VPageChannel VPageChannel;
+
+typedef void (*VPageChannelRecvCB)(void *clientData,
+ VPageChannelPacket *packet);
+
+
+#if !defined(VMKERNEL)
+
+typedef int (*VPageChannelAllocElemFn)(void *clientData,
+ VPageChannelElem *elems,
+ int numElems);
+
+typedef void (*VPageChannelFreeElemFn)(void *clientData,
+ VPageChannelElem *elems,
+ int numElems);
+
+int VPageChannel_CreateInVM(VPageChannel **channel,
+ VMCIId resourceId,
+ VMCIId peerResourceId,
+ uint64 produceQSize,
+ uint64 consumeQSize,
+ VPageChannelRecvCB recvCB,
+ void *clientRecvData,
+ Bool notifyOnly,
+ VPageChannelAllocElemFn elemAlloc,
+ void *allocClientData,
+ VPageChannelFreeElemFn elemFree,
+ void *freeClientData,
+ int defaultRecvBuffers,
+ int maxRecvBuffers);
+
+/*
+ * Send a packet to the hypervisor. The message is copied and the buffers
+ * represented by the scatter-gather list of (pa, le) are sent to the
+ * hypervisor. The buffers belong to the hypervisor until it sends a completion
+ * notification using VPageChannel_CompletionNotify().
+ */
+
+int VPageChannel_SendInVM(VPageChannel *channel, VPageChannelPacket *packet);
+
+#else // VMKERNEL
+
+int VPageChannel_CreateInVMK(VPageChannel **channel,
+ VMCIId resourceId,
+ VPageChannelRecvCB recvCB,
+ void *clientRecvData);
+
+int VPageChannel_ReserveBuffers(VPageChannel *channel,
+ size_t dataLen,
+ VPageChannelBuffer **buffer);
+void VPageChannel_ReleaseBuffers(VPageChannel *channel,
+ VPageChannelBuffer *buffer,
+ Bool returnToFreePool);
+
+/*
+ * This function is called when the client is finished using the
+ * scatter-gather list of a packet. This will generate a notification to the
+ * guest to pass the ownership of buffers back to the guest. This can also be
+ * used to read back the data from hypervisor and send it the to guest.
+ */
+
+int VPageChannel_CompletionNotify(VPageChannel *channel,
+ char *message,
+ int len,
+ VPageChannelBuffer *buffer);
+
+int VPageChannel_MapToMa(VPageChannel *channel,
+ VPageChannelElem paElem,
+ VPageChannelElem *maElems,
+ uint32 numElems);
+int VPageChannel_UnmapMa(VPageChannel *channel,
+ VPageChannelBuffer *buffer,
+ int numElems);
+
+#endif // VMKERNEL
+
+/*
+ * Common functions.
+ */
+
+void VPageChannel_Destroy(VPageChannel *channel);
+int VPageChannel_Send(VPageChannel *channel,
+ VPageChannelPacketType type,
+ char *message,
+ int len,
+ VPageChannelBuffer *buffer);
+int VPageChannel_SendPacket(VPageChannel *channel,
+ VPageChannelPacket *packet);
+void VPageChannel_PollRecvQ(VPageChannel *channel);
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * VPageChannelPacket_BufferLen --
+ *
+ * Calculate the length of the given packet.
+ *
+ * Results:
+ * The length of the given packet in bytes.
+ *
+ * Side effects:
+ * None.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static INLINE size_t
+VPageChannelPacket_BufferLen(VPageChannelPacket *packet) // IN
+{
+ size_t len, i;
+ VPageChannelElem *elems;
+
+ ASSERT(packet);
+
+ len = 0;
+ elems = VPAGECHANNEL_PACKET_ELEMS(packet);
+ for (i = 0; i < packet->numElems; i++) {
+ len += elems[i].le;
+ }
+
+ return len;
+}
+
+
+#if defined(linux) && !defined(VMKERNEL)
+#include "compat_pci.h"
+#define vmci_pci_map_page(_pg, _off, _sz, _dir) \
+ pci_map_page(NULL, (_pg), (_off), (_sz), (_dir))
+#define vmci_pci_unmap_page(_dma, _sz, _dir) \
+ pci_unmap_page(NULL, (_dma), (_sz), (_dir))
+#endif // linux && !VMKERNEL
+
+#endif // _VMCI_PACKET_H_
* VixTools_SetRunProgramCallback --
*
* Register a callback that reports when a program has completed.
- * Different clients of this library will use different IPC mechanisms for
+ * Different clients of this library will use different IPC mechanisms for
* sending this message. For example, it may use the backdoor or a socket.
* Different sockets may use different message protocols, such as the backdoor-on-a-socket
* or the Foundry network message.
if (runProgramRequest->runProgramOptions & VIX_RUNPROGRAM_RUN_AS_LOCAL_SYSTEM) {
if (!VixToolsUserIsMemberOfAdministratorGroup(requestMsg)) {
err = VIX_E_GUEST_USER_PERMISSIONS;
- goto abort;
+ goto abort;
}
userToken = PROCESS_CREATOR_USER_TOKEN;
}
#endif
-
+
if (NULL == userToken) {
err = VixToolsImpersonateUser(requestMsg, &userToken);
if (VIX_OK != err) {
userToken,
eventQueue,
&pid);
-
+
abort:
if (impersonatingVMWareUser) {
VixToolsUnimpersonateUser(userToken);
* On linux, we run the program by exec'ing /bin/sh, and that does not
* return a clear error code indicating that the program does not exist
* or cannot be executed.
- * This is a common and user-correctable error, however, so we want to
+ * This is a common and user-correctable error, however, so we want to
* check for it and return a specific error code in this case.
*
*/
programExists = File_Exists(startProgramFileName);
- programIsExecutable =
- (FileIO_Access(startProgramFileName, FILEIO_ACCESS_EXEC) ==
+ programIsExecutable =
+ (FileIO_Access(startProgramFileName, FILEIO_ACCESS_EXEC) ==
FILEIO_SUCCESS);
free(tempCommandLine);
packageList = "";
if (confDictRef != NULL) {
- powerOffScript = g_key_file_get_string(confDictRef, "powerops",
+ powerOffScript = g_key_file_get_string(confDictRef, "powerops",
CONFNAME_POWEROFFSCRIPT, NULL);
powerOnScript = g_key_file_get_string(confDictRef, "powerops",
CONFNAME_POWERONSCRIPT, NULL);
* if pathName is an invalid symbolic link, we still want to delete it.
*/
if (FALSE == File_IsSymLink(pathName)) {
- if (!(File_Exists(pathName))) {
+ if (!(File_Exists(pathName))) {
err = VIX_E_FILE_NOT_FOUND;
goto abort;
}
goto abort;
}
#endif
- /*
+ /*
* At this point, we want to set environmental variable for current
* user, even if the current user is root/administrator
*/
default:
err = VIX_E_OP_NOT_SUPPORTED_ON_GUEST;
break;
- } // switch (readRequest->variableType)
+ } // switch (readRequest->variableType)
abort:
if (impersonatingVMWareUser) {
err = VIX_E_INVALID_ARG;
goto abort;
}
-
+
err = VixToolsImpersonateUser(requestMsg, &userToken);
if (VIX_OK != err) {
goto abort;
ASSERT_MEM_ALLOC(NULL != escapedFileName);
}
- *destPtr += Str_Sprintf(*destPtr,
- endDestPtr - *destPtr,
+ *destPtr += Str_Sprintf(*destPtr,
+ endDestPtr - *destPtr,
fileInfoFormatString,
fileName,
fileProperties,
interpreterName = "/bin/sh";
#endif
}
-
+
if (*interpreterName) {
programExists = File_Exists(interpreterName);
* thinking.
*/
- programIsExecutable =
+ programIsExecutable =
(FileIO_Access(interpreterName, FILEIO_ACCESS_EXEC) ==
FILEIO_SUCCESS);
if (!programExists) {
goto abort;
}
}
-
+
/*
* Create a temporary file that we can run as a script.
* TODO: Plumb a file suffix/extention throught to the File
if (PROCESS_CREATOR_USER_TOKEN != userToken) {
err = VixToolsGetUserTmpDir(userToken, &tempDirPath);
- /*
+ /*
* Don't give up if VixToolsGetUserTmpDir() failed. It might just
* have failed to load DLLs, so we might be running on Win 9x.
* Just fall through to use the old fashioned File_GetSafeTmpDir().
}
for (var = 0; var <= 0xFFFFFFFF; var++) {
free(tempScriptFilePath);
- tempScriptFilePath = Str_Asprintf(NULL,
- "%s"DIRSEPS"%s%d%s",
- tempDirPath,
- scriptFileBaseName,
- var,
+ tempScriptFilePath = Str_Asprintf(NULL,
+ "%s"DIRSEPS"%s%d%s",
+ tempDirPath,
+ scriptFileBaseName,
+ var,
fileSuffix);
if (NULL == tempScriptFilePath) {
err = VIX_E_OUT_OF_MEMORY;
goto abort;
}
-
+
fd = Posix_Open(tempScriptFilePath, // UTF-8
O_CREAT | O_EXCL
#if defined(_WIN32)
if (writeResult < 0) {
/*
- * Yes, I'm duplicating code by running this check before the call to
+ * Yes, I'm duplicating code by running this check before the call to
* close(), but if close() succeeds it will clobber the errno, causing
* something confusing to be reported to the user.
*/
if ((NULL != interpreterName) && (*interpreterName)) {
fullCommandLine = Str_Asprintf(NULL, // resulting string length
- "\"%s\" %s \"%s\"",
+ "\"%s\" %s \"%s\"",
interpreterName,
interpreterFlags,
tempScriptFilePath);
} else {
fullCommandLine = Str_Asprintf(NULL, // resulting string length
- "\"%s\"",
+ "\"%s\"",
tempScriptFilePath);
}
credentialType = requestMsg->userCredentialType;
- if (VIX_USER_CREDENTIAL_TICKETED_SESSION == credentialType) {
+ switch (credentialType) {
+ case VIX_USER_CREDENTIAL_TICKETED_SESSION:
+ {
VixCommandTicketedSession *commandTicketedSession = (VixCommandTicketedSession *) credentialField;
size_t ticketLength = commandTicketedSession->ticketLength;
credentialType,
credentialField,
userToken);
-
- } else if (VIX_USER_CREDENTIAL_SSPI == credentialType) {
- /*
- * SSPI currently only supported in ticketed sessions
- */
- err = VIX_E_NOT_SUPPORTED;
-
- } else {
- VixCommandNamePassword *namePasswordStruct = (VixCommandNamePassword *) credentialField;
+ break;
+ }
+ case VIX_USER_CREDENTIAL_ROOT:
+ case VIX_USER_CREDENTIAL_CONSOLE_USER:
+ err = VixToolsImpersonateUserImplEx(NULL,
+ credentialType,
+ NULL,
+ userToken);
+ break;
+ case VIX_USER_CREDENTIAL_NAME_PASSWORD:
+ case VIX_USER_CREDENTIAL_NAME_PASSWORD_OBFUSCATED:
+ case VIX_USER_CREDENTIAL_NAMED_INTERACTIVE_USER:
+ {
+ VixCommandNamePassword *namePasswordStruct =
+ (VixCommandNamePassword *) credentialField;
credentialField += sizeof(*namePasswordStruct);
err = VixToolsImpersonateUserImplEx(NULL,
credentialField,
userToken);
if ((VIX_OK != err)
- && ((VIX_USER_CREDENTIAL_NAME_PASSWORD_OBFUSCATED == credentialType)
- || (VIX_USER_CREDENTIAL_NAME_PASSWORD == credentialType))) {
+ && ((VIX_USER_CREDENTIAL_NAME_PASSWORD_OBFUSCATED == credentialType)
+ || (VIX_USER_CREDENTIAL_NAME_PASSWORD == credentialType))) {
/*
* Windows does not allow you to login with an empty password. Only
* the console allows this login, which means the console does not
}
#endif
}
+ break;
+ }
+ case VIX_USER_CREDENTIAL_SSPI:
+ /*
+ * SSPI currently only supported in ticketed sessions
+ */
+ default:
+ Debug("%s: credentialType = %d\n", __FUNCTION__, credentialType);
+ err = VIX_E_NOT_SUPPORTED;
}
Debug("<%s\n", __FUNCTION__);
*
* VixToolsImpersonateUserImpl --
*
- * Little compatability wrapper for legacy Foundry Tools implementations.
+ * Little compatability wrapper for legacy Foundry Tools implementations.
*
* Return value:
* TRUE on success
* VixToolsImpersonateUserImplEx --
*
* On Windows:
- * To retrieve the security context of another user
- * call LogonUser to log the user whom you want to impersonate on to the
- * local computer, specifying the name of the user account, the user's
- * domain, and the user's password. This function returns a pointer to
+ * To retrieve the security context of another user
+ * call LogonUser to log the user whom you want to impersonate on to the
+ * local computer, specifying the name of the user account, the user's
+ * domain, and the user's password. This function returns a pointer to
* a handle to the access token of the logged-on user as an out parameter.
- * Call ImpersonateLoggedOnUser using the handle to the access token obtained
+ * Call ImpersonateLoggedOnUser using the handle to the access token obtained
* in the call to LogonUser.
- * Run RegEdt32 to load the registry hive of the impersonated user manually.
+ * Run RegEdt32 to load the registry hive of the impersonated user manually.
*
* Return value:
* VIX_OK on success, or an appropriate error code on failure.
*/
#if defined(__linux__) || defined(_WIN32)
-VixError
+VixError
VixToolsGetGuestNetworkingConfig(VixCommandRequestHeader *requestMsg, // IN
char **resultBuffer, // OUT
size_t *resultBufferLength) // OUT
*/
#if defined(_WIN32)
-VixError
+VixError
VixToolsSetGuestNetworkingConfig(VixCommandRequestHeader *requestMsg) // IN
{
VixError err = VIX_OK;
VixPropertyListImpl propList;
VixPropertyValue *propertyPtr = NULL;
char *messageBody = NULL;
- char ipAddr[IP_ADDR_SIZE];
+ char ipAddr[IP_ADDR_SIZE];
char subnetMask[IP_ADDR_SIZE];
Bool dhcpEnabled = FALSE;
HRESULT hrErr;
ASSERT(NULL != requestMsg);
- ipAddr[0] = '\0';
+ ipAddr[0] = '\0';
subnetMask[0] = '\0';
-
+
err = VixToolsImpersonateUser(requestMsg, &userToken);
if (VIX_OK != err) {
goto abort;
messageBody = (char *) requestMsg + sizeof(*setGuestNetworkingConfigRequest);
VixPropertyList_Initialize(&propList);
- err = VixPropertyList_Deserialize(&propList,
- messageBody,
+ err = VixPropertyList_Deserialize(&propList,
+ messageBody,
setGuestNetworkingConfigRequest -> bufferSize,
VIX_PROPERTY_LIST_BAD_ENCODING_ERROR);
if (VIX_OK != err) {
switch (propertyPtr->propertyID) {
///////////////////////////////////////////
case VIX_PROPERTY_VM_DHCP_ENABLED:
- if (propertyPtr->value.boolValue) {
+ if (propertyPtr->value.boolValue) {
dhcpEnabled = TRUE;
}
break;
- ///////////////////////////////////////////
+ ///////////////////////////////////////////
case VIX_PROPERTY_VM_IP_ADDRESS:
if (strlen(propertyPtr->value.strValue) < sizeof ipAddr) {
Str_Strcpy(ipAddr,
- propertyPtr->value.strValue,
+ propertyPtr->value.strValue,
sizeof ipAddr);
} else {
err = VIX_E_INVALID_ARG;
///////////////////////////////////////////
case VIX_PROPERTY_VM_SUBNET_MASK:
if (strlen(propertyPtr->value.strValue) < sizeof subnetMask) {
- Str_Strcpy(subnetMask,
+ Str_Strcpy(subnetMask,
propertyPtr->value.strValue,
- sizeof subnetMask);
+ sizeof subnetMask);
} else {
err = VIX_E_INVALID_ARG;
goto abort;
}
- break;
-
+ break;
+
///////////////////////////////////////////
default:
/*
* Be more tolerant. Igonore unknown properties.
*/
break;
- } // switch
+ } // switch
propertyPtr = propertyPtr->next;
} // while {propList.properties != NULL)
hrErr = VixToolsEnableDHCPOnPrimary();
} else {
if (('\0' != ipAddr[0]) ||
- ('\0' != subnetMask[0])) {
+ ('\0' != subnetMask[0])) {
hrErr = VixToolsEnableStaticOnPrimary(ipAddr, subnetMask);
} else {
/*
err = Vix_TranslateCOMError(hrErr);
} else {
err = Vix_TranslateSystemError(hrErr);
- }
+ }
}
abort:
struct passwd *ppwd = &pwd;
char *buffer = NULL; // a pool of memory for Posix_Getpwnam_r() to use.
size_t bufferSize;
-
+
/*
* For POSIX systems, look up the uid of 'username', and compare
* it to the uid of the owner of this process. This handles systems
* where multiple usernames map to the name user.
*/
-
+
/*
* Get the maximum size buffer needed by getpwuid_r.
* Multiply by 4 to compensate for the conversion to UTF-8 by
if (Posix_Getpwnam_r(username, &pwd, buffer, bufferSize, &ppwd) != 0 ||
NULL == ppwd) {
- /*
+ /*
* This username should exist, since it should have already
* been validated by guestd. Assume it is a system error.
*/
Util_ZeroFree(buffer, bufferSize);
#endif
-
+
return err;
}
size_t resultValueLength = 0;
Bool mustSetResultValueLength = TRUE;
Bool deleteResultValue = FALSE;
-
+
if (NULL != resultBuffer) {
*resultBuffer = NULL;
&resultValueLength);
if (VIX_FAILED(err)) {
/*
- * VixToolsGetGuestNetworkingConfig() failed, so resultVal is still NULL,
- * so let it get replaced with the empty string at the abort label.
+ * VixToolsGetGuestNetworkingConfig() failed, so resultVal is still NULL,
+ * so let it get replaced with the empty string at the abort label.
*/
goto abort;
}
*-----------------------------------------------------------------------------
*
* VixToolsEnableDHCPOnPrimary --
- *
+ *
* Enable DHCP on primary NIC. A primary NIC is the
* first interface you get using ipconfig. You can change the order
* of NIC cards on a computer via Windows GUI.
*
* Side effects:
* None.
- *
+ *
*-----------------------------------------------------------------------------
*/
*-----------------------------------------------------------------------------
*
* VixToolsEnableStaticOnPrimary --
- *
- * Set the IP address and/or subnet mask of the primary NIC. A primary NIC
+ *
+ * Set the IP address and/or subnet mask of the primary NIC. A primary NIC
* is the first interface you get using ipconfig. You can change the order
- * of NIC cards on a computer via Windows GUI.
+ * of NIC cards on a computer via Windows GUI.
*
* Results:
* S_OK on success. COM error codes on failure.
*
* Side effects:
* None.
- *
+ *
*-----------------------------------------------------------------------------
*/
char actualIpAddress[IP_ADDR_SIZE];
char actualSubnetMask[IP_ADDR_SIZE];
- if ((NULL == ipAddr) ||
+ if ((NULL == ipAddr) ||
(NULL == subnetMask)) {
return E_INVALIDARG;
}
/*
* Set IP address if client provides it.
*/
-
+
primaryIp = &primaryNic->ips.ips_val[0];
-
+
if ('\0' != ipAddr[0]) {
Str_Strcpy(actualIpAddress,
ipAddr,
*/
if ('\0' != subnetMask[0]) {
Str_Strcpy(actualSubnetMask,
- subnetMask,
+ subnetMask,
sizeof actualSubnetMask);
} else {
Str_Strcpy(actualSubnetMask,
sizeof actualSubnetMask);
}
- ret = WMI_EnableStatic(primaryNic->macAddress,
- actualIpAddress,
+ ret = WMI_EnableStatic(primaryNic->macAddress,
+ actualIpAddress,
actualSubnetMask);
VMX_XDR_FREE(xdr_GuestNic, primaryNic);