* -------------- NEW -------------
* | |
* \_/ \_/
- * CREATED (nomem) <-----------------> CREATED
+ * CREATED_NO_MEM <-----------------> CREATED_MEM
* | | |
* | o-----------------------o |
* | | |
* \_/ \_/ \_/
- * ATTACHED (nomem) <----------------> ATTACHED
+ * ATTACHED_NO_MEM <----------------> ATTACHED_MEM
* | | |
* | o----------------------o |
* | | |
* \_/ \_/ \_/
- * SHUTDOWN (nomem) <----------------> SHUTDOWN
+ * SHUTDOWN_NO_MEM <----------------> SHUTDOWN_MEM
* | |
* | |
* -------------> gone <-------------
*
* In more detail. When a VMCI queue pair is first created, it will be in the
* VMCIQPB_NEW state. It will then move into one of the following states:
- * - VMCIQPB_CREATED with hasMem[0] FALSE: this state indicates that either:
+ * - VMCIQPB_CREATED_NO_MEM: this state indicates that either:
* - the created was performed by a host endpoint, in which case there is no
* backing memory yet.
* - the create was initiated by an old-style VMX, that uses
* later point in time. This state can be distinguished from the one above
* by the context ID of the creator. A host side is not allowed to attach
* until the page store has been set.
- * - VMCIQPB_CREATED with hasMem[0] TRUE: this state is the result when the
- * queue pair is created by a VMX using the queue pair device backend that
- * sets the UVAs of the queue pair immediately and stores the information
- * for later attachers. At this point, it is ready for the host side to attach
- * to it.
+ * - VMCIQPB_CREATED_MEM: this state is the result when the queue pair is created
+ * by a VMX using the queue pair device backend that sets the UVAs of the
+ * queue pair immediately and stores the information for later attachers. At
+ * this point, it is ready for the host side to attach to it.
* Once the queue pair is in one of the created states (with the exception of the
* case mentioned for older VMX'en above), it is possible to attach to the queue
* pair. Again we have two new states possible:
- * - VMCIQPB_ATTACHED with hasMem[0] TRUE: this state can be reached through
- * the following paths:
- * - from VMCIQPB_CREATED without memory when a new-style VMX allocates a queue pair,
+ * - VMCIQPB_ATTACHED_MEM: this state can be reached through the following paths:
+ * - from VMCIQPB_CREATED_NO_MEM when a new-style VMX allocates a queue pair,
* and attaches to a queue pair previously created by the host side.
- * - from VMCIQPB_CREATED with memory when the host side attaches to a queue pair
+ * - from VMCIQPB_CREATED_MEM when the host side attaches to a queue pair
* already created by a guest.
- * - from VMCIQPB_ATTACHED without memory, when an old-style VMX calls
+ * - from VMCIQPB_ATTACHED_NO_MEM, when an old-style VMX calls
* VMCIQPBroker_SetPageStore (see below).
- * - VMCIQPB_ATTACHED with hasMem[0] FALSE: If the queue pair already was in the
- * VMCIQPB_CREATED without memory due to a host side create, an old-style VMX
- * will bring the queue pair into this state. Once VMCIQPBroker_SetPageStore is
- * called to register the user memory, the VMCIQPB_ATTACH with memory state will be
+ * - VMCIQPB_ATTACHED_NO_MEM: If the queue pair already was in the
+ * VMCIQPB_CREATED_NO_MEM due to a host side create, an old-style VMX will
+ * bring the queue pair into this state. Once VMCIQPBroker_SetPageStore is
+ * called to register the user memory, the VMCIQPB_ATTACH_MEM state will be
* entered.
* From the attached queue pair, the queue pair can enter the shutdown states
* when either side of the queue pair detaches. If the guest side detaches first,
- * the queue pair will enter the VMCIQPB_SHUTDOWN without memory state, where the content
+ * the queue pair will enter the VMCIQPB_SHUTDOWN_NO_MEM state, where the content
* of the queue pair will no longer be available. If the host side detaches first,
- * the queue pair will either enter the VMCIQPB_SHUTDOWN with memory, if the guest memory
- * is currently mapped, or VMCIQPB_SHUTDOWN without memory, if the guest memory is not
+ * the queue pair will either enter the VMCIQPB_SHUTDOWN_MEM, if the guest memory
+ * is currently mapped, or VMCIQPB_SHUTDOWN_NO_MEM, if the guest memory is not
* mapped (e.g., the host detaches while a guest is stunned).
*
* New-style VMX'en will also unmap guest memory, if the guest is quiesced, e.g.,
* during a snapshot operation. In that case, the guest memory will no longer be
- * available, and the queue pair will transition from memory to memory-less state.
- * The VMX may later map the memory once more, in which case the queue
- * pair will transition from the memory-less state at that point back to the memory
- * state.
+ * available, and the queue pair will transition from *_MEM state to a *_NO_MEM
+ * state. The VMX may later map the memory once more, in which case the queue
+ * pair will transition from the *_NO_MEM state at that point back to the *_MEM
+ * state. Note that the *_NO_MEM state may have changed, since the peer may have
+ * either attached or detached in the meantime. The values are laid out such that
+ * ++ on a state will move from a *_NO_MEM to a *_MEM state, and vice versa.
*/
typedef enum {
VMCIQPB_NEW,
- VMCIQPB_CREATED,
- VMCIQPB_ATTACHED,
- VMCIQPB_SHUTDOWN,
+ VMCIQPB_CREATED_NO_MEM,
+ VMCIQPB_CREATED_MEM,
+ VMCIQPB_ATTACHED_NO_MEM,
+ VMCIQPB_ATTACHED_MEM,
+ VMCIQPB_SHUTDOWN_NO_MEM,
+ VMCIQPB_SHUTDOWN_MEM,
VMCIQPB_GONE
} QPBrokerState;
+#define QPBROKERSTATE_HAS_MEM(_qpb) (_qpb->state == VMCIQPB_CREATED_MEM || \
+ _qpb->state == VMCIQPB_ATTACHED_MEM || \
+ _qpb->state == VMCIQPB_SHUTDOWN_MEM)
/*
* In the queue pair broker, we always use the guest point of view for
QueuePairEntry qp;
VMCIId createId;
VMCIId attachId;
- QPBrokerState stateQP;
- Bool hasMem[2];
+ QPBrokerState state;
Bool requireTrustedAttach;
Bool createdByTrusted;
Bool vmciPageFiles; // Created by VMX using VMCI page files
VMCIEventReleaseCB wakeupCB;
void *clientData;
void *localMem; // Kernel memory for local queue pair
- Bool isVM2VM;
} QPBrokerEntry;
#if !defined(VMKERNEL)
void *clientData);
static int VMCIQueuePairDetachHostWork(VMCIHandle handle);
-static int QueuePairSaveHeaders(QPBrokerEntry *entry, VMCIId contextId);
+static int QueuePairSaveHeaders(QPBrokerEntry *entry);
static void QueuePairResetSavedHeaders(QPBrokerEntry *entry);
#if !defined(VMKERNEL)
#endif
-/*
- *-----------------------------------------------------------------------------
- *
- * VMCIQPBEGetIndex --
- *
- * Retrieve index into host's queue structures for queue entry.
- *
- * Results:
- * 0 or 1. Or crash.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-static unsigned int
-VMCIQPBEGetIndex(const QPBrokerEntry *entry, // IN
- VMCIId contextId) // IN
-{
- ASSERT(entry->createId == contextId || entry->attachId == contextId);
-
- return (entry->isVM2VM && entry->createId != contextId) ? 1 : 0;
-}
-
-
/*
*-----------------------------------------------------------------------------
*
int result;
uint64 guestProduceSize;
uint64 guestConsumeSize;
- Bool isVM2VM;
/*
* Do not create if the caller asked not to.
return VMCI_ERROR_NO_ACCESS;
}
- isVM2VM = VMCI_CONTEXT_IS_VM(contextId) && VMCI_CONTEXT_IS_VM(peer);
- if (isVM2VM) {
+ if (VMCI_CONTEXT_IS_VM(contextId) && VMCI_CONTEXT_IS_VM(peer)) {
VMCI_DEBUG_LOG(5, ("QP Create - VM2VM\n"));
return VMCI_ERROR_DST_UNREACHABLE;
}
entry->qp.refCount = 1;
entry->createId = contextId;
entry->attachId = VMCI_INVALID_ID;
- entry->stateQP = VMCIQPB_NEW;
+ entry->state = VMCIQPB_NEW;
entry->requireTrustedAttach =
(context->privFlags & VMCI_PRIVILEGE_FLAG_RESTRICTED) ? TRUE : FALSE;
entry->createdByTrusted =
entry->vmciPageFiles = FALSE;
entry->wakeupCB = wakeupCB;
entry->clientData = clientData;
- entry->isVM2VM = FALSE; /* It is not VM2VM until VM attaches... */
entry->produceQ = VMCIHost_AllocQueue(guestProduceSize);
if (entry->produceQ == NULL) {
result = VMCI_ERROR_NO_MEM;
VMCI_DEBUG_LOG(5, ("QP Create - no memory LM\n"));
goto error;
}
- entry->stateQP = VMCIQPB_CREATED;
- entry->hasMem[0] = TRUE;
+ entry->state = VMCIQPB_CREATED_MEM;
entry->produceQ->qHeader = entry->localMem;
entry->consumeQ->qHeader =
(VMCIQueueHeader *)((uint8 *)entry->localMem +
VMCIQueueHeader_Init(entry->produceQ->qHeader, handle);
VMCIQueueHeader_Init(entry->consumeQ->qHeader, handle);
} else if (pageStore) {
- ASSERT(entry->createId != VMCI_HOST_CONTEXT_ID);
+ ASSERT(entry->createId != VMCI_HOST_CONTEXT_ID || isLocal);
/*
* The VMX already initialized the queue pair headers, so no
* need for the kernel side to do that.
*/
- result = VMCIHost_RegisterUserMemory(0, pageStore,
+ result = VMCIHost_RegisterUserMemory(pageStore,
entry->produceQ,
entry->consumeQ);
if (result < VMCI_SUCCESS) {
VMCI_DEBUG_LOG(5, ("QP Create - cannot register user memory\n"));
goto error;
}
- VMCIHost_MarkQueuesAvailable(0, entry->produceQ, entry->consumeQ);
- entry->stateQP = VMCIQPB_CREATED;
- entry->hasMem[0] = TRUE;
+ VMCIHost_MarkQueuesAvailable(entry->produceQ, entry->consumeQ);
+ entry->state = VMCIQPB_CREATED_MEM;
} else {
/*
* A create without a pageStore may be either a host side create (in which
* call as the next step).
*/
- entry->stateQP = VMCIQPB_CREATED;
+ entry->state = VMCIQPB_CREATED_NO_MEM;
}
QueuePairList_AddEntry(&qpBrokerList, &entry->qp);
const VMCIId contextId = VMCIContext_GetId(context);
Bool isLocal = flags & VMCI_QPFLAG_LOCAL;
int result;
- Bool isVM2VM;
- if (entry->stateQP != VMCIQPB_CREATED) {
- VMCI_DEBUG_LOG(5, ("QP Attach - state is %x\n", entry->stateQP));
+ if (entry->state != VMCIQPB_CREATED_NO_MEM &&
+ entry->state != VMCIQPB_CREATED_MEM) {
+ VMCI_DEBUG_LOG(5, ("QP Attach - state is %x\n", entry->state));
return VMCI_ERROR_UNAVAILABLE;
}
ASSERT(entry->qp.refCount < 2);
ASSERT(entry->attachId == VMCI_INVALID_ID);
- isVM2VM = VMCI_CONTEXT_IS_VM(contextId) && VMCI_CONTEXT_IS_VM(entry->createId);
- if (isVM2VM) {
+ if (VMCI_CONTEXT_IS_VM(contextId) && VMCI_CONTEXT_IS_VM(entry->createId)) {
VMCI_DEBUG_LOG(5, ("QP Attach - VM2VM\n"));
return VMCI_ERROR_DST_UNREACHABLE;
}
return VMCI_ERROR_QUEUEPAIR_MISMATCH;
}
- if (contextId != VMCI_HOST_CONTEXT_ID && !isVM2VM) {
+ if (contextId != VMCI_HOST_CONTEXT_ID) {
/*
* The queue pair broker entry stores values from the guest
* point of view, so an attaching guest should match the values
* any memory associated with it already.
*/
- if (isVM2VM) {
- if (!pageStore || entry->stateQP != VMCIQPB_CREATED) {
- VMCI_DEBUG_LOG(5, ("QP Attach - bad QP state for VM2VM, %x, %p\n", entry->stateQP, pageStore));
- return VMCI_ERROR_INVALID_ARGS;
- }
- } else {
- if (entry->stateQP != VMCIQPB_CREATED || entry->hasMem[0]) {
- VMCI_DEBUG_LOG(5, ("QP Attach - bad QP state, %x\n", entry->stateQP));
- return VMCI_ERROR_INVALID_ARGS;
- }
+ if (entry->state != VMCIQPB_CREATED_NO_MEM) {
+ VMCI_DEBUG_LOG(5, ("QP Attach - bad QP state for VM2VM, %x, %p\n",
+ entry->state, pageStore));
+ return VMCI_ERROR_INVALID_ARGS;
}
if (pageStore != NULL) {
- unsigned int index;
-
- ASSERT(entry->isVM2VM == FALSE);
- entry->isVM2VM = isVM2VM;
-
/*
* Patch up host state to point to guest supplied memory. The VMX
* already initialized the queue pair headers, so no need for the
* kernel side to do that.
*/
- index = isVM2VM ? 1 : 0;
- result = VMCIHost_RegisterUserMemory(index,
- pageStore,
+ result = VMCIHost_RegisterUserMemory(pageStore,
entry->produceQ,
entry->consumeQ);
if (result < VMCI_SUCCESS) {
VMCI_DEBUG_LOG(5, ("QP Attach - cannot register memory\n"));
- entry->isVM2VM = FALSE;
return result;
}
- VMCIHost_MarkQueuesAvailable(index, entry->produceQ, entry->consumeQ);
+ VMCIHost_MarkQueuesAvailable(entry->produceQ, entry->consumeQ);
if (entry->qp.flags & VMCI_QPFLAG_NONBLOCK) {
- result = VMCIHost_MapQueues(index, entry->produceQ, entry->consumeQ,
+ result = VMCIHost_MapQueues(entry->produceQ, entry->consumeQ,
entry->qp.flags);
if (result < VMCI_SUCCESS) {
- VMCIHost_ReleaseUserMemory(index, entry->produceQ, entry->consumeQ);
- entry->isVM2VM = FALSE;
+ VMCIHost_ReleaseUserMemory(entry->produceQ, entry->consumeQ);
VMCI_DEBUG_LOG(5, ("QP Attach - cannot map queues\n"));
return result;
}
}
- entry->stateQP = VMCIQPB_ATTACHED;
- entry->hasMem[index] = TRUE;
+ entry->state = VMCIQPB_ATTACHED_MEM;
} else {
- entry->stateQP = VMCIQPB_ATTACHED;
+ entry->state = VMCIQPB_ATTACHED_NO_MEM;
}
- } else if (entry->stateQP == VMCIQPB_CREATED && !entry->hasMem[0]) {
+ } else if (entry->state == VMCIQPB_CREATED_NO_MEM) {
/*
* The host side is attempting to attach to a queue pair that doesn't have
* any memory associated with it. This must be a pre NOVMVM vmx that hasn't
*/
if (flags & VMCI_QPFLAG_NONBLOCK) {
- /*
- * We only have to do work here if this is a host-to-VM queuepair.
- * Otherwise there's nothing to map, since the pages backing the
- * queues are allocated directly out of host memory.
- */
-
- if (!isLocal) {
- VMCIHost_MarkQueuesAvailable(0, entry->produceQ, entry->consumeQ);
- result = VMCIHost_MapQueues(0, entry->produceQ, entry->consumeQ, flags);
- if (result < VMCI_SUCCESS) {
- VMCI_DEBUG_LOG(5, ("QP Attach - cannot map queues for host\n"));
- return result;
- }
+ result = VMCIHost_MapQueues(entry->produceQ, entry->consumeQ, flags);
+ if (result < VMCI_SUCCESS) {
+ VMCI_DEBUG_LOG(5, ("QP Attach - cannot map queues for host\n"));
+ return result;
}
entry->qp.flags |= flags & (VMCI_QPFLAG_NONBLOCK | VMCI_QPFLAG_PINNED);
}
* The host side has successfully attached to a queue pair.
*/
- entry->stateQP = VMCIQPB_ATTACHED;
+ entry->state = VMCIQPB_ATTACHED_MEM;
}
- if (entry->stateQP == VMCIQPB_ATTACHED && entry->hasMem[0] && (!entry->isVM2VM || entry->hasMem[1])) {
+ if (entry->state == VMCIQPB_ATTACHED_MEM) {
result = QueuePairNotifyPeer(TRUE, entry->qp.handle, contextId,
entry->createId);
if (result < VMCI_SUCCESS) {
QPBrokerEntry *entry;
int result;
const VMCIId contextId = VMCIContext_GetId(context);
- unsigned int index;
if (VMCI_HANDLE_INVALID(handle) || !context || contextId == VMCI_INVALID_ID) {
return VMCI_ERROR_INVALID_ARGS;
goto out;
}
- index = VMCIQPBEGetIndex(entry, contextId);
-
- if (entry->hasMem[index] ||
- (entry->stateQP != VMCIQPB_CREATED && entry->stateQP == VMCIQPB_ATTACHED)) {
+ if (entry->state != VMCIQPB_CREATED_NO_MEM &&
+ entry->state != VMCIQPB_ATTACHED_NO_MEM) {
result = VMCI_ERROR_UNAVAILABLE;
goto out;
}
- result = VMCIHost_GetUserMemory(index, produceUVA, consumeUVA,
+ result = VMCIHost_GetUserMemory(produceUVA, consumeUVA,
entry->produceQ, entry->consumeQ);
if (result < VMCI_SUCCESS) {
goto out;
}
- VMCIHost_MarkQueuesAvailable(index, entry->produceQ, entry->consumeQ);
- result = VMCIHost_MapQueues(index, entry->produceQ, entry->consumeQ, 0);
+ VMCIHost_MarkQueuesAvailable(entry->produceQ, entry->consumeQ);
+ result = VMCIHost_MapQueues(entry->produceQ, entry->consumeQ, FALSE);
if (result < VMCI_SUCCESS) {
- VMCIHost_ReleaseUserMemory(index, entry->produceQ, entry->consumeQ);
+ VMCIHost_ReleaseUserMemory(entry->produceQ, entry->consumeQ);
goto out;
}
- entry->hasMem[index] = TRUE;
+ if (entry->state == VMCIQPB_CREATED_NO_MEM) {
+ entry->state = VMCIQPB_CREATED_MEM;
+ } else {
+ ASSERT(entry->state == VMCIQPB_ATTACHED_NO_MEM);
+ entry->state = VMCIQPB_ATTACHED_MEM;
+ }
entry->vmciPageFiles = TRUE;
- if (entry->stateQP == VMCIQPB_ATTACHED && entry->hasMem[0] && (!entry->isVM2VM || entry->hasMem[1])) {
+ if (entry->state == VMCIQPB_ATTACHED_MEM) {
result = QueuePairNotifyPeer(TRUE, handle, contextId, entry->createId);
if (result < VMCI_SUCCESS) {
VMCI_WARNING((LGPFX"Failed to notify peer (ID=0x%x) of attach to queue "
VMCIId peerId;
Bool isLocal = FALSE;
int result;
- unsigned int index;
if (VMCI_HANDLE_INVALID(handle) || !context || contextId == VMCI_INVALID_ID) {
return VMCI_ERROR_INVALID_ARGS;
goto out;
}
- index = VMCIQPBEGetIndex(entry, contextId);
-
if (contextId == entry->createId) {
peerId = entry->attachId;
entry->createId = VMCI_INVALID_ID;
VMCI_AcquireQueueMutex(entry->produceQ, TRUE);
headersMapped = entry->produceQ->qHeader || entry->consumeQ->qHeader;
- if (entry->hasMem[index]) {
- VMCIHost_MarkQueuesUnavailable(index, entry->produceQ, entry->consumeQ);
- result = VMCIHost_UnmapQueues(index, INVALID_VMCI_GUEST_MEM_ID,
+ if (QPBROKERSTATE_HAS_MEM(entry)) {
+ result = VMCIHost_UnmapQueues(INVALID_VMCI_GUEST_MEM_ID,
entry->produceQ,
entry->consumeQ);
if (result < VMCI_SUCCESS) {
"(handle=0x%x:0x%x,result=%d).\n", handle.context,
handle.resource, result));
}
+ VMCIHost_MarkQueuesUnavailable(entry->produceQ, entry->consumeQ);
if (entry->vmciPageFiles) {
- VMCIHost_ReleaseUserMemory(index, entry->produceQ, entry->consumeQ);
+ VMCIHost_ReleaseUserMemory(entry->produceQ, entry->consumeQ);
} else {
- VMCIHost_UnregisterUserMemory(index, entry->produceQ, entry->consumeQ);
+ VMCIHost_UnregisterUserMemory(entry->produceQ, entry->consumeQ);
}
- entry->hasMem[index] = FALSE;
}
if (!headersMapped) {
QueuePairResetSavedHeaders(entry);
}
- if (index == 1) {
- entry->isVM2VM = FALSE;
- }
VMCI_ReleaseQueueMutex(entry->produceQ);
if (!headersMapped && entry->wakeupCB) {
entry->wakeupCB(entry->clientData);
if (isLocal) {
VMCI_FreeKernelMem(entry->localMem, QPE_NUM_PAGES(entry->qp) * PAGE_SIZE);
- entry->hasMem[0] = FALSE;
}
- ASSERT(entry->hasMem[0] == FALSE);
- ASSERT(entry->hasMem[1] == FALSE);
VMCI_CleanupQueueMutex(entry->produceQ, entry->consumeQ);
VMCIHost_FreeQueue(entry->produceQ, entry->qp.produceSize);
VMCIHost_FreeQueue(entry->consumeQ, entry->qp.consumeSize);
} else {
ASSERT(peerId != VMCI_INVALID_ID);
QueuePairNotifyPeer(FALSE, handle, contextId, peerId);
- entry->stateQP = VMCIQPB_SHUTDOWN;
+ if (contextId == VMCI_HOST_CONTEXT_ID && QPBROKERSTATE_HAS_MEM(entry)) {
+ entry->state = VMCIQPB_SHUTDOWN_MEM;
+ } else {
+ entry->state = VMCIQPB_SHUTDOWN_NO_MEM;
+ }
if (!isLocal) {
VMCIContext_QueuePairDestroy(context, handle);
}
const VMCIId contextId = VMCIContext_GetId(context);
Bool isLocal = FALSE;
int result;
- unsigned int endpoint;
- unsigned int index;
if (VMCI_HANDLE_INVALID(handle) || !context || contextId == VMCI_INVALID_ID) {
return VMCI_ERROR_INVALID_ARGS;
result = VMCI_ERROR_QUEUEPAIR_NOTATTACHED;
goto out;
}
- index = VMCIQPBEGetIndex(entry, contextId);
- endpoint = contextId == entry->createId ? 0 : 1;
isLocal = entry->qp.flags & VMCI_QPFLAG_LOCAL;
*/
VMCI_AcquireQueueMutex(entry->produceQ, TRUE);
- VMCIHost_MarkQueuesAvailable(index, entry->produceQ, entry->consumeQ);
+ VMCIHost_MarkQueuesAvailable(entry->produceQ, entry->consumeQ);
if (entry->qp.flags & VMCI_QPFLAG_NONBLOCK) {
- result = VMCIHost_MapQueues(index, entry->produceQ, entry->consumeQ,
+ result = VMCIHost_MapQueues(entry->produceQ, entry->consumeQ,
entry->qp.flags);
} else {
result = VMCI_SUCCESS;
} else if (contextId != VMCI_HOST_CONTEXT_ID) {
QueuePairPageStore pageStore;
- ASSERT((entry->stateQP == VMCIQPB_CREATED ||
- entry->stateQP == VMCIQPB_SHUTDOWN ||
- entry->stateQP == VMCIQPB_ATTACHED) && !entry->hasMem[0]);
+ ASSERT(entry->state == VMCIQPB_CREATED_NO_MEM ||
+ entry->state == VMCIQPB_SHUTDOWN_NO_MEM ||
+ entry->state == VMCIQPB_ATTACHED_NO_MEM);
ASSERT(!isLocal);
pageStore.pages = guestMem;
VMCI_AcquireQueueMutex(entry->produceQ, TRUE);
QueuePairResetSavedHeaders(entry);
- result = VMCIHost_RegisterUserMemory(index, &pageStore, entry->produceQ, entry->consumeQ);
- VMCIHost_MarkQueuesAvailable(index, entry->produceQ, entry->consumeQ);
+ result = VMCIHost_RegisterUserMemory(&pageStore, entry->produceQ, entry->consumeQ);
+ VMCIHost_MarkQueuesAvailable(entry->produceQ, entry->consumeQ);
VMCI_ReleaseQueueMutex(entry->produceQ);
if (result == VMCI_SUCCESS) {
- entry->hasMem[index] = TRUE;
+ /*
+ * Move state from *_NO_MEM to *_MEM.
+ */
+
+ entry->state++;
+
+ ASSERT(entry->state == VMCIQPB_CREATED_MEM ||
+ entry->state == VMCIQPB_SHUTDOWN_MEM ||
+ entry->state == VMCIQPB_ATTACHED_MEM);
+
if (entry->wakeupCB) {
entry->wakeupCB(entry->clientData);
}
*/
static int
-QueuePairSaveHeaders(QPBrokerEntry *entry, // IN
- VMCIId contextId) // IN
+QueuePairSaveHeaders(QPBrokerEntry *entry) // IN
{
int result;
return VMCI_SUCCESS;
}
if (NULL == entry->produceQ->qHeader || NULL == entry->consumeQ->qHeader) {
- unsigned int index;
-
- /*
- * If this is second VM, do not save headers: qHeader is for VM which
- * created queue pair only. And no API which uses savedHeader should
- * be used together with VM2VM queue pair anyway.
- */
- index = VMCIQPBEGetIndex(entry, contextId);
- if (index != 0) {
- return VMCI_SUCCESS;
- }
- result = VMCIHost_MapQueues(index, entry->produceQ, entry->consumeQ, 0);
+ result = VMCIHost_MapQueues(entry->produceQ, entry->consumeQ, FALSE);
if (result < VMCI_SUCCESS) {
return result;
}
const VMCIId contextId = VMCIContext_GetId(context);
Bool isLocal = FALSE;
int result;
- unsigned int index;
if (VMCI_HANDLE_INVALID(handle) || !context || contextId == VMCI_INVALID_ID) {
return VMCI_ERROR_INVALID_ARGS;
result = VMCI_ERROR_QUEUEPAIR_NOTATTACHED;
goto out;
}
- index = VMCIQPBEGetIndex(entry, contextId);
+
isLocal = entry->qp.flags & VMCI_QPFLAG_LOCAL;
if (contextId != VMCI_HOST_CONTEXT_ID) {
- ASSERT(entry->hasMem[index]);
+ ASSERT(entry->state != VMCIQPB_CREATED_NO_MEM &&
+ entry->state != VMCIQPB_SHUTDOWN_NO_MEM &&
+ entry->state != VMCIQPB_ATTACHED_NO_MEM);
ASSERT(!isLocal);
VMCI_AcquireQueueMutex(entry->produceQ, TRUE);
- result = QueuePairSaveHeaders(entry, contextId);
+ result = QueuePairSaveHeaders(entry);
if (result < VMCI_SUCCESS) {
VMCI_WARNING((LGPFX"Failed to save queue headers for queue pair "
"(handle=0x%x:0x%x,result=%d).\n", handle.context,
handle.resource, result));
}
- VMCIHost_MarkQueuesUnavailable(index, entry->produceQ, entry->consumeQ);
- VMCIHost_UnmapQueues(index, gid, entry->produceQ, entry->consumeQ);
+ VMCIHost_UnmapQueues(gid, entry->produceQ, entry->consumeQ);
+ VMCIHost_MarkQueuesUnavailable(entry->produceQ, entry->consumeQ);
if (!vmkernel) {
/*
* On hosted, when we unmap queue pairs, the VMX will also
* memory with a possibly new user VA.
*/
- VMCIHost_UnregisterUserMemory(index, entry->produceQ, entry->consumeQ);
- entry->hasMem[index] = FALSE;
+ VMCIHost_UnregisterUserMemory(entry->produceQ, entry->consumeQ);
+
+ /*
+ * Move state from *_MEM to *_NO_MEM.
+ */
+
+ entry->state--;
}
VMCI_ReleaseQueueMutex(entry->produceQ);