From: VMware, Inc <> Date: Wed, 18 Sep 2013 03:19:48 +0000 (-0700) Subject: VMCI: Remove VM2VM X-Git-Tag: 2013.09.16-1328054~89 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4f860433a9a51fd978f51ed6c9fa1db167909419;p=thirdparty%2Fopen-vm-tools.git VMCI: Remove VM2VM We're never going to ship it, so let's yank it out. This isn't a straight backout for the following reasons: o Some of the files have diverged so far that backout fails. o Petr added some nice log messages in his original change that we want to retain. So this was mostly manual. I did do a side-by-side with the pre-VM2VM version and it looks good. Note that our 128-bit QP tag code will re-appear in vm_atomic.h at some point. Signed-off-by: Dmitry Torokhov --- diff --git a/open-vm-tools/modules/linux/shared/vmci_kernel_if.h b/open-vm-tools/modules/linux/shared/vmci_kernel_if.h index 4163aabb2..29c609dfd 100644 --- a/open-vm-tools/modules/linux/shared/vmci_kernel_if.h +++ b/open-vm-tools/modules/linux/shared/vmci_kernel_if.h @@ -315,7 +315,7 @@ void VMCIKernelIf_Exit(void); #if defined(_WIN32) void VMCIKernelIf_DrainDelayedWork(void); #endif // _WIN32 -#endif // SOLARIS || _WIN32 || __APPLE__ || VMKERNEL +#endif // SOLARIS || _WIN32 || __APPLE__ #if !defined(VMKERNEL) && (defined(__linux__) || defined(_WIN32) || \ defined(SOLARIS) || defined(__APPLE__)) @@ -351,19 +351,15 @@ typedef uint32 VMCIGuestMemID; #if defined(VMKERNEL) || defined(__linux__) || defined(_WIN32) || \ defined(__APPLE__) struct QueuePairPageStore; - int VMCIHost_RegisterUserMemory(unsigned int index, - struct QueuePairPageStore *pageStore, + int VMCIHost_RegisterUserMemory(struct QueuePairPageStore *pageStore, struct VMCIQueue *produceQ, struct VMCIQueue *consumeQ); - void VMCIHost_UnregisterUserMemory(unsigned int index, - struct VMCIQueue *produceQ, + void VMCIHost_UnregisterUserMemory(struct VMCIQueue *produceQ, struct VMCIQueue *consumeQ); - int VMCIHost_MapQueues(unsigned int index, - struct VMCIQueue *produceQ, + int VMCIHost_MapQueues(struct VMCIQueue *produceQ, struct VMCIQueue *consumeQ, uint32 flags); - int VMCIHost_UnmapQueues(unsigned int index, - VMCIGuestMemID gid, + int VMCIHost_UnmapQueues(VMCIGuestMemID gid, struct VMCIQueue *produceQ, struct VMCIQueue *consumeQ); void VMCI_InitQueueMutex(struct VMCIQueue *produceQ, @@ -377,22 +373,20 @@ typedef uint32 VMCIGuestMemID; # define VMCI_CleanupQueueMutex(_pq, _cq) do { } while (0) # define VMCI_AcquireQueueMutex(_q, _cb) VMCI_SUCCESS # define VMCI_ReleaseQueueMutex(_q) do { } while (0) -# define VMCIHost_RegisterUserMemory(_idx, _ps, _pq, _cq) VMCI_ERROR_UNAVAILABLE -# define VMCIHost_UnregisterUserMemory(_idx, _pq, _cq) do { } while (0) -# define VMCIHost_MapQueues(_idx, _pq, _cq, _f) VMCI_SUCCESS -# define VMCIHost_UnmapQueues(_idx, _gid, _pq, _cq) VMCI_SUCCESS +# define VMCIHost_RegisterUserMemory(_ps, _pq, _cq) VMCI_ERROR_UNAVAILABLE +# define VMCIHost_UnregisterUserMemory(_pq, _cq) do { } while (0) +# define VMCIHost_MapQueues(_pq, _cq, _f) VMCI_SUCCESS +# define VMCIHost_UnmapQueues(_gid, _pq, _cq) VMCI_SUCCESS #endif #if defined(VMKERNEL) - void VMCIHost_MarkQueuesAvailable(unsigned int index, - struct VMCIQueue *produceQ, + void VMCIHost_MarkQueuesAvailable(struct VMCIQueue *produceQ, struct VMCIQueue *consumeQ); - void VMCIHost_MarkQueuesUnavailable(unsigned int index, - struct VMCIQueue *produceQ, + void VMCIHost_MarkQueuesUnavailable(struct VMCIQueue *produceQ, struct VMCIQueue *consumeQ); #else -# define VMCIHost_MarkQueuesAvailable(_idx, _q, _p) do { } while (0) -# define VMCIHost_MarkQueuesUnavailable(_idx, _q, _p) do { } while(0) +# define VMCIHost_MarkQueuesAvailable(_q, _p) do { } while (0) +# define VMCIHost_MarkQueuesUnavailable(_q, _p) do { } while(0) #endif #if defined(VMKERNEL) || defined(__linux__) @@ -405,16 +399,14 @@ typedef uint32 VMCIGuestMemID; #if (!defined(VMKERNEL) && defined(__linux__)) || defined(_WIN32) || \ defined(__APPLE__) || defined(SOLARIS) - int VMCIHost_GetUserMemory(unsigned int index, - VA64 produceUVA, VA64 consumeUVA, + int VMCIHost_GetUserMemory(VA64 produceUVA, VA64 consumeUVA, struct VMCIQueue *produceQ, struct VMCIQueue *consumeQ); - void VMCIHost_ReleaseUserMemory(unsigned int index, - struct VMCIQueue *produceQ, + void VMCIHost_ReleaseUserMemory(struct VMCIQueue *produceQ, struct VMCIQueue *consumeQ); #else -# define VMCIHost_GetUserMemory(_idx, _puva, _cuva, _pq, _cq) VMCI_ERROR_UNAVAILABLE -# define VMCIHost_ReleaseUserMemory(_idx, _pq, _cq) ASSERT_NOT_IMPLEMENTED(FALSE) +# define VMCIHost_GetUserMemory(_puva, _cuva, _pq, _cq) VMCI_ERROR_UNAVAILABLE +# define VMCIHost_ReleaseUserMemory(_pq, _cq) ASSERT_NOT_IMPLEMENTED(FALSE) #endif #if defined(_WIN32) diff --git a/open-vm-tools/modules/linux/vmci/common/vmciContext.c b/open-vm-tools/modules/linux/vmci/common/vmciContext.c index 5a698e34e..513e93d4f 100644 --- a/open-vm-tools/modules/linux/vmci/common/vmciContext.c +++ b/open-vm-tools/modules/linux/vmci/common/vmciContext.c @@ -1977,8 +1977,7 @@ VMCIContext_NotifyDoorbell(VMCIId srcCID, // IN if (srcCID != handle.context) { VMCIPrivilegeFlags dstPrivFlags; - if (!vmkernel && VMCI_CONTEXT_IS_VM(srcCID) && - VMCI_CONTEXT_IS_VM(handle.context)) { + if (VMCI_CONTEXT_IS_VM(srcCID) && VMCI_CONTEXT_IS_VM(handle.context)) { VMCI_DEBUG_LOG(4, (LGPFX"Doorbell notification from VM to VM not " "supported (src=0x%x, dst=0x%x).\n", srcCID, handle.context)); diff --git a/open-vm-tools/modules/linux/vmci/common/vmciDatagram.c b/open-vm-tools/modules/linux/vmci/common/vmciDatagram.c index 0dbac6527..2f17a1828 100644 --- a/open-vm-tools/modules/linux/vmci/common/vmciDatagram.c +++ b/open-vm-tools/modules/linux/vmci/common/vmciDatagram.c @@ -669,21 +669,19 @@ VMCIDatagramDispatchAsHost(VMCIId contextID, // IN: if (VMCIDenyInteraction(srcPrivFlags, vmci_context_get_priv_flags(dg->dst.context))) { VMCI_DEBUG_LOG(4, (LGPFX"Interaction denied (%X/%X - %X/%X)\n", - contextID, srcPrivFlags, - dg->dst.context, - vmci_context_get_priv_flags(dg->dst.context))); + contextID, srcPrivFlags, + dg->dst.context, + vmci_context_get_priv_flags(dg->dst.context))); return VMCI_ERROR_NO_ACCESS; } else if (VMCI_CONTEXT_IS_VM(contextID)) { /* * If the sending context is a VM, it cannot reach another VM. */ - if (!vmkernel) { - VMCI_DEBUG_LOG(4, (LGPFX"Datagram communication between VMs not " - "supported (src=0x%x, dst=0x%x).\n", - contextID, dg->dst.context)); - return VMCI_ERROR_DST_UNREACHABLE; - } + VMCI_DEBUG_LOG(4, (LGPFX"Datagram communication between VMs not " + "supported (src=0x%x, dst=0x%x).\n", + contextID, dg->dst.context)); + return VMCI_ERROR_DST_UNREACHABLE; } } diff --git a/open-vm-tools/modules/linux/vmci/common/vmciQPair.c b/open-vm-tools/modules/linux/vmci/common/vmciQPair.c index 5c5253fd0..4116fc916 100644 --- a/open-vm-tools/modules/linux/vmci/common/vmciQPair.c +++ b/open-vm-tools/modules/linux/vmci/common/vmciQPair.c @@ -294,14 +294,7 @@ VMCIQPairMapQueueHeaders(VMCIQueue *produceQ, // IN if (NULL == produceQ->qHeader || NULL == consumeQ->qHeader) { if (canBlock) { - /* - * We return data from creator of the queue in VM2VM case. - * That should be OK, as if they do not match then there - * is somebody else in progress of making them match, and - * you should not be looking at somebody else's queue if - * queue is active. - */ - result = VMCIHost_MapQueues(0, produceQ, consumeQ, 0); + result = VMCIHost_MapQueues(produceQ, consumeQ, 0); } else { result = VMCI_ERROR_QUEUEPAIR_NOT_READY; } diff --git a/open-vm-tools/modules/linux/vmci/common/vmciQueuePair.c b/open-vm-tools/modules/linux/vmci/common/vmciQueuePair.c index bdd74d909..a4e511e3d 100644 --- a/open-vm-tools/modules/linux/vmci/common/vmciQueuePair.c +++ b/open-vm-tools/modules/linux/vmci/common/vmciQueuePair.c @@ -59,24 +59,24 @@ * -------------- 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 @@ -84,51 +84,57 @@ * 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 @@ -154,8 +160,7 @@ typedef struct QPBrokerEntry { 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 @@ -166,7 +171,6 @@ typedef struct QPBrokerEntry { VMCIEventReleaseCB wakeupCB; void *clientData; void *localMem; // Kernel memory for local queue pair - Bool isVM2VM; } QPBrokerEntry; #if !defined(VMKERNEL) @@ -252,7 +256,7 @@ static int VMCIQueuePairAllocHostWork(VMCIHandle *handle, VMCIQueue **produceQ, 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) @@ -281,32 +285,6 @@ extern int VMCI_SendDatagram(VMCIDatagram *); #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; -} - - /* *----------------------------------------------------------------------------- * @@ -1030,7 +1008,6 @@ VMCIQPBrokerCreate(VMCIHandle handle, // IN int result; uint64 guestProduceSize; uint64 guestConsumeSize; - Bool isVM2VM; /* * Do not create if the caller asked not to. @@ -1052,8 +1029,7 @@ VMCIQPBrokerCreate(VMCIHandle handle, // IN 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; } @@ -1100,7 +1076,7 @@ VMCIQPBrokerCreate(VMCIHandle handle, // IN 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 = @@ -1108,7 +1084,6 @@ VMCIQPBrokerCreate(VMCIHandle handle, // IN 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; @@ -1136,8 +1111,7 @@ VMCIQPBrokerCreate(VMCIHandle handle, // IN 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 + @@ -1145,23 +1119,22 @@ VMCIQPBrokerCreate(VMCIHandle handle, // IN 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 @@ -1170,7 +1143,7 @@ VMCIQPBrokerCreate(VMCIHandle handle, // IN * call as the next step). */ - entry->stateQP = VMCIQPB_CREATED; + entry->state = VMCIQPB_CREATED_NO_MEM; } QueuePairList_AddEntry(&qpBrokerList, &entry->qp); @@ -1245,10 +1218,10 @@ VMCIQPBrokerAttach(QPBrokerEntry *entry, // IN 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; } @@ -1268,8 +1241,7 @@ VMCIQPBrokerAttach(QPBrokerEntry *entry, // IN 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; } @@ -1343,7 +1315,7 @@ VMCIQPBrokerAttach(QPBrokerEntry *entry, // IN 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 @@ -1372,57 +1344,41 @@ VMCIQPBrokerAttach(QPBrokerEntry *entry, // IN * 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 @@ -1439,19 +1395,10 @@ VMCIQPBrokerAttach(QPBrokerEntry *entry, // IN */ 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); } @@ -1460,10 +1407,10 @@ VMCIQPBrokerAttach(QPBrokerEntry *entry, // IN * 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) { @@ -1537,7 +1484,6 @@ VMCIQPBroker_SetPageStore(VMCIHandle handle, // IN 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; @@ -1582,30 +1528,33 @@ VMCIQPBroker_SetPageStore(VMCIHandle handle, // IN 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 " @@ -1661,7 +1610,6 @@ VMCIQPBroker_Detach(VMCIHandle handle, // IN 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; @@ -1691,8 +1639,6 @@ VMCIQPBroker_Detach(VMCIHandle handle, // IN goto out; } - index = VMCIQPBEGetIndex(entry, contextId); - if (contextId == entry->createId) { peerId = entry->attachId; entry->createId = VMCI_INVALID_ID; @@ -1718,9 +1664,8 @@ VMCIQPBroker_Detach(VMCIHandle handle, // IN 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) { @@ -1728,19 +1673,16 @@ VMCIQPBroker_Detach(VMCIHandle handle, // IN "(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); @@ -1757,10 +1699,7 @@ VMCIQPBroker_Detach(VMCIHandle handle, // IN 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); @@ -1770,7 +1709,11 @@ VMCIQPBroker_Detach(VMCIHandle handle, // IN } 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); } @@ -1810,8 +1753,6 @@ VMCIQPBroker_Map(VMCIHandle handle, // IN 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; @@ -1840,8 +1781,6 @@ VMCIQPBroker_Map(VMCIHandle handle, // IN result = VMCI_ERROR_QUEUEPAIR_NOTATTACHED; goto out; } - index = VMCIQPBEGetIndex(entry, contextId); - endpoint = contextId == entry->createId ? 0 : 1; isLocal = entry->qp.flags & VMCI_QPFLAG_LOCAL; @@ -1852,9 +1791,9 @@ VMCIQPBroker_Map(VMCIHandle handle, // IN */ 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; @@ -1871,9 +1810,9 @@ VMCIQPBroker_Map(VMCIHandle handle, // IN } 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; @@ -1881,11 +1820,20 @@ VMCIQPBroker_Map(VMCIHandle handle, // IN 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); } @@ -1919,8 +1867,7 @@ out: */ static int -QueuePairSaveHeaders(QPBrokerEntry *entry, // IN - VMCIId contextId) // IN +QueuePairSaveHeaders(QPBrokerEntry *entry) // IN { int result; @@ -1934,18 +1881,7 @@ QueuePairSaveHeaders(QPBrokerEntry *entry, // IN 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; } @@ -2021,7 +1957,6 @@ VMCIQPBroker_Unmap(VMCIHandle handle, // IN 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; @@ -2049,22 +1984,24 @@ VMCIQPBroker_Unmap(VMCIHandle handle, // IN 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 @@ -2074,8 +2011,13 @@ VMCIQPBroker_Unmap(VMCIHandle handle, // IN * 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); diff --git a/open-vm-tools/modules/linux/vmci/linux/vmciKernelIf.c b/open-vm-tools/modules/linux/vmci/linux/vmciKernelIf.c index a51bef89e..fc262e072 100644 --- a/open-vm-tools/modules/linux/vmci/linux/vmciKernelIf.c +++ b/open-vm-tools/modules/linux/vmci/linux/vmciKernelIf.c @@ -1886,15 +1886,13 @@ VMCIReleasePages(struct page **pages, // IN */ int -VMCIHost_RegisterUserMemory(unsigned int index, // IN - QueuePairPageStore *pageStore, // IN +VMCIHost_RegisterUserMemory(QueuePairPageStore *pageStore, // IN VMCIQueue *produceQ, // OUT VMCIQueue *consumeQ) // OUT { VA64 produceUVA; VA64 consumeUVA; - ASSERT(index == 0); ASSERT(produceQ->kernelIf->headerPage && consumeQ->kernelIf->headerPage); /* @@ -1905,7 +1903,7 @@ VMCIHost_RegisterUserMemory(unsigned int index, // IN produceUVA = pageStore->pages; consumeUVA = pageStore->pages + produceQ->kernelIf->numPages * PAGE_SIZE; - return VMCIHost_GetUserMemory(index, produceUVA, consumeUVA, produceQ, consumeQ); + return VMCIHost_GetUserMemory(produceUVA, consumeUVA, produceQ, consumeQ); } @@ -1928,11 +1926,9 @@ VMCIHost_RegisterUserMemory(unsigned int index, // IN */ void -VMCIHost_UnregisterUserMemory(unsigned int index, // IN - VMCIQueue *produceQ, // IN/OUT +VMCIHost_UnregisterUserMemory(VMCIQueue *produceQ, // IN/OUT VMCIQueue *consumeQ) // IN/OUT { - ASSERT(index == 0); ASSERT(produceQ->kernelIf); ASSERT(consumeQ->kernelIf); ASSERT(!produceQ->qHeader && !consumeQ->qHeader); @@ -1967,14 +1963,12 @@ VMCIHost_UnregisterUserMemory(unsigned int index, // IN */ int -VMCIHost_MapQueues(unsigned int index, // IN - VMCIQueue *produceQ, // IN/OUT +VMCIHost_MapQueues(VMCIQueue *produceQ, // IN/OUT VMCIQueue *consumeQ, // IN/OUT uint32 flags) // UNUSED { int result; - ASSERT(index == 0); if (!produceQ->qHeader || !consumeQ->qHeader) { struct page *headers[2]; @@ -2026,12 +2020,10 @@ VMCIHost_MapQueues(unsigned int index, // IN */ int -VMCIHost_UnmapQueues(unsigned int index, // IN - VMCIGuestMemID gid, // IN +VMCIHost_UnmapQueues(VMCIGuestMemID gid, // IN VMCIQueue *produceQ, // IN/OUT VMCIQueue *consumeQ) // IN/OUT { - ASSERT(index == 0); if (produceQ->qHeader) { ASSERT(consumeQ->qHeader); @@ -2068,8 +2060,7 @@ VMCIHost_UnmapQueues(unsigned int index, // IN */ int -VMCIHost_GetUserMemory(unsigned int index, // IN - VA64 produceUVA, // IN +VMCIHost_GetUserMemory(VA64 produceUVA, // IN VA64 consumeUVA, // IN VMCIQueue *produceQ, // OUT VMCIQueue *consumeQ) // OUT @@ -2077,7 +2068,6 @@ VMCIHost_GetUserMemory(unsigned int index, // IN int retval; int err = VMCI_SUCCESS; - ASSERT(index == 0); down_write(¤t->mm->mmap_sem); retval = get_user_pages(current, current->mm, @@ -2133,14 +2123,12 @@ out: */ void -VMCIHost_ReleaseUserMemory(unsigned int index, // IN - VMCIQueue *produceQ, // IN/OUT +VMCIHost_ReleaseUserMemory(VMCIQueue *produceQ, // IN/OUT VMCIQueue *consumeQ) // IN/OUT { - ASSERT(index == 0); ASSERT(produceQ->kernelIf->headerPage); - VMCIHost_UnregisterUserMemory(index, produceQ, consumeQ); + VMCIHost_UnregisterUserMemory(produceQ, consumeQ); } diff --git a/open-vm-tools/modules/linux/vmci/linux/vmci_version.h b/open-vm-tools/modules/linux/vmci/linux/vmci_version.h index 9bce2298f..80e19bb5e 100644 --- a/open-vm-tools/modules/linux/vmci/linux/vmci_version.h +++ b/open-vm-tools/modules/linux/vmci/linux/vmci_version.h @@ -25,8 +25,8 @@ #ifndef _VMCI_VERSION_H_ #define _VMCI_VERSION_H_ -#define VMCI_DRIVER_VERSION 9.5.17.0 -#define VMCI_DRIVER_VERSION_COMMAS 9,5,17,0 -#define VMCI_DRIVER_VERSION_STRING "9.5.17.0" +#define VMCI_DRIVER_VERSION 9.5.18.0 +#define VMCI_DRIVER_VERSION_COMMAS 9,5,18,0 +#define VMCI_DRIVER_VERSION_STRING "9.5.18.0" #endif /* _VMCI_VERSION_H_ */