[PATCH 02/12] VMCI: datagram implementation.

2013-01-08 Thread George Zhang
VMCI datagram Implements datagrams to allow data to be sent between host and 
guest.

Signed-off-by: George Zhang georgezh...@vmware.com
Acked-by: Andy king ack...@vmware.com
Acked-by: Dmitry Torokhov d...@vmware.com
---
 drivers/misc/vmw_vmci/vmci_datagram.c |  500 +
 drivers/misc/vmw_vmci/vmci_datagram.h |   52 +++
 2 files changed, 552 insertions(+), 0 deletions(-)
 create mode 100644 drivers/misc/vmw_vmci/vmci_datagram.c
 create mode 100644 drivers/misc/vmw_vmci/vmci_datagram.h

diff --git a/drivers/misc/vmw_vmci/vmci_datagram.c 
b/drivers/misc/vmw_vmci/vmci_datagram.c
new file mode 100644
index 000..ed5c433
--- /dev/null
+++ b/drivers/misc/vmw_vmci/vmci_datagram.c
@@ -0,0 +1,500 @@
+/*
+ * 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.
+ */
+
+#include linux/vmw_vmci_defs.h
+#include linux/vmw_vmci_api.h
+#include linux/module.h
+#include linux/sched.h
+#include linux/slab.h
+#include linux/bug.h
+
+#include vmci_datagram.h
+#include vmci_resource.h
+#include vmci_context.h
+#include vmci_driver.h
+#include vmci_event.h
+#include vmci_route.h
+
+/*
+ * struct datagram_entry describes the datagram entity. It is used for datagram
+ * entities created only on the host.
+ */
+struct datagram_entry {
+   struct vmci_resource resource;
+   u32 flags;
+   bool run_delayed;
+   vmci_datagram_recv_cb recv_cb;
+   void *client_data;
+   u32 priv_flags;
+};
+
+struct delayed_datagram_info {
+   struct datagram_entry *entry;
+   struct vmci_datagram msg;
+   struct work_struct work;
+   bool in_dg_host_queue;
+};
+
+/* Number of in-flight host-host datagrams */
+static atomic_t delayed_dg_host_queue_size = ATOMIC_INIT(0);
+
+/*
+ * Create a datagram entry given a handle pointer.
+ */
+static int dg_create_handle(u32 resource_id,
+   u32 flags,
+   u32 priv_flags,
+   vmci_datagram_recv_cb recv_cb,
+   void *client_data, struct vmci_handle *out_handle)
+{
+   int result;
+   u32 context_id;
+   struct vmci_handle handle;
+   struct datagram_entry *entry;
+
+   if ((flags  VMCI_FLAG_WELLKNOWN_DG_HND) != 0)
+   return VMCI_ERROR_INVALID_ARGS;
+
+   if ((flags  VMCI_FLAG_ANYCID_DG_HND) != 0) {
+   context_id = VMCI_INVALID_ID;
+   } else {
+   context_id = vmci_get_context_id();
+   if (context_id == VMCI_INVALID_ID)
+   return VMCI_ERROR_NO_RESOURCES;
+   }
+
+   handle = vmci_make_handle(context_id, resource_id);
+
+   entry = kmalloc(sizeof(*entry), GFP_KERNEL);
+   if (!entry) {
+   pr_warn(Failed allocating memory for datagram entry\n);
+   return VMCI_ERROR_NO_MEM;
+   }
+
+   entry-run_delayed = (flags  VMCI_FLAG_DG_DELAYED_CB) ? true : false;
+   entry-flags = flags;
+   entry-recv_cb = recv_cb;
+   entry-client_data = client_data;
+   entry-priv_flags = priv_flags;
+
+   /* Make datagram resource live. */
+   result = vmci_resource_add(entry-resource,
+  VMCI_RESOURCE_TYPE_DATAGRAM,
+  handle);
+   if (result != VMCI_SUCCESS) {
+   pr_warn(Failed to add new resource (handle=0x%x:0x%x), error: 
%d\n,
+   handle.context, handle.resource, result);
+   kfree(entry);
+   return result;
+   }
+
+   *out_handle = vmci_resource_handle(entry-resource);
+   return VMCI_SUCCESS;
+}
+
+/*
+ * Internal utility function with the same purpose as
+ * vmci_datagram_get_priv_flags that also takes a context_id.
+ */
+static int vmci_datagram_get_priv_flags(u32 context_id,
+   struct vmci_handle handle,
+   u32 *priv_flags)
+{
+   if (context_id == VMCI_INVALID_ID)
+   return VMCI_ERROR_INVALID_ARGS;
+
+   if (context_id == VMCI_HOST_CONTEXT_ID) {
+   struct datagram_entry *src_entry;
+   struct vmci_resource *resource;
+
+   resource = vmci_resource_by_handle(handle,
+  VMCI_RESOURCE_TYPE_DATAGRAM);
+   if (!resource)
+   return VMCI_ERROR_INVALID_ARGS;
+
+   src_entry = container_of(resource, struct datagram_entry,
+   

[PATCH 02/12] VMCI: datagram implementation.

2012-11-21 Thread George Zhang
VMCI datagram Implements datagrams to allow data to be sent between host and 
guest.

Signed-off-by: George Zhang georgezh...@vmware.com
Signed-off-by: Dmitry Torokhov d...@vmware.com
Signed-off-by: Andy King ack...@vmware.com

---
 drivers/misc/vmw_vmci/vmci_datagram.c |  501 +
 drivers/misc/vmw_vmci/vmci_datagram.h |   52 +++
 2 files changed, 553 insertions(+), 0 deletions(-)
 create mode 100644 drivers/misc/vmw_vmci/vmci_datagram.c
 create mode 100644 drivers/misc/vmw_vmci/vmci_datagram.h

diff --git a/drivers/misc/vmw_vmci/vmci_datagram.c 
b/drivers/misc/vmw_vmci/vmci_datagram.c
new file mode 100644
index 000..a6513f4
--- /dev/null
+++ b/drivers/misc/vmw_vmci/vmci_datagram.c
@@ -0,0 +1,501 @@
+/*
+ * 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.
+ */
+
+#include linux/vmw_vmci_defs.h
+#include linux/vmw_vmci_api.h
+#include linux/module.h
+#include linux/sched.h
+#include linux/slab.h
+#include linux/bug.h
+
+#include vmci_common_int.h
+#include vmci_datagram.h
+#include vmci_resource.h
+#include vmci_context.h
+#include vmci_driver.h
+#include vmci_event.h
+#include vmci_route.h
+
+/*
+ * struct datagram_entry describes the datagram entity. It is used for datagram
+ * entities created only on the host.
+ */
+struct datagram_entry {
+   struct vmci_resource resource;
+   u32 flags;
+   bool run_delayed;
+   vmci_datagram_recv_cb recv_cb;
+   void *client_data;
+   u32 priv_flags;
+};
+
+struct delayed_datagram_info {
+   struct datagram_entry *entry;
+   struct vmci_datagram msg;
+   struct work_struct work;
+   bool in_dg_host_queue;
+};
+
+/* Number of in-flight host-host datagrams */
+static atomic_t delayed_dg_host_queue_size = ATOMIC_INIT(0);
+
+/*
+ * Create a datagram entry given a handle pointer.
+ */
+static int dg_create_handle(u32 resource_id,
+   u32 flags,
+   u32 priv_flags,
+   vmci_datagram_recv_cb recv_cb,
+   void *client_data, struct vmci_handle *out_handle)
+{
+   int result;
+   u32 context_id;
+   struct vmci_handle handle;
+   struct datagram_entry *entry;
+
+   if ((flags  VMCI_FLAG_WELLKNOWN_DG_HND) != 0)
+   return VMCI_ERROR_INVALID_ARGS;
+
+   if ((flags  VMCI_FLAG_ANYCID_DG_HND) != 0) {
+   context_id = VMCI_INVALID_ID;
+   } else {
+   context_id = vmci_get_context_id();
+   if (context_id == VMCI_INVALID_ID)
+   return VMCI_ERROR_NO_RESOURCES;
+   }
+
+   handle = vmci_make_handle(context_id, resource_id);
+
+   entry = kmalloc(sizeof(*entry), GFP_KERNEL);
+   if (!entry) {
+   pr_warn(Failed allocating memory for datagram entry.\n);
+   return VMCI_ERROR_NO_MEM;
+   }
+
+   entry-run_delayed = (flags  VMCI_FLAG_DG_DELAYED_CB) ? true : false;
+   entry-flags = flags;
+   entry-recv_cb = recv_cb;
+   entry-client_data = client_data;
+   entry-priv_flags = priv_flags;
+
+   /* Make datagram resource live. */
+   result = vmci_resource_add(entry-resource,
+  VMCI_RESOURCE_TYPE_DATAGRAM,
+  handle);
+   if (result != VMCI_SUCCESS) {
+   pr_warn(Failed to add new resource (handle=0x%x:0x%x), error: 
%d\n,
+   handle.context, handle.resource, result);
+   kfree(entry);
+   return result;
+   }
+
+   *out_handle = vmci_resource_handle(entry-resource);
+   return VMCI_SUCCESS;
+}
+
+/*
+ * Internal utility function with the same purpose as
+ * vmci_datagram_get_priv_flags that also takes a context_id.
+ */
+static int vmci_datagram_get_priv_flags(u32 context_id,
+   struct vmci_handle handle,
+   u32 *priv_flags)
+{
+   if (context_id == VMCI_INVALID_ID)
+   return VMCI_ERROR_INVALID_ARGS;
+
+   if (context_id == VMCI_HOST_CONTEXT_ID) {
+   struct datagram_entry *src_entry;
+   struct vmci_resource *resource;
+
+   resource = vmci_resource_by_handle(handle,
+  VMCI_RESOURCE_TYPE_DATAGRAM);
+   if (!resource)
+   return VMCI_ERROR_INVALID_ARGS;
+
+   src_entry = container_of(resource, struct 

[PATCH 02/12] VMCI: datagram implementation.

2012-11-01 Thread George Zhang
VMCI datagram Implements datagrams to allow data to be sent between host
and guest.


Signed-off-by: George Zhang georgezh...@vmware.com
---
 drivers/misc/vmw_vmci/vmci_datagram.c |  506 +
 drivers/misc/vmw_vmci/vmci_datagram.h |   52 +++
 2 files changed, 558 insertions(+), 0 deletions(-)
 create mode 100644 drivers/misc/vmw_vmci/vmci_datagram.c
 create mode 100644 drivers/misc/vmw_vmci/vmci_datagram.h

diff --git a/drivers/misc/vmw_vmci/vmci_datagram.c 
b/drivers/misc/vmw_vmci/vmci_datagram.c
new file mode 100644
index 000..d755e31
--- /dev/null
+++ b/drivers/misc/vmw_vmci/vmci_datagram.c
@@ -0,0 +1,506 @@
+/*
+ * 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.
+ */
+
+#include linux/vmw_vmci_defs.h
+#include linux/vmw_vmci_api.h
+#include linux/module.h
+#include linux/sched.h
+#include linux/slab.h
+#include linux/bug.h
+
+#include vmci_common_int.h
+#include vmci_datagram.h
+#include vmci_resource.h
+#include vmci_context.h
+#include vmci_driver.h
+#include vmci_event.h
+#include vmci_route.h
+
+/*
+ * struct datagram_entry describes the datagram entity. It is used for datagram
+ * entities created only on the host.
+ */
+struct datagram_entry {
+   struct vmci_resource resource;
+   u32 flags;
+   bool run_delayed;
+   vmci_datagram_recv_cb recv_cb;
+   void *client_data;
+   u32 priv_flags;
+};
+
+struct delayed_datagram_info {
+   struct datagram_entry *entry;
+   struct vmci_datagram msg;
+   struct work_struct work;
+   bool in_dg_host_queue;
+};
+
+/* Number of in-flight host-host datagrams */
+static atomic_t delayed_dg_host_queue_size = ATOMIC_INIT(0);
+
+/*
+ * Create a datagram entry given a handle pointer.
+ */
+static int dg_create_handle(u32 resource_id,
+   u32 flags,
+   u32 priv_flags,
+   vmci_datagram_recv_cb recv_cb,
+   void *client_data, struct vmci_handle *out_handle)
+{
+   int result;
+   u32 context_id;
+   struct vmci_handle handle;
+   struct datagram_entry *entry;
+
+   BUG_ON(!recv_cb);
+   BUG_ON(!out_handle);
+   BUG_ON(priv_flags  ~VMCI_PRIVILEGE_ALL_FLAGS);
+
+   if ((flags  VMCI_FLAG_WELLKNOWN_DG_HND) != 0)
+   return VMCI_ERROR_INVALID_ARGS;
+
+   if ((flags  VMCI_FLAG_ANYCID_DG_HND) != 0) {
+   context_id = VMCI_INVALID_ID;
+   } else {
+   context_id = vmci_get_context_id();
+   if (context_id == VMCI_INVALID_ID)
+   return VMCI_ERROR_NO_RESOURCES;
+   }
+
+   handle = vmci_make_handle(context_id, resource_id);
+
+   entry = kmalloc(sizeof(*entry), GFP_KERNEL);
+   if (!entry) {
+   pr_warn(Failed allocating memory for datagram entry.\n);
+   return VMCI_ERROR_NO_MEM;
+   }
+
+   entry-run_delayed = (flags  VMCI_FLAG_DG_DELAYED_CB) ? true : false;
+   entry-flags = flags;
+   entry-recv_cb = recv_cb;
+   entry-client_data = client_data;
+   entry-priv_flags = priv_flags;
+
+   /* Make datagram resource live. */
+   result = vmci_resource_add(entry-resource,
+  VMCI_RESOURCE_TYPE_DATAGRAM,
+  handle);
+   if (result != VMCI_SUCCESS) {
+   pr_warn(Failed to add new resource (handle=0x%x:0x%x), error: 
%d\n,
+   handle.context, handle.resource, result);
+   kfree(entry);
+   return result;
+   }
+
+   *out_handle = vmci_resource_handle(entry-resource);
+   return VMCI_SUCCESS;
+}
+
+/*
+ * Internal utility function with the same purpose as
+ * vmci_datagram_get_priv_flags that also takes a context_id.
+ */
+static int vmci_datagram_get_priv_flags(u32 context_id,
+   struct vmci_handle handle,
+   u32 *priv_flags)
+{
+   if (context_id == VMCI_INVALID_ID)
+   return VMCI_ERROR_INVALID_ARGS;
+
+   if (context_id == VMCI_HOST_CONTEXT_ID) {
+   struct datagram_entry *src_entry;
+   struct vmci_resource *resource;
+
+   resource = vmci_resource_by_handle(handle,
+  VMCI_RESOURCE_TYPE_DATAGRAM);
+   if (!resource)
+   return VMCI_ERROR_INVALID_ARGS;
+
+   src_entry =