From: VMware, Inc <> Date: Thu, 17 Jun 2010 22:12:48 +0000 (-0700) Subject: Unification of VMCI host and guest kernel API (2/5) X-Git-Tag: 2010.06.16-268169~44 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=b31cc7e99c940e8ccd83d65590e054a359d1a79d;p=thirdparty%2Fopen-vm-tools.git Unification of VMCI host and guest kernel API (2/5) The VMCI kernel API should be the same for both host and guest. Currently, that is not the case. The unification will consist of the following five changes - this is step 2: 1) Make the functions supported by the host kernel API a superset of the functions supported by the guest kernel API. This consists of adding VMCI_DeviceGet, VMCI_DeviceRelease, VMCI_GetContextID, VMCI_Version and VMCI_DsLookup. 2) Make the functions available by the guest kernel API the same as the functions available by the host kernel API. This means adding VMCI_ContextID2HostVmID and defining doorbell API on all platforms. These functions return VMCI_ERROR_UNAVAILABLE either because they don't make sense (the first one or because they aren't implemented yet). The unified header file will make clear what is supported where. 3) Integrate vmciHostKernelAPI.h to vmciKernelAPI.h. 4) Edit vmciKernelAPI.h to not refer to vmciHostKernelAPI.h and integrate the VMCIQPair.h definitions into the header file. 5) Delete old vmci*KernelAPI.h and VMCIQPair.h files, and make all host and guest references to a kernel API header file refer to the new unified header file. Signed-off-by: Marcelo Vanzin --- diff --git a/open-vm-tools/modules/linux/shared/vmciGuestKernelAPI.h b/open-vm-tools/modules/linux/shared/vmciGuestKernelAPI.h index 352724d03..05a921224 100644 --- a/open-vm-tools/modules/linux/shared/vmciGuestKernelAPI.h +++ b/open-vm-tools/modules/linux/shared/vmciGuestKernelAPI.h @@ -25,19 +25,15 @@ #ifndef __VMCI_GUESTKERNELAPI_H__ #define __VMCI_GUESTKERNELAPI_H__ -/* VMCI guest kernel API version number. */ -#define VMCI_GUEST_KERNEL_API_VERSION 1 - /* Macros to operate on the driver version number. */ #define VMCI_MAJOR_VERSION(v) (((v) >> 16) & 0xffff) -#define VMCI_MINOT_VERSION(v) ((v) & 0xffff) +#define VMCI_MINOR_VERSION(v) ((v) & 0xffff) #define INCLUDE_ALLOW_MODULE #include "includeCheck.h" #include "vmci_defs.h" #include "vmci_call_defs.h" -#include "vmciQueue.h" /* * Note: APIs marked as compat are provided for compatibility with the host @@ -65,6 +61,8 @@ int VMCIDatagram_Send(VMCIDatagram *msg); VMCIId VMCI_GetContextID(void); uint32 VMCI_Version(void); +int VMCI_ContextID2HostVmID(VMCIId contextID, void *hostVmID, + size_t hostVmIDLen); /* VMCI Event API. */ @@ -85,8 +83,6 @@ int VMCIDs_Lookup(const char *name, VMCIHandle *out); /* VMCI Doorbell API. */ -#if !defined(SOLARIS) && !defined(__APPLE__) - #define VMCI_FLAG_DELAYED_CB 0x01 typedef void (*VMCICallback)(void *clientData); @@ -98,7 +94,5 @@ int VMCIDoorbell_Destroy(VMCIHandle handle); int VMCIDoorbell_Notify(VMCIHandle handle, VMCIPrivilegeFlags privFlags); -#endif // !defined(SOLARIS) && !defined(__APPLE__) - #endif /* !__VMCI_GUESTKERNELAPI_H__ */ diff --git a/open-vm-tools/modules/linux/vmci/vmciNotifications.c b/open-vm-tools/modules/linux/vmci/vmciNotifications.c index c12288108..008a0e2b2 100644 --- a/open-vm-tools/modules/linux/vmci/vmciNotifications.c +++ b/open-vm-tools/modules/linux/vmci/vmciNotifications.c @@ -39,6 +39,8 @@ #include "vmciUtil.h" #include "circList.h" +#if !defined(SOLARIS) && !defined(__APPLE__) + /* * The VMCI Notify hash table provides two mappings: * 1) one maps a given notification index in the bitmap to the @@ -1042,3 +1044,49 @@ VMCIDoorbell_Notify(VMCIHandle handle, // IN #if defined(__linux__) EXPORT_SYMBOL(VMCIDoorbell_Notify); #endif + +#else // defined(SOLARIS) || defined(__APPLE__) + +/* + *----------------------------------------------------------------------------- + * + * VMCIDoorbell_Create/VMCIDoorbell_Destroy/VMCIDoorbell_Notify -- + * + * The doorbell functions have yet to be implemented for Solaris + * and Mac OS X guest drivers. + * + * Results: + * VMCI_ERROR_UNAVAILABLE. + * + * Side effects: + * None. + * + *----------------------------------------------------------------------------- + */ + +int +VMCIDoorbell_Create(VMCIHandle *handle, // IN + uint32 flags, // IN + VMCIPrivilegeFlags privFlags, // IN + VMCICallback notifyCB, // IN + void *clientData) // IN +{ + return VMCI_ERROR_UNAVAILABLE; +} + + +int +VMCIDoorbell_Destroy(VMCIHandle handle) // IN +{ + return VMCI_ERROR_UNAVAILABLE; +} + + +int +VMCIDoorbell_Notify(VMCIHandle handle, // IN + VMCIPrivilegeFlags privFlags) // IN +{ + return VMCI_ERROR_UNAVAILABLE; +} + +#endif diff --git a/open-vm-tools/modules/linux/vmci/vmciQueuePair.c b/open-vm-tools/modules/linux/vmci/vmciQueuePair.c index 2e53b8a93..927255ff0 100644 --- a/open-vm-tools/modules/linux/vmci/vmciQueuePair.c +++ b/open-vm-tools/modules/linux/vmci/vmciQueuePair.c @@ -24,7 +24,6 @@ #ifdef __linux__ # include "driver-config.h" -# define EXPORT_SYMTAB # include # include #elif defined(_WIN32) @@ -234,7 +233,7 @@ VMCIQueuePair_Exit(void) detachMsg.hdr.src = VMCI_ANON_SRC_HANDLE; detachMsg.hdr.payloadSize = sizeof entry->handle; detachMsg.handle = entry->handle; - + (void)VMCI_SendDatagram((VMCIDatagram *)&detachMsg); } /* @@ -388,10 +387,6 @@ QueuePairList_GetHead(void) *----------------------------------------------------------------------------- */ -#ifdef __linux__ -EXPORT_SYMBOL(VMCIQueuePair_Alloc); -#endif - int VMCIQueuePair_Alloc(VMCIHandle *handle, // IN/OUT: VMCIQueue **produceQ, // OUT: @@ -425,10 +420,6 @@ VMCIQueuePair_Alloc(VMCIHandle *handle, // IN/OUT: *----------------------------------------------------------------------------- */ -#ifdef __linux__ -EXPORT_SYMBOL(VMCIQueuePair_AllocPriv); -#endif - int VMCIQueuePair_AllocPriv(VMCIHandle *handle, // IN/OUT: VMCIQueue **produceQ, // OUT: @@ -470,10 +461,6 @@ VMCIQueuePair_AllocPriv(VMCIHandle *handle, // IN/OUT: *----------------------------------------------------------------------------- */ -#ifdef __linux__ -EXPORT_SYMBOL(VMCIQueuePair_Detach); -#endif - int VMCIQueuePair_Detach(VMCIHandle handle) // IN: { @@ -519,7 +506,7 @@ QueuePairEntryCreate(VMCIHandle handle, // IN: 2; /* One page each for the queue headers. */ ASSERT((produceSize || consumeSize) && produceQ && consumeQ); - + if (VMCI_HANDLE_INVALID(handle)) { VMCIId contextID = VMCI_GetContextID(); VMCIId oldRID = queuePairRID; @@ -908,11 +895,10 @@ out: /* If we didn't remove the entry, this could change once we unlock. */ refCount = entry ? entry->refCount : - 0xffffffff; /* + 0xffffffff; /* * Value does not matter, silence the * compiler. */ - QueuePairList_Unlock(); diff --git a/open-vm-tools/modules/linux/vmci/vmciQueuePairInt.h b/open-vm-tools/modules/linux/vmci/vmciQueuePairInt.h index 4aba56bf6..93b0b95e7 100644 --- a/open-vm-tools/modules/linux/vmci/vmciQueuePairInt.h +++ b/open-vm-tools/modules/linux/vmci/vmciQueuePairInt.h @@ -25,7 +25,8 @@ #ifndef _VMCI_QUEUE_PAIR_INT_H_ #define _VMCI_QUEUE_PAIR_INT_H_ -#include "vmciGuestKernelAPI.h" +#include "vmci_defs.h" +#include "vmciQueue.h" void VMCIQueuePair_Init(void); void VMCIQueuePair_Exit(void); diff --git a/open-vm-tools/modules/linux/vmci/vmciUtil.c b/open-vm-tools/modules/linux/vmci/vmciUtil.c index e482bd253..095cec3b4 100644 --- a/open-vm-tools/modules/linux/vmci/vmciUtil.c +++ b/open-vm-tools/modules/linux/vmci/vmciUtil.c @@ -36,7 +36,7 @@ # include "compat_interrupt.h" #elif defined(_WIN32) # ifndef WINNT_DDK -# error This file only works with the NT ddk +# error This file only works with the NT ddk # endif // WINNT_DDK # include #elif defined(SOLARIS) @@ -45,7 +45,7 @@ # include #elif defined(__APPLE__) # include -#else +#else #error "platform not supported." #endif //linux @@ -88,14 +88,14 @@ static Atomic_uint32 vmContextID = { VMCI_INVALID_ID }; void VMCIUtil_Init(void) { - /* + /* * We subscribe to the VMCI_EVENT_CTX_ID_UPDATE here so we can update the * internal context id when needed. */ if (VMCIEvent_Subscribe(VMCI_EVENT_CTX_ID_UPDATE, VMCI_FLAG_EVENT_NONE, VMCIUtilCidUpdate, NULL, &ctxUpdateSubID) < VMCI_SUCCESS) { - VMCI_LOG(("VMCIUtil: Failed to subscribe to event %d.\n", + VMCI_LOG(("VMCIUtil: Failed to subscribe to event %d.\n", VMCI_EVENT_CTX_ID_UPDATE)); } } @@ -106,7 +106,7 @@ VMCIUtil_Init(void) * * VMCIUtil_Exit -- * - * Cleanup + * Cleanup * * Results: * None. @@ -192,7 +192,7 @@ VMCIUtil_CheckHostCapabilities(void) { int result; VMCIResourcesQueryMsg *msg; - uint32 msgSize = sizeof(VMCIResourcesQueryHdr) + + uint32 msgSize = sizeof(VMCIResourcesQueryHdr) + VMCI_UTIL_NUM_RESOURCES * sizeof(VMCI_Resource); VMCIDatagram *checkMsg = VMCI_AllocKernelMem(msgSize, VMCI_MEMORY_NONPAGED); @@ -201,7 +201,7 @@ VMCIUtil_CheckHostCapabilities(void) return FALSE; } - checkMsg->dst = VMCI_MAKE_HANDLE(VMCI_HYPERVISOR_CONTEXT_ID, + checkMsg->dst = VMCI_MAKE_HANDLE(VMCI_HYPERVISOR_CONTEXT_ID, VMCI_RESOURCES_QUERY); checkMsg->src = VMCI_ANON_SRC_HANDLE; checkMsg->payloadSize = msgSize - VMCI_DG_HEADERSIZE; @@ -223,7 +223,7 @@ VMCIUtil_CheckHostCapabilities(void) * * VMCI_GetContextID -- * - * Returns the context id. + * Returns the context id. * * Results: * Context id. @@ -294,7 +294,7 @@ VMCI_CheckHostCapabilities(void) * * Returns the version of the VMCI guest driver. * - * Results: + * Results: * Returns a version number. * * Side effects: @@ -321,7 +321,7 @@ VMCI_Version() * * Determines if we are running in tasklet/dispatch level or above. * - * Results: + * Results: * TRUE if tasklet/dispatch or above, FALSE otherwise. * * Side effects: @@ -358,7 +358,7 @@ VMCI_InInterrupt() * the callers intention to use the device until it calls * VMCI_DeviceRelease(). * - * Results: + * Results: * TRUE if a valid VMCI device is present, FALSE otherwise. * * Side effects: @@ -385,7 +385,7 @@ VMCI_DeviceGet(void) * * Indicates that the caller is done using the VMCI device. * - * Results: + * Results: * None. * * Side effects: @@ -441,15 +441,15 @@ VMCI_ReadDatagramsFromPort(VMCIIoHandle ioHandle, // IN ASSERT(dgInBufferSize >= PAGE_SIZE); VMCI_ReadPortBytes(ioHandle, dgInPort, dgInBuffer, currentDgInBufferSize); - dg = (VMCIDatagram *)dgInBuffer; + dg = (VMCIDatagram *)dgInBuffer; remainingBytes = currentDgInBufferSize; - + while (dg->dst.resource != VMCI_INVALID_ID || remainingBytes > PAGE_SIZE) { unsigned dgInSize; - + /* * When the input buffer spans multiple pages, a datagram can - * start on any page boundary in the buffer. + * start on any page boundary in the buffer. */ if (dg->dst.resource == VMCI_INVALID_ID) { @@ -461,7 +461,7 @@ VMCI_ReadDatagramsFromPort(VMCIIoHandle ioHandle, // IN } dgInSize = VMCI_DG_SIZE_ALIGNED(dg); - + if (dgInSize <= dgInBufferSize) { int result; @@ -471,7 +471,7 @@ VMCI_ReadDatagramsFromPort(VMCIIoHandle ioHandle, // IN * enough room for it and then we read the reminder of the * datagram and possibly any following datagrams. */ - + if (dgInSize > remainingBytes) { if (remainingBytes != currentDgInBufferSize) { @@ -481,11 +481,11 @@ VMCI_ReadDatagramsFromPort(VMCIIoHandle ioHandle, // IN * the reminder of the datagram and possibly following * calls into the following bytes. */ - + memmove(dgInBuffer, dgInBuffer + currentDgInBufferSize - remainingBytes, remainingBytes); - dg = (VMCIDatagram *)dgInBuffer; + dg = (VMCIDatagram *)dgInBuffer; } if (currentDgInBufferSize != dgInBufferSize) { @@ -495,9 +495,9 @@ VMCI_ReadDatagramsFromPort(VMCIIoHandle ioHandle, // IN VMCI_ReadPortBytes(ioHandle, dgInPort, dgInBuffer + remainingBytes, currentDgInBufferSize - remainingBytes); } - + /* We special case event datagrams from the hypervisor. */ - if (dg->src.context == VMCI_HYPERVISOR_CONTEXT_ID && + if (dg->src.context == VMCI_HYPERVISOR_CONTEXT_ID && dg->dst.resource == VMCI_EVENT_HANDLER) { result = VMCIEvent_Dispatch(dg); } else { @@ -507,19 +507,19 @@ VMCI_ReadDatagramsFromPort(VMCIIoHandle ioHandle, // IN VMCI_LOG(("Datagram with resource %d failed with err %x.\n", dg->dst.resource, result)); } - + /* On to the next datagram. */ dg = (VMCIDatagram *)((uint8 *)dg + dgInSize); } else { size_t bytesToSkip; - + /* * Datagram doesn't fit in datagram buffer of maximal size. We drop it. */ VMCI_LOG(("Failed to receive datagram of size %u.\n", dgInSize)); - + bytesToSkip = dgInSize - remainingBytes; if (currentDgInBufferSize != dgInBufferSize) { currentDgInBufferSize = dgInBufferSize; @@ -533,12 +533,12 @@ VMCI_ReadDatagramsFromPort(VMCIIoHandle ioHandle, // IN } dg = (VMCIDatagram *)(dgInBuffer + bytesToSkip); } - + remainingBytes = (size_t) (dgInBuffer + currentDgInBufferSize - (uint8 *)dg); - + if (remainingBytes < VMCI_DG_HEADERSIZE) { /* Get the next batch of datagrams. */ - + VMCI_ReadPortBytes(ioHandle, dgInPort, dgInBuffer, currentDgInBufferSize); dg = (VMCIDatagram *)dgInBuffer; remainingBytes = currentDgInBufferSize; @@ -572,3 +572,32 @@ VMCIContext_GetPrivFlags(VMCIId contextID) // IN { return VMCI_NO_PRIVILEGE_FLAGS; } + + +/* + *---------------------------------------------------------------------- + * + * VMCI_ContextID2HostVmID -- + * + * Provided for compatibility with the host VMCI API. + * + * Results: + * Returns VMCI_ERROR_UNAVAILABLE. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +#ifdef __linux__ +EXPORT_SYMBOL(VMCI_ContextID2HostVmID); +#endif + +int +VMCI_ContextID2HostVmID(VMCIId contextID, // IN + void *hostVmID, // OUT + size_t hostVmIDLen) // IN +{ + return VMCI_ERROR_UNAVAILABLE; +}