lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <1329267955-32367-5-git-send-email-astiegmann@vmware.com>
Date:	Tue, 14 Feb 2012 17:05:45 -0800
From:	"Andrew Stiegmann (stieg)" <astiegmann@...are.com>
To:	linux-kernel@...r.kernel.org
Cc:	vm-crosstalk@...are.com, dtor@...are.com, cschamp@...are.com,
	"Andrew Stiegmann (stieg)" <astiegmann@...are.com>
Subject: [PATCH 04/14] Add vmciDriver.*

---
 drivers/misc/vmw_vmci/vmciDriver.c |  663 ++++++++++++++++++++++++++++++++++++
 drivers/misc/vmw_vmci/vmciDriver.h |   57 +++
 2 files changed, 720 insertions(+), 0 deletions(-)
 create mode 100644 drivers/misc/vmw_vmci/vmciDriver.c
 create mode 100644 drivers/misc/vmw_vmci/vmciDriver.h

diff --git a/drivers/misc/vmw_vmci/vmciDriver.c b/drivers/misc/vmw_vmci/vmciDriver.c
new file mode 100644
index 0000000..e121d6d
--- /dev/null
+++ b/drivers/misc/vmw_vmci/vmciDriver.c
@@ -0,0 +1,663 @@
+/*
+ *
+ * VMware VMCI Driver
+ *
+ * Copyright (C) 2012 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
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+
+#include "vmci_defs.h"
+#include "vmci_infrastructure.h"
+#include "vmci_kernel_if.h"
+#include "vmciCommonInt.h"
+#include "vmciContext.h"
+#include "vmciDatagram.h"
+#include "vmciDoorbell.h"
+#include "vmciDriver.h"
+#include "vmciEvent.h"
+#include "vmciHashtable.h"
+#include "vmciKernelAPI.h"
+#include "vmciQueuePair.h"
+#include "vmciResource.h"
+
+#define LGPFX "VMCI: "
+#define VMCI_UTIL_NUM_RESOURCES 1
+
+static uint32_t ctxUpdateSubID = VMCI_INVALID_ID;
+static struct vmci_context *hostContext;
+static atomic_t vmContextID = { VMCI_INVALID_ID };
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * VMCI_HostInit --
+ *
+ *      Initializes the host driver specific components of VMCI.
+ *
+ * Results:
+ *      VMCI_SUCCESS if successful, appropriate error code otherwise.
+ *
+ * Side effects:
+ *      None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int VMCI_HostInit(void)
+{
+	int result;
+
+	/*
+	 * In theory, it is unsafe to pass an eventHnd of -1 to platforms which use
+	 * it (VMKernel/Windows/Mac OS at the time of this writing). In practice we
+	 * are fine though, because the event is never used in the case of the host
+	 * context.
+	 */
+	result = VMCIContext_InitContext(VMCI_HOST_CONTEXT_ID,
+					 VMCI_DEFAULT_PROC_PRIVILEGE_FLAGS,
+					 -1, VMCI_VERSION, NULL, &hostContext);
+	if (result < VMCI_SUCCESS) {
+		VMCI_WARNING((LGPFX
+			      "Failed to initialize VMCIContext (result=%d).\n",
+			      result));
+		goto errorExit;
+	}
+
+	result = VMCIQPBroker_Init();
+	if (result < VMCI_SUCCESS) {
+		goto hostContextExit;
+	}
+
+	VMCI_LOG((LGPFX "host components initialized.\n"));
+	return VMCI_SUCCESS;
+
+ hostContextExit:
+	VMCIContext_ReleaseContext(hostContext);
+ errorExit:
+	return result;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * VMCI_HostCleanup --
+ *
+ *      Cleans up the host specific components of the VMCI module.
+ *
+ * Results:
+ *      None.
+ *
+ * Side effects:
+ *      None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void VMCI_HostCleanup(void)
+{
+	VMCIContext_ReleaseContext(hostContext);
+	VMCIQPBroker_Exit();
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * VMCI_DeviceGet --
+ *
+ *      Verifies that a valid VMCI device is present, and indicates
+ *      the callers intention to use the device until it calls
+ *      VMCI_DeviceRelease().
+ *
+ * Results:
+ *      true if a valid VMCI device is present, false otherwise.
+ *
+ * Side effects:
+ *      None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+bool VMCI_DeviceGet(uint32_t * apiVersion,	// IN/OUT
+		    VMCI_DeviceShutdownFn * deviceShutdownCB,	// UNUSED
+		    void *userData,	// UNUSED
+		    void **deviceRegistration)	// OUT
+{
+	if (NULL != deviceRegistration) {
+		*deviceRegistration = NULL;
+	}
+
+	if (*apiVersion > VMCI_KERNEL_API_VERSION) {
+		*apiVersion = VMCI_KERNEL_API_VERSION;
+		return false;
+	}
+
+	if (!VMCI_DeviceEnabled()) {
+		return false;
+	}
+
+	return true;
+}
+
+EXPORT_SYMBOL(VMCI_DeviceGet);
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * VMCI_DeviceRelease --
+ *
+ *      Indicates that the caller is done using the VMCI device.
+ *
+ * Results:
+ *      None.
+ *
+ * Side effects:
+ *      None.
+ *
+ * XXX: Remove me?  Used by vsock?
+ *----------------------------------------------------------------------
+ */
+
+void VMCI_DeviceRelease(void *deviceRegistration)	// UNUSED
+{
+}
+
+EXPORT_SYMBOL(VMCI_DeviceRelease);
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * VMCIUtilCidUpdate --
+ *
+ *      Gets called with the new context id if updated or resumed.
+ *
+ * Results:
+ *      Context id.
+ *
+ * Side effects:
+ *      None.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static void VMCIUtilCidUpdate(uint32_t subID,	// IN:
+			      struct vmci_event_data *eventData,	// IN:
+			      void *clientData)	// IN:
+{
+	struct vmci_event_payld_ctx *evPayload =
+	    VMCIEventDataPayload(eventData);
+
+	if (subID != ctxUpdateSubID) {
+		VMCI_DEBUG_LOG(4,
+			       (LGPFX "Invalid subscriber (ID=0x%x).\n",
+				subID));
+		return;
+	}
+
+	if (eventData == NULL || evPayload->contextID == VMCI_INVALID_ID) {
+		VMCI_DEBUG_LOG(4, (LGPFX "Invalid event data.\n"));
+		return;
+	}
+
+	VMCI_LOG((LGPFX
+		  "Updating context from (ID=0x%x) to (ID=0x%x) on event "
+		  "(type=%d).\n", atomic_read(&vmContextID),
+		  evPayload->contextID, eventData->event));
+	atomic_set(&vmContextID, evPayload->contextID);
+}
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * VMCIUtil_Init --
+ *
+ *      Subscribe to context id update event.
+ *
+ * Results:
+ *      None.
+ *
+ * Side effects:
+ *      None.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+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_WARNING((LGPFX
+			      "Failed to subscribe to event (type=%d).\n",
+			      VMCI_EVENT_CTX_ID_UPDATE));
+	}
+}
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * VMCIUtil_Exit --
+ *
+ *      Cleanup
+ *
+ * Results:
+ *      None.
+ *
+ * Side effects:
+ *      None.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+void VMCIUtil_Exit(void)
+{
+	if (VMCIEvent_Unsubscribe(ctxUpdateSubID) < VMCI_SUCCESS) {
+		VMCI_WARNING((LGPFX
+			      "Failed to unsubscribe to event (type=%d) with "
+			      "subscriber (ID=0x%x).\n",
+			      VMCI_EVENT_CTX_ID_UPDATE, ctxUpdateSubID));
+	}
+}
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * VMCIUtil_CheckHostCapabilities --
+ *
+ *      Verify that the host supports the hypercalls we need. If it does not,
+ *      try to find fallback hypercalls and use those instead.
+ *
+ * Results:
+ *      true if required hypercalls (or fallback hypercalls) are
+ *      supported by the host, false otherwise.
+ *
+ * Side effects:
+ *      None.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static bool VMCIUtilCheckHostCapabilities(void)
+{
+	int result;
+	struct vmci_rscs_query_msg *msg;
+	uint32_t msgSize = sizeof(struct vmci_rsrc_query_hdr) +
+	    VMCI_UTIL_NUM_RESOURCES * sizeof(uint32_t);
+	struct vmci_datagram *checkMsg = kmalloc(msgSize, GFP_KERNEL);
+
+	if (checkMsg == NULL) {
+		VMCI_WARNING((LGPFX "Check host: Insufficient memory.\n"));
+		return false;
+	}
+
+	checkMsg->dst = VMCI_MAKE_HANDLE(VMCI_HYPERVISOR_CONTEXT_ID,
+					 VMCI_RESOURCES_QUERY);
+	checkMsg->src = VMCI_ANON_SRC_HANDLE;
+	checkMsg->payloadSize = msgSize - VMCI_DG_HEADERSIZE;
+	msg = (struct vmci_rscs_query_msg *)VMCI_DG_PAYLOAD(checkMsg);
+
+	msg->numResources = VMCI_UTIL_NUM_RESOURCES;
+	msg->resources[0] = VMCI_GET_CONTEXT_ID;
+
+	result = VMCI_SendDatagram(checkMsg);
+	kfree(checkMsg);
+
+	/* We need the vector. There are no fallbacks. */
+	return (result == 0x1);
+}
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * VMCI_CheckHostCapabilities --
+ *
+ *      Tell host which guestcalls we support and let each API check
+ *      that the host supports the hypercalls it needs. If a hypercall
+ *      is not supported, the API can check for a fallback hypercall,
+ *      or fail the check.
+ *
+ * Results:
+ *      true if successful, false otherwise.
+ *
+ * Side effects:
+ *      Fallback mechanisms may be enabled in the API and vmmon.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+bool VMCI_CheckHostCapabilities(void)
+{
+	bool result = VMCIUtilCheckHostCapabilities();
+
+	VMCI_LOG((LGPFX "Host capability check: %s.\n",
+		  result ? "PASSED" : "FAILED"));
+
+	return result;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * VMCI_ReadDatagramsFromPort --
+ *
+ *      Reads datagrams from the data in port and dispatches them. We
+ *      always start reading datagrams into only the first page of the
+ *      datagram buffer. If the datagrams don't fit into one page, we
+ *      use the maximum datagram buffer size for the remainder of the
+ *      invocation. This is a simple heuristic for not penalizing
+ *      small datagrams.
+ *
+ *      This function assumes that it has exclusive access to the data
+ *      in port for the duration of the call.
+ *
+ * Results:
+ *      No result.
+ *
+ * Side effects:
+ *      Datagram handlers may be invoked.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void VMCI_ReadDatagramsFromPort(int ioHandle,	// IN
+				unsigned short int dgInPort,	// IN
+				uint8_t * dgInBuffer,	// IN
+				size_t dgInBufferSize)	// IN
+{
+	struct vmci_datagram *dg;
+	size_t currentDgInBufferSize = PAGE_SIZE;
+	size_t remainingBytes;
+
+	ASSERT(dgInBufferSize >= PAGE_SIZE);
+
+	insb(dgInPort, dgInBuffer, currentDgInBufferSize);
+	dg = (struct vmci_datagram *)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.
+		 */
+
+		if (dg->dst.resource == VMCI_INVALID_ID) {
+			ASSERT(remainingBytes > PAGE_SIZE);
+			dg = (struct vmci_datagram *)roundup((uintptr_t)
+							     dg + 1, PAGE_SIZE);
+			ASSERT((uint8_t *) dg <
+			       dgInBuffer + currentDgInBufferSize);
+			remainingBytes =
+			    (size_t) (dgInBuffer + currentDgInBufferSize -
+				      (uint8_t *) dg);
+			continue;
+		}
+
+		dgInSize = VMCI_DG_SIZE_ALIGNED(dg);
+
+		if (dgInSize <= dgInBufferSize) {
+			int result;
+
+			/*
+			 * If the remaining bytes in the datagram buffer doesn't
+			 * contain the complete datagram, we first make sure we have
+			 * enough room for it and then we read the reminder of the
+			 * datagram and possibly any following datagrams.
+			 */
+
+			if (dgInSize > remainingBytes) {
+				if (remainingBytes != currentDgInBufferSize) {
+
+					/*
+					 * We move the partial datagram to the front and read
+					 * the reminder of the datagram and possibly following
+					 * calls into the following bytes.
+					 */
+
+					memmove(dgInBuffer, dgInBuffer +
+						currentDgInBufferSize -
+						remainingBytes, remainingBytes);
+					dg = (struct vmci_datagram *)
+					    dgInBuffer;
+				}
+
+				if (currentDgInBufferSize != dgInBufferSize)
+					currentDgInBufferSize = dgInBufferSize;
+
+				insb(dgInPort, dgInBuffer + remainingBytes,
+				     currentDgInBufferSize - remainingBytes);
+			}
+
+			/* We special case event datagrams from the hypervisor. */
+			if (dg->src.context == VMCI_HYPERVISOR_CONTEXT_ID
+			    && dg->dst.resource == VMCI_EVENT_HANDLER) {
+				result = VMCIEvent_Dispatch(dg);
+			} else {
+				result = VMCIDatagram_InvokeGuestHandler(dg);
+			}
+			if (result < VMCI_SUCCESS) {
+				VMCI_DEBUG_LOG(4,
+					       (LGPFX
+						"Datagram with resource (ID=0x%x) failed "
+						"(err=%d).\n",
+						dg->dst.resource, result));
+			}
+
+			/* On to the next datagram. */
+			dg = (struct vmci_datagram *)((uint8_t *) dg +
+						      dgInSize);
+		} else {
+			size_t bytesToSkip;
+
+			/* Datagram doesn't fit in datagram buffer of maximal size. We drop it. */
+			VMCI_DEBUG_LOG(4,
+				       (LGPFX
+					"Failed to receive datagram (size=%u bytes).\n",
+					dgInSize));
+
+			bytesToSkip = dgInSize - remainingBytes;
+			if (currentDgInBufferSize != dgInBufferSize)
+				currentDgInBufferSize = dgInBufferSize;
+
+			for (;;) {
+				insb(dgInPort, dgInBuffer,
+				     currentDgInBufferSize);
+				if (bytesToSkip <= currentDgInBufferSize) {
+					break;
+				}
+				bytesToSkip -= currentDgInBufferSize;
+			}
+			dg = (struct vmci_datagram *)(dgInBuffer + bytesToSkip);
+		}
+
+		remainingBytes =
+		    (size_t) (dgInBuffer + currentDgInBufferSize -
+			      (uint8_t *) dg);
+
+		if (remainingBytes < VMCI_DG_HEADERSIZE) {
+			/* Get the next batch of datagrams. */
+
+			insb(dgInPort, dgInBuffer, currentDgInBufferSize);
+			dg = (struct vmci_datagram *)dgInBuffer;
+			remainingBytes = currentDgInBufferSize;
+		}
+	}
+}
+
+/*
+ *----------------------------------------------------------------------------
+ *
+ * VMCI_GetContextID --
+ *
+ *    Returns the current context ID.  Note that since this is accessed only
+ *    from code running in the host, this always returns the host context ID.
+ *
+ * Results:
+ *    Context ID.
+ *
+ * Side effects:
+ *    None.
+ *
+ *----------------------------------------------------------------------------
+ */
+
+uint32_t VMCI_GetContextID(void)
+{
+	if (VMCI_GuestPersonalityActive()) {
+		if (atomic_read(&vmContextID) == VMCI_INVALID_ID) {
+			uint32_t result;
+			struct vmci_datagram getCidMsg;
+			getCidMsg.dst =
+			    VMCI_MAKE_HANDLE(VMCI_HYPERVISOR_CONTEXT_ID,
+					     VMCI_GET_CONTEXT_ID);
+			getCidMsg.src = VMCI_ANON_SRC_HANDLE;
+			getCidMsg.payloadSize = 0;
+			result = VMCI_SendDatagram(&getCidMsg);
+			atomic_set(&vmContextID, result);
+		}
+		return atomic_read(&vmContextID);
+	} else if (VMCI_HostPersonalityActive()) {
+		return VMCI_HOST_CONTEXT_ID;
+	}
+	return VMCI_INVALID_ID;
+}
+
+EXPORT_SYMBOL(VMCI_GetContextID);
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * VMCI_Version --
+ *
+ *     Returns the version of the VMCI driver.
+ *
+ * Results:
+ *      Returns a version number.
+ *
+ * Side effects:
+ *      None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+uint32_t VMCI_Version()
+{
+	return VMCI_VERSION;
+}
+
+EXPORT_SYMBOL(VMCI_Version);
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * VMCI_SharedInit --
+ *
+ *      Initializes VMCI components shared between guest and host
+ *      driver. This registers core hypercalls.
+ *
+ * Results:
+ *      VMCI_SUCCESS if successful, appropriate error code otherwise.
+ *
+ * Side effects:
+ *      None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int VMCI_SharedInit(void)
+{
+	int result;
+
+	result = VMCIResource_Init();
+	if (result < VMCI_SUCCESS) {
+		VMCI_WARNING((LGPFX
+			      "Failed to initialize VMCIResource (result=%d).\n",
+			      result));
+		goto errorExit;
+	}
+
+	result = VMCIContext_Init();
+	if (result < VMCI_SUCCESS) {
+		VMCI_WARNING((LGPFX
+			      "Failed to initialize VMCIContext (result=%d).\n",
+			      result));
+		goto resourceExit;
+	}
+
+	result = VMCIDatagram_Init();
+	if (result < VMCI_SUCCESS) {
+		VMCI_WARNING((LGPFX
+			      "Failed to initialize VMCIDatagram (result=%d).\n",
+			      result));
+		goto resourceExit;
+	}
+
+	result = VMCIEvent_Init();
+	if (result < VMCI_SUCCESS) {
+		VMCI_WARNING((LGPFX
+			      "Failed to initialize VMCIEvent (result=%d).\n",
+			      result));
+		goto resourceExit;
+	}
+
+	result = VMCIDoorbell_Init();
+	if (result < VMCI_SUCCESS) {
+		VMCI_WARNING((LGPFX
+			      "Failed to initialize VMCIDoorbell (result=%d).\n",
+			      result));
+		goto eventExit;
+	}
+
+	VMCI_LOG((LGPFX "shared components initialized.\n"));
+	return VMCI_SUCCESS;
+
+ eventExit:
+	VMCIEvent_Exit();
+ resourceExit:
+	VMCIResource_Exit();
+ errorExit:
+	return result;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * VMCI_SharedCleanup --
+ *
+ *      Cleans up VMCI components shared between guest and host
+ *      driver.
+ *
+ * Results:
+ *      None.
+ *
+ * Side effects:
+ *      None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void VMCI_SharedCleanup(void)
+{
+	VMCIEvent_Exit();
+	VMCIResource_Exit();
+}
diff --git a/drivers/misc/vmw_vmci/vmciDriver.h b/drivers/misc/vmw_vmci/vmciDriver.h
new file mode 100644
index 0000000..9f38bee
--- /dev/null
+++ b/drivers/misc/vmw_vmci/vmciDriver.h
@@ -0,0 +1,57 @@
+/*
+ *
+ * VMware VMCI Driver
+ *
+ * Copyright (C) 2012 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
+ */
+
+#ifndef _VMCI_DRIVER_H_
+#define _VMCI_DRIVER_H_
+
+#include "vmci_defs.h"
+#include "vmci_infrastructure.h"
+#include "vmciContext.h"
+
+/*
+ * A few macros to encapsulate logging in common code. The macros
+ * result in LOG/LOGThrottled on vmkernel and Log on hosted.
+ */
+
+#define VMCI_DEBUG_LEVEL 4
+#define VMCI_DEBUG_LOG(_level, _args)		\
+  do {						\
+    if (_level < VMCI_DEBUG_LEVEL) {		\
+      Log _args ;				\
+    }						\
+  } while(false)
+#define VMCI_LOG(_args) Log _args
+#define VMCI_WARNING(_args) Warning _args
+
+int VMCI_SharedInit(void);
+void VMCI_SharedCleanup(void);
+int VMCI_HostInit(void);
+void VMCI_HostCleanup(void);
+uint32_t VMCI_GetContextID(void);
+int VMCI_SendDatagram(struct vmci_datagram *dg);
+
+void VMCIUtil_Init(void);
+void VMCIUtil_Exit(void);
+bool VMCI_CheckHostCapabilities(void);
+void VMCI_ReadDatagramsFromPort(int ioHandle, unsigned short int dgInPort,
+				uint8_t * dgInBuffer, size_t dgInBufferSize);
+bool VMCI_DeviceEnabled(void);
+
+#endif				// _VMCI_DRIVER_H_
-- 
1.7.0.4

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ