Re: [PATCH 21/28] staging: most: fix retrieval of buffer availability

2015-12-24 Thread Sudip Mukherjee
On Tue, Dec 22, 2015 at 10:53:02AM +0100, Christian Gromm wrote:
> This patch fixes the function channel_has_mbo that delivers the false
> information in case two AIMs are using the same tx channel.
> 
> Signed-off-by: Christian Gromm 
> ---
> 

> diff --git a/drivers/staging/most/mostcore/core.c 
> b/drivers/staging/most/mostcore/core.c
> index b085f0a..ff0e0dc 100644
> --- a/drivers/staging/most/mostcore/core.c
> +++ b/drivers/staging/most/mostcore/core.c
> @@ -1352,7 +1352,7 @@ most_c_obj *get_channel_by_iface(struct most_interface 
> *iface, int id)
>   return i->channel[id];
>  }
>  
> -int channel_has_mbo(struct most_interface *iface, int id)
> +int channel_has_mbo(struct most_interface *iface, int id, struct most_aim 
> *aim)
>  {
>   struct most_c_obj *c = get_channel_by_iface(iface, id);
>   unsigned long flags;
> @@ -1361,6 +1361,11 @@ int channel_has_mbo(struct most_interface *iface, int 
> id)
>   if (unlikely(!c))
>   return -EINVAL;
>  
> + if (c->aim0.refs && c->aim1.refs &&
> + ((aim == c->aim0.ptr && c->aim0.num_buffers <= 0) ||
> +  (aim == c->aim1.ptr && c->aim1.num_buffers <= 0)))
> + return false;

channel_has_mbo() return int. maybe return 0 instead of return false..

regards
sudip
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [RFC PATCH 00/15] staging/rdma/hfi1: Initial patches to add rdmavt support in HFI1

2015-12-24 Thread ira.weiny
On Tue, Dec 22, 2015 at 06:27:57PM -0800, gre...@linuxfoundation.org wrote:
> On Tue, Dec 22, 2015 at 02:15:08PM -0500, ira.weiny wrote:
> > On Mon, Dec 21, 2015 at 05:01:48PM -0800, gre...@linuxfoundation.org wrote:

[snip]

> > > 
> > > No, git is good :)
> > > 
> > > > How do we handle changes which affect both qib and hfi1?
> > > 
> > > I don't know, now this gets messy...
> > > 
> > 
> > Agreed and this is what we are worried about.
> > 
> > Can we do what Dan and Doug have proposed in the past and have Doug take 
> > over
> > the staging/rdma sub-tree?
> > 
> > http://driverdev.linuxdriverproject.org/pipermail/driverdev-devel/2015-November/081922.html
> > 
> > I think the upcoming merge window is a reasonable time for him to do that.
> 
> Ok, but keeping on top of all of the generic staging patches that come
> in is a tough thing to do, that's up to Doug, if he is ready for it...
> 

To help this process, once the change over happens, we will help to monitor
driverdev-devel for anything submitted to staging/rdma.  If something is
submitted which was not to Doug and linux-rdma we can handle alerting the
submitter to make sure it gets submitted to Doug as per the current MAINTAINERS
file.

Hope this helps,
Ira

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH] staging: most: replace multiple if..else with table lookup

2015-12-24 Thread Joe Perches
On Thu, 2015-12-24 at 10:49 +, Gujulan Elango, Hari Prasath (H.) wrote:
> From: Hari Prasath Gujulan Elango 
> 
> Replace multiple if..else if..statements with simple table lookup in two
> functions.
> 
> Signed-off-by: Hari Prasath Gujulan Elango 
> ---
>  drivers/staging/most/mostcore/core.c | 39 
> 
>  1 file changed, 22 insertions(+), 17 deletions(-)
> 
> diff --git a/drivers/staging/most/mostcore/core.c 
> b/drivers/staging/most/mostcore/core.c
> index ed1ed25..7b4636b 100644
> --- a/drivers/staging/most/mostcore/core.c
> +++ b/drivers/staging/most/mostcore/core.c
> @@ -82,6 +82,14 @@ struct most_inst_obj {
>   struct list_head list;
>  };
>  
> +static const struct {
> + int most_ch_data_type;
> + char *name;
> +} ch_data_type[] = { { MOST_CH_CONTROL, "control\n" },
> + { MOST_CH_ASYNC, "async\n" },
> + { MOST_CH_SYNC, "sync\n" },
> + { MOST_CH_ISOC_AVP, "isoc_avp\n"} };
> +
>  #define to_inst_obj(d) container_of(d, struct most_inst_obj, kobj)
>  
>  /**
> @@ -414,14 +422,12 @@ static ssize_t show_set_datatype(struct most_c_obj *c,
>    struct most_c_attr *attr,
>    char *buf)
>  {
> - if (c->cfg.data_type & MOST_CH_CONTROL)
> - return snprintf(buf, PAGE_SIZE, "control\n");
> - else if (c->cfg.data_type & MOST_CH_ASYNC)
> - return snprintf(buf, PAGE_SIZE, "async\n");
> - else if (c->cfg.data_type & MOST_CH_SYNC)
> - return snprintf(buf, PAGE_SIZE, "sync\n");
> - else if (c->cfg.data_type & MOST_CH_ISOC_AVP)
> - return snprintf(buf, PAGE_SIZE, "isoc_avp\n");
> + int i;
> +
> + for (i = 0; i < ARRAY_SIZE(ch_data_type); i++) {
> + if (c->cfg.data_type & ch_data_type[i].most_ch_data_type)
> + return snprintf(buf, PAGE_SIZE, ch_data_type[i].name);
> + }
>   return snprintf(buf, PAGE_SIZE, "unconfigured\n");
>  }
>  
> @@ -430,15 +436,14 @@ static ssize_t store_set_datatype(struct most_c_obj *c,
>     const char *buf,
>     size_t count)
>  {
> - if (!strcmp(buf, "control\n")) {
> - c->cfg.data_type = MOST_CH_CONTROL;
> - } else if (!strcmp(buf, "async\n")) {
> - c->cfg.data_type = MOST_CH_ASYNC;
> - } else if (!strcmp(buf, "sync\n")) {
> - c->cfg.data_type = MOST_CH_SYNC;
> - } else if (!strcmp(buf, "isoc_avp\n")) {
> - c->cfg.data_type = MOST_CH_ISOC_AVP;
> - } else {
> + int i;
> +
> + for (i = 0; i < ARRAY_SIZE(ch_data_type); i++) {
> + if (!strcmp(buf, ch_data_type[i].name))
> + c->cfg.data_type = ch_data_type[i].most_ch_data_type;

Missing braces and break;

> + }
> +
> + if (i == ARRAY_SIZE(ch_data_type)) {
>   pr_info("WARN: invalid attribute settings\n");
>   return -EINVAL;
>   }

This seems like a lot of code for a simple test.

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH] staging: most: replace multiple if..else with table lookup

2015-12-24 Thread Gujulan Elango, Hari Prasath (H.)
From: Hari Prasath Gujulan Elango 

Replace multiple if..else if..statements with simple table lookup in two
functions.

Signed-off-by: Hari Prasath Gujulan Elango 
---
 drivers/staging/most/mostcore/core.c | 39 
 1 file changed, 22 insertions(+), 17 deletions(-)

diff --git a/drivers/staging/most/mostcore/core.c 
b/drivers/staging/most/mostcore/core.c
index ed1ed25..7b4636b 100644
--- a/drivers/staging/most/mostcore/core.c
+++ b/drivers/staging/most/mostcore/core.c
@@ -82,6 +82,14 @@ struct most_inst_obj {
struct list_head list;
 };
 
+static const struct {
+   int most_ch_data_type;
+   char *name;
+} ch_data_type[] = { { MOST_CH_CONTROL, "control\n" },
+   { MOST_CH_ASYNC, "async\n" },
+   { MOST_CH_SYNC, "sync\n" },
+   { MOST_CH_ISOC_AVP, "isoc_avp\n"} };
+
 #define to_inst_obj(d) container_of(d, struct most_inst_obj, kobj)
 
 /**
@@ -414,14 +422,12 @@ static ssize_t show_set_datatype(struct most_c_obj *c,
 struct most_c_attr *attr,
 char *buf)
 {
-   if (c->cfg.data_type & MOST_CH_CONTROL)
-   return snprintf(buf, PAGE_SIZE, "control\n");
-   else if (c->cfg.data_type & MOST_CH_ASYNC)
-   return snprintf(buf, PAGE_SIZE, "async\n");
-   else if (c->cfg.data_type & MOST_CH_SYNC)
-   return snprintf(buf, PAGE_SIZE, "sync\n");
-   else if (c->cfg.data_type & MOST_CH_ISOC_AVP)
-   return snprintf(buf, PAGE_SIZE, "isoc_avp\n");
+   int i;
+
+   for (i = 0; i < ARRAY_SIZE(ch_data_type); i++) {
+   if (c->cfg.data_type & ch_data_type[i].most_ch_data_type)
+   return snprintf(buf, PAGE_SIZE, ch_data_type[i].name);
+   }
return snprintf(buf, PAGE_SIZE, "unconfigured\n");
 }
 
@@ -430,15 +436,14 @@ static ssize_t store_set_datatype(struct most_c_obj *c,
  const char *buf,
  size_t count)
 {
-   if (!strcmp(buf, "control\n")) {
-   c->cfg.data_type = MOST_CH_CONTROL;
-   } else if (!strcmp(buf, "async\n")) {
-   c->cfg.data_type = MOST_CH_ASYNC;
-   } else if (!strcmp(buf, "sync\n")) {
-   c->cfg.data_type = MOST_CH_SYNC;
-   } else if (!strcmp(buf, "isoc_avp\n")) {
-   c->cfg.data_type = MOST_CH_ISOC_AVP;
-   } else {
+   int i;
+
+   for (i = 0; i < ARRAY_SIZE(ch_data_type); i++) {
+   if (!strcmp(buf, ch_data_type[i].name))
+   c->cfg.data_type = ch_data_type[i].most_ch_data_type;
+   }
+
+   if (i == ARRAY_SIZE(ch_data_type)) {
pr_info("WARN: invalid attribute settings\n");
return -EINVAL;
}
-- 
1.9.1
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH V5 0/9] introduce Hyper-V VM Sockets(hvsock

2015-12-24 Thread Dexuan Cui
Merry Christmas, everyone!

Changes since v1:
- updated "[PATCH 6/7] hvsock: introduce Hyper-V VM Sockets feature"
- added __init and __exit for the module init/exit functions
- net/hv_sock/Kconfig: "default m" -> "default m if HYPERV"
- MODULE_LICENSE: "Dual MIT/GPL" -> "Dual BSD/GPL" 

Changes since v2:
- fixed various coding issue pointed out by David Miller
- fixed indentation issues
- removed pr_debug in net/hv_sock/af_hvsock.c
- used reverse-Chrismas-tree style for local variables.
- EXPORT_SYMBOL -> EXPORT_SYMBOL_GPL

Changes since v3:
- fixed a few coding issue pointed by Vitaly Kuznetsov and Dan Carpenter
- fixed the ret value in vmbus_recvpacket_hvsock on error
- fixed the style of multi-line comment: vmbus_get_hvsock_rw_status()

Changes since v4 (https://lkml.org/lkml/2015/7/28/404):
- addressed all the comments about V4.
- treat the hvsock offers/channels as special VMBus devices
- add a mechanism to pass hvsock events to the hvsock driver
- fixed some corner cases with proper locking when a connection is closed
- rebased to the latest Greg's tree

Hyper-V VM Sockets (hvsock) is a byte-stream based communication mechanism
between Windowsd 10 (or later) host and a guest. It's kind of TCP over
VMBus, but the transportation layer (VMBus) is much simpler than IP.
With Hyper-V VM Sockets, applications between the host and a guest can
talk with each other directly by the traditional BSD-style socket APIs.

The patchset implements the necessary support in the guest side by adding
the necessary new APIs in the vmbus driver, and introducing a new driver
hv_sock.ko, which implements_a new socket address family AF_HYPERV.

I know the kernel has already had a VM Sockets driver (AF_VSOCK) based
on VMware's VMCI (net/vmw_vsock/, drivers/misc/vmw_vmci), and KVM is
proposing AF_VSOCK of virtio version:
http://thread.gmane.org/gmane.linux.network/365205.

However, though Hyper-V VM Sockets may seem conceptually similar to
AF_VOSCK, there are differences in the transportation layer, and IMO these
make the direct code reusing impractical:

1. In AF_VSOCK, the endpoint type is: , but in
AF_HYPERV, the endpoint type is: . Here GUID
is 128-bit.

2. AF_VSOCK supports SOCK_DGRAM, while AF_HYPERV doesn't.

3. AF_VSOCK supports some special sock opts, like SO_VM_SOCKETS_BUFFER_SIZE,
SO_VM_SOCKETS_BUFFER_MIN/MAX_SIZE and SO_VM_SOCKETS_CONNECT_TIMEOUT.
These are meaningless to AF_HYPERV.

4. Some AF_VSOCK's VMCI transportation ops are meanless to AF_HYPERV/VMBus,
like.notify_recv_init
.notify_recv_pre_block
.notify_recv_pre_dequeue
.notify_recv_post_dequeue
.notify_send_init
.notify_send_pre_block
.notify_send_pre_enqueue
.notify_send_post_enqueue
etc.

So I think we'd better introduce a new address family: AF_HYPERV.

Please review the patchset.

Looking forward to your comments!

Dexuan Cui (9):
  Drivers: hv: vmbus: add a helper function to set a channel's pending
send size
  Drivers: hv: vmbus: define the new offer type for Hyper-V socket
(hvsock)
  Drivers: hv: vmbus: define a new VMBus message type for hvsock
  Drivers: hv: ring_buffer: enhance hv_ringbuffer_read() to support
hvsock
  Drivers: hv: vmbus: add APIs to send/recv hvsock packets
  Drivers: hv: vmbus: add a hvsock flag in struct hv_driver
  Drivers: hv: vmbus: add a mechanism to pass hvsock events to the
hvsock driver
  Drivers: hv: vmbus: add an API vmbus_hvsock_device_unregister()
  hvsock: introduce Hyper-V VM Sockets feature

 MAINTAINERS |2 +
 drivers/hv/channel.c|   84 ++-
 drivers/hv/channel_mgmt.c   |   53 +-
 drivers/hv/connection.c |4 +-
 drivers/hv/hyperv_vmbus.h   |   13 +-
 drivers/hv/ring_buffer.c|   54 +-
 drivers/hv/vmbus_drv.c  |4 +
 include/linux/hyperv.h  |   88 +++
 include/linux/socket.h  |4 +-
 include/net/af_hvsock.h |   44 ++
 include/uapi/linux/hyperv.h |   16 +
 net/Kconfig |1 +
 net/Makefile|1 +
 net/hv_sock/Kconfig |   10 +
 net/hv_sock/Makefile|3 +
 net/hv_sock/af_hvsock.c | 1473 +++
 16 files changed, 1830 insertions(+), 24 deletions(-)
 create mode 100644 include/net/af_hvsock.h
 create mode 100644 net/hv_sock/Kconfig
 create mode 100644 net/hv_sock/Makefile
 create mode 100644 net/hv_sock/af_hvsock.c

-- 
2.1.4

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH V5 1/9] Drivers: hv: vmbus: add a helper function to set a channel's pending send size

2015-12-24 Thread Dexuan Cui
This will be used by the coming net/hvsock driver.

Signed-off-by: Dexuan Cui 
---
 include/linux/hyperv.h | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
index 753dbad..e4867a7 100644
--- a/include/linux/hyperv.h
+++ b/include/linux/hyperv.h
@@ -790,6 +790,12 @@ static inline void *get_per_channel_state(struct 
vmbus_channel *c)
return c->per_channel_state;
 }
 
+static inline void set_channel_pending_send_size(struct vmbus_channel *c,
+u32 size)
+{
+   c->outbound.ring_buffer->pending_send_sz = size;
+}
+
 void vmbus_onmessage(void *context);
 
 int vmbus_request_offers(void);
-- 
2.1.4

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH V5 8/9] Drivers: hv: vmbus: add an API vmbus_hvsock_device_unregister()

2015-12-24 Thread Dexuan Cui
The hvsock driver needs this API to release all the resources related
to the channel.

Signed-off-by: Dexuan Cui 
---
 drivers/hv/channel_mgmt.c | 33 -
 drivers/hv/connection.c   |  4 ++--
 include/linux/hyperv.h|  2 ++
 3 files changed, 32 insertions(+), 7 deletions(-)

diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c
index 87fc7d2..f963645 100644
--- a/drivers/hv/channel_mgmt.c
+++ b/drivers/hv/channel_mgmt.c
@@ -195,6 +195,7 @@ void hv_process_channel_removal(struct vmbus_channel 
*channel, u32 relid)
vmbus_release_relid(relid);
 
BUG_ON(!channel->rescind);
+   BUG_ON(!mutex_is_locked(_connection.channel_mutex));
 
if (channel->target_cpu != get_cpu()) {
put_cpu();
@@ -206,9 +207,7 @@ void hv_process_channel_removal(struct vmbus_channel 
*channel, u32 relid)
}
 
if (channel->primary_channel == NULL) {
-   mutex_lock(_connection.channel_mutex);
list_del(>listentry);
-   mutex_unlock(_connection.channel_mutex);
 
primary_channel = channel;
} else {
@@ -251,6 +250,7 @@ static void vmbus_process_offer(struct vmbus_channel 
*newchannel)
struct vmbus_channel *channel;
bool fnew = true;
unsigned long flags;
+   int ret;
 
/* Make sure this is a new offer */
mutex_lock(_connection.channel_mutex);
@@ -330,7 +330,11 @@ static void vmbus_process_offer(struct vmbus_channel 
*newchannel)
 * binding which eventually invokes the device driver's AddDevice()
 * method.
 */
-   if (vmbus_device_register(newchannel->device_obj) != 0) {
+   mutex_lock(_connection.channel_mutex);
+   ret = vmbus_device_register(newchannel->device_obj);
+   mutex_unlock(_connection.channel_mutex);
+
+   if (ret != 0) {
pr_err("unable to add child device object (relid %d)\n",
newchannel->offermsg.child_relid);
kfree(newchannel->device_obj);
@@ -592,6 +596,8 @@ static void vmbus_onoffer_rescind(struct 
vmbus_channel_message_header *hdr)
struct device *dev;
 
rescind = (struct vmbus_channel_rescind_offer *)hdr;
+
+   mutex_lock(_connection.channel_mutex);
channel = relid2channel(rescind->child_relid);
 
if (channel == NULL) {
@@ -600,7 +606,7 @@ static void vmbus_onoffer_rescind(struct 
vmbus_channel_message_header *hdr)
 * vmbus_process_offer(), we have already invoked
 * vmbus_release_relid() on error.
 */
-   return;
+   goto out;
}
 
spin_lock_irqsave(>lock, flags);
@@ -616,7 +622,7 @@ static void vmbus_onoffer_rescind(struct 
vmbus_channel_message_header *hdr)
 * We can't invoke vmbus_device_unregister()
 * until the socket fd is closed.
 */
-   return;
+   goto out;
}
/*
 * We will have to unregister this device from the
@@ -631,7 +637,24 @@ static void vmbus_onoffer_rescind(struct 
vmbus_channel_message_header *hdr)
hv_process_channel_removal(channel,
channel->offermsg.child_relid);
}
+
+out:
+   mutex_unlock(_connection.channel_mutex);
+}
+
+
+void vmbus_hvsock_device_unregister(struct vmbus_channel *channel)
+{
+   mutex_lock(_connection.channel_mutex);
+
+   BUG_ON(!is_hvsock_channel(channel));
+
+   channel->rescind = true;
+   vmbus_device_unregister(channel->device_obj);
+
+   mutex_unlock(_connection.channel_mutex);
 }
+EXPORT_SYMBOL_GPL(vmbus_hvsock_device_unregister);
 
 /*
  * vmbus_onoffers_delivered -
diff --git a/drivers/hv/connection.c b/drivers/hv/connection.c
index 3dc5a9c..deb48e6 100644
--- a/drivers/hv/connection.c
+++ b/drivers/hv/connection.c
@@ -288,7 +288,8 @@ struct vmbus_channel *relid2channel(u32 relid)
struct list_head *cur, *tmp;
struct vmbus_channel *cur_sc;
 
-   mutex_lock(_connection.channel_mutex);
+   BUG_ON(!mutex_is_locked(_connection.channel_mutex));
+
list_for_each_entry(channel, _connection.chn_list, listentry) {
if (channel->offermsg.child_relid == relid) {
found_channel = channel;
@@ -307,7 +308,6 @@ struct vmbus_channel *relid2channel(u32 relid)
}
}
}
-   mutex_unlock(_connection.channel_mutex);
 
return found_channel;
 }
diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
index 7e507bb..8e59f98 100644
--- a/include/linux/hyperv.h
+++ b/include/linux/hyperv.h
@@ -1055,6 +1055,8 @@ int __must_check __vmbus_driver_register(struct hv_driver 
*hv_driver,
 const char *mod_name);
 void vmbus_driver_unregister(struct hv_driver *hv_driver);

[PATCH] staging: dgnc: convert to wait_event_interruptible_timeout

2015-12-24 Thread Gujulan Elango, Hari Prasath (H.)
This patch makes use of wait_event_interruptible_timeout to achieve timeout
functionality.This is a TODO mentiond in the comment which is also removed.
It also aligns with what the function is supposed to do as in the
comments.

Signed-off-by: Hari Prasath Gujulan Elango 
---
 drivers/staging/dgnc/dgnc_neo.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/staging/dgnc/dgnc_neo.c b/drivers/staging/dgnc/dgnc_neo.c
index 39c76e7..7d9efe0 100644
--- a/drivers/staging/dgnc/dgnc_neo.c
+++ b/drivers/staging/dgnc/dgnc_neo.c
@@ -1306,10 +1306,8 @@ static int neo_drain(struct tty_struct *tty, uint 
seconds)
/*
 * Go to sleep waiting for the tty layer to wake me back up when
 * the empty flag goes away.
-*
-* NOTE: TODO: Do something with time passed in.
 */
-   rc = wait_event_interruptible(un->un_flags_wait, ((un->un_flags & 
UN_EMPTY) == 0));
+   rc = wait_event_interruptible_timeout(un->un_flags_wait, ((un->un_flags 
& UN_EMPTY) == 0), msecs_to_jiffies(seconds * 1000));
 
/* If ret is non-zero, user ctrl-c'ed us */
return rc;
-- 
1.9.1
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH V5 7/9] Drivers: hv: vmbus: add a mechanism to pass hvsock events to the hvsock driver

2015-12-24 Thread Dexuan Cui
For now only 1 event is defined: HVSOCK_RESCIND_CHANNEL.
We'll have more events in the future.

Signed-off-by: Dexuan Cui 
---
 drivers/hv/channel_mgmt.c | 18 ++
 include/linux/hyperv.h| 17 +
 2 files changed, 35 insertions(+)

diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c
index 4611b50..87fc7d2 100644
--- a/drivers/hv/channel_mgmt.c
+++ b/drivers/hv/channel_mgmt.c
@@ -608,6 +608,16 @@ static void vmbus_onoffer_rescind(struct 
vmbus_channel_message_header *hdr)
spin_unlock_irqrestore(>lock, flags);
 
if (channel->device_obj) {
+   if (is_hvsock_channel(channel) &&
+   channel->hvsock_event_callback) {
+   channel->hvsock_event_callback(channel,
+  HVSOCK_RESCIND_CHANNEL);
+   /*
+* We can't invoke vmbus_device_unregister()
+* until the socket fd is closed.
+*/
+   return;
+   }
/*
 * We will have to unregister this device from the
 * driver core.
@@ -977,3 +987,11 @@ bool vmbus_are_subchannels_present(struct vmbus_channel 
*primary)
return ret;
 }
 EXPORT_SYMBOL_GPL(vmbus_are_subchannels_present);
+
+void vmbus_set_hvsock_event_callback(struct vmbus_channel *channel,
+   void (*hvsock_event_callback)(struct vmbus_channel *,
+ enum hvsock_event))
+{
+   channel->hvsock_event_callback = hvsock_event_callback;
+}
+EXPORT_SYMBOL_GPL(vmbus_set_hvsock_event_callback);
diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
index b4cc44c..7e507bb 100644
--- a/include/linux/hyperv.h
+++ b/include/linux/hyperv.h
@@ -645,6 +645,12 @@ enum hv_signal_policy {
HV_SIGNAL_POLICY_EXPLICIT,
 };
 
+/* hvsock related definitions */
+enum hvsock_event {
+   /* The host application is close()-ing the connection */
+   HVSOCK_RESCIND_CHANNEL,
+};
+
 struct vmbus_channel {
/* Unique channel id */
int id;
@@ -740,6 +746,13 @@ struct vmbus_channel {
void (*sc_creation_callback)(struct vmbus_channel *new_sc);
 
/*
+* hvsock event callback.
+* For now only 1 event is defined: HVSOCK_RESCIND_CHANNEL.
+*/
+   void (*hvsock_event_callback)(struct vmbus_channel *channel,
+ enum hvsock_event event);
+
+   /*
 * The spinlock to protect the structure. It is being used to protect
 * test-and-set access to various attributes of the structure as well
 * as all sc_list operations.
@@ -825,6 +838,10 @@ int vmbus_request_offers(void);
 void vmbus_set_sc_create_callback(struct vmbus_channel *primary_channel,
void (*sc_cr_cb)(struct vmbus_channel *new_sc));
 
+void vmbus_set_hvsock_event_callback(struct vmbus_channel *channel,
+   void (*hvsock_event_callback)(struct vmbus_channel *,
+ enum hvsock_event));
+
 /*
  * Retrieve the (sub) channel on which to send an outgoing request.
  * When a primary channel has multiple sub-channels, we choose a
-- 
2.1.4

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH V5 4/9] Drivers: hv: ring_buffer: enhance hv_ringbuffer_read() to support hvsock

2015-12-24 Thread Dexuan Cui
To get the payload of hvsock, we need raw=0 to skip the level-1 header
(i.e., struct vmpacket_descriptor desc) and we also need to skip the
level-2 header (i.e., struct vmpipe_proto_header pipe_hdr).

NB: if the length of the hvsock payload is not aligned with the 8-byte
boundeary, at most 7 padding bytes are appended, so the real hvsock
payload's length must be retrieved by the pipe_hdr.data_size field.

I 'upgrade' the 'raw' parameter of hv_ringbuffer_read() to a
'read_flags', trying to share the logic of the function.

This patch is required by the next patch, which will introduce the hvsock
send/recv APIs.

Signed-off-by: Dexuan Cui 
Cc: Vitaly Kuznetsov 
---
 drivers/hv/channel.c  | 10 +
 drivers/hv/hyperv_vmbus.h | 13 +++-
 drivers/hv/ring_buffer.c  | 54 ---
 include/linux/hyperv.h| 12 +++
 4 files changed, 72 insertions(+), 17 deletions(-)

diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c
index eaaa066..cc49966 100644
--- a/drivers/hv/channel.c
+++ b/drivers/hv/channel.c
@@ -940,13 +940,14 @@ EXPORT_SYMBOL_GPL(vmbus_sendpacket_multipagebuffer);
 static inline int
 __vmbus_recvpacket(struct vmbus_channel *channel, void *buffer,
   u32 bufferlen, u32 *buffer_actual_len, u64 *requestid,
-  bool raw)
+  u32 read_flags)
 {
int ret;
bool signal = false;
 
ret = hv_ringbuffer_read(>inbound, buffer, bufferlen,
-buffer_actual_len, requestid, , raw);
+buffer_actual_len, requestid, ,
+read_flags);
 
if (signal)
vmbus_setevent(channel);
@@ -959,7 +960,7 @@ int vmbus_recvpacket(struct vmbus_channel *channel, void 
*buffer,
 u64 *requestid)
 {
return __vmbus_recvpacket(channel, buffer, bufferlen,
- buffer_actual_len, requestid, false);
+ buffer_actual_len, requestid, 0);
 }
 EXPORT_SYMBOL(vmbus_recvpacket);
 
@@ -971,6 +972,7 @@ int vmbus_recvpacket_raw(struct vmbus_channel *channel, 
void *buffer,
  u64 *requestid)
 {
return __vmbus_recvpacket(channel, buffer, bufferlen,
- buffer_actual_len, requestid, true);
+ buffer_actual_len, requestid,
+ HV_RINGBUFFER_READ_FLAG_RAW);
 }
 EXPORT_SYMBOL_GPL(vmbus_recvpacket_raw);
diff --git a/drivers/hv/hyperv_vmbus.h b/drivers/hv/hyperv_vmbus.h
index 0411b7b..46206b6 100644
--- a/drivers/hv/hyperv_vmbus.h
+++ b/drivers/hv/hyperv_vmbus.h
@@ -619,9 +619,20 @@ int hv_ringbuffer_write(struct hv_ring_buffer_info 
*ring_info,
struct kvec *kv_list,
u32 kv_count, bool *signal);
 
+/*
+ * By default, a read_flags of 0 means: the payload offset is
+ * sizeof(struct vmpacket_descriptor).
+ *
+ * If HV_RINGBUFFER_READ_FLAG_RAW is used, the payload offset is 0.
+ *
+ * If HV_RINGBUFFER_READ_FLAG_HVSOCK is used, the payload offset is
+ * sizeof(struct vmpacket_descriptor) + sizeof(struct vmpipe_proto_header).
+ */
+#define HV_RINGBUFFER_READ_FLAG_RAW(1 << 0)
+#define HV_RINGBUFFER_READ_FLAG_HVSOCK (1 << 1)
 int hv_ringbuffer_read(struct hv_ring_buffer_info *inring_info,
   void *buffer, u32 buflen, u32 *buffer_actual_len,
-  u64 *requestid, bool *signal, bool raw);
+  u64 *requestid, bool *signal, u32 read_flags);
 
 void hv_ringbuffer_get_debuginfo(struct hv_ring_buffer_info *ring_info,
struct hv_ring_buffer_debug_info *debug_info);
diff --git a/drivers/hv/ring_buffer.c b/drivers/hv/ring_buffer.c
index b53702c..03a509c 100644
--- a/drivers/hv/ring_buffer.c
+++ b/drivers/hv/ring_buffer.c
@@ -382,32 +382,43 @@ int hv_ringbuffer_write(struct hv_ring_buffer_info 
*outring_info,
 
 int hv_ringbuffer_read(struct hv_ring_buffer_info *inring_info,
   void *buffer, u32 buflen, u32 *buffer_actual_len,
-  u64 *requestid, bool *signal, bool raw)
+  u64 *requestid, bool *signal, u32 read_flags)
 {
+   bool raw = !!(read_flags & HV_RINGBUFFER_READ_FLAG_RAW);
+   bool hvsock = !!(read_flags & HV_RINGBUFFER_READ_FLAG_HVSOCK);
+
u32 bytes_avail_towrite;
u32 bytes_avail_toread;
u32 next_read_location = 0;
u64 prev_indices = 0;
unsigned long flags;
-   struct vmpacket_descriptor desc;
+   struct vmpipe_proto_header *pipe_hdr;
+   struct vmpacket_descriptor *desc;
u32 offset;
-   u32 packetlen;
+   u32 packetlen, tot_hdrlen;
int ret = 0;
 
if (buflen <= 0)
return -EINVAL;
 
+   tot_hdrlen = sizeof(*desc);
+   if (hvsock)
+   tot_hdrlen += 

[PATCH V5 9/9] hvsock: introduce Hyper-V VM Sockets feature

2015-12-24 Thread Dexuan Cui
Hyper-V VM sockets (hvsock) supplies a byte-stream based communication
mechanism between the host and a guest. It's kind of TCP over VMBus, but
the transportation layer (VMBus) is much simpler than IP. With Hyper-V VM
Sockets, applications between the host and a guest can talk with each
other directly by the traditional BSD-style socket APIs.

Hyper-V VM Sockets is only available on Windows 10 host and later. The
patch implements the necessary support in the guest side by introducing
a new socket address family AF_HYPERV.

Signed-off-by: Dexuan Cui 
---
 MAINTAINERS |2 +
 include/linux/hyperv.h  |8 +
 include/linux/socket.h  |4 +-
 include/net/af_hvsock.h |   44 ++
 include/uapi/linux/hyperv.h |   16 +
 net/Kconfig |1 +
 net/Makefile|1 +
 net/hv_sock/Kconfig |   10 +
 net/hv_sock/Makefile|3 +
 net/hv_sock/af_hvsock.c | 1473 +++
 10 files changed, 1561 insertions(+), 1 deletion(-)
 create mode 100644 include/net/af_hvsock.h
 create mode 100644 net/hv_sock/Kconfig
 create mode 100644 net/hv_sock/Makefile
 create mode 100644 net/hv_sock/af_hvsock.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 44666b1..f89a4ba 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -5156,7 +5156,9 @@ F:drivers/input/serio/hyperv-keyboard.c
 F: drivers/net/hyperv/
 F: drivers/scsi/storvsc_drv.c
 F: drivers/video/fbdev/hyperv_fb.c
+F: net/hv_sock/
 F: include/linux/hyperv.h
+F: include/net/af_hvsock.h
 F: tools/hv/
 F: Documentation/ABI/stable/sysfs-bus-vmbus
 
diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
index 8e59f98..3495762 100644
--- a/include/linux/hyperv.h
+++ b/include/linux/hyperv.h
@@ -1322,4 +1322,12 @@ struct vmpipe_proto_header {
 #define HVSOCK_HEADER_LEN  (sizeof(struct vmpacket_descriptor) + \
 sizeof(struct vmpipe_proto_header))
 
+/* See 'prev_indices' in hv_ringbuffer_read(), hv_ringbuffer_write() */
+#define PREV_INDICES_LEN   (sizeof(u64))
+
+#define HVSOCK_PKT_LEN(payload_len)(HVSOCK_HEADER_LEN + \
+   ALIGN((payload_len), 8) + \
+   PREV_INDICES_LEN)
+#define HVSOCK_MIN_PKT_LEN HVSOCK_PKT_LEN(1)
+
 #endif /* _HYPERV_H */
diff --git a/include/linux/socket.h b/include/linux/socket.h
index 5bf59c8..d5ef612 100644
--- a/include/linux/socket.h
+++ b/include/linux/socket.h
@@ -200,7 +200,8 @@ struct ucred {
 #define AF_ALG 38  /* Algorithm sockets*/
 #define AF_NFC 39  /* NFC sockets  */
 #define AF_VSOCK   40  /* vSockets */
-#define AF_MAX 41  /* For now.. */
+#define AF_HYPERV  41  /* Hyper-V virtual sockets  */
+#define AF_MAX 42  /* For now.. */
 
 /* Protocol families, same as address families. */
 #define PF_UNSPEC  AF_UNSPEC
@@ -246,6 +247,7 @@ struct ucred {
 #define PF_ALG AF_ALG
 #define PF_NFC AF_NFC
 #define PF_VSOCK   AF_VSOCK
+#define PF_HYPERV  AF_HYPERV
 #define PF_MAX AF_MAX
 
 /* Maximum queue length specifiable by listen.  */
diff --git a/include/net/af_hvsock.h b/include/net/af_hvsock.h
new file mode 100644
index 000..9951658
--- /dev/null
+++ b/include/net/af_hvsock.h
@@ -0,0 +1,44 @@
+#ifndef __AF_HVSOCK_H__
+#define __AF_HVSOCK_H__
+
+#include 
+#include 
+#include 
+
+#define VMBUS_RINGBUFFER_SIZE_HVSOCK_RECV (5 * PAGE_SIZE)
+#define VMBUS_RINGBUFFER_SIZE_HVSOCK_SEND (5 * PAGE_SIZE)
+
+#define HVSOCK_RCV_BUF_SZ  VMBUS_RINGBUFFER_SIZE_HVSOCK_RECV
+#define HVSOCK_SND_BUF_SZ  PAGE_SIZE
+
+#define sk_to_hvsock(__sk)((struct hvsock_sock *)(__sk))
+#define hvsock_to_sk(__hvsk)   ((struct sock *)(__hvsk))
+
+struct hvsock_sock {
+   /* sk must be the first member. */
+   struct sock sk;
+
+   struct sockaddr_hv local_addr;
+   struct sockaddr_hv remote_addr;
+
+   /* protected by the global hvsock_mutex */
+   struct list_head bound_list;
+   struct list_head connected_list;
+
+   struct list_head accept_queue;
+   /* used by enqueue and dequeue */
+   struct mutex accept_queue_mutex;
+
+   struct delayed_work dwork;
+
+   u32 peer_shutdown;
+
+   struct vmbus_channel *channel;
+
+   char send_buf[HVSOCK_SND_BUF_SZ];
+   char recv_buf[HVSOCK_RCV_BUF_SZ];
+   unsigned int recv_data_len;
+   unsigned int recv_data_offset;
+};
+
+#endif /* __AF_HVSOCK_H__ */
diff --git a/include/uapi/linux/hyperv.h b/include/uapi/linux/hyperv.h
index e347b24..ded4c13 100644
--- a/include/uapi/linux/hyperv.h
+++ b/include/uapi/linux/hyperv.h
@@ -26,6 +26,7 @@
 #define _UAPI_HYPERV_H
 
 #include 
+#include 
 
 /*
  * Framework version for util services.
@@ -396,4 +397,19 @@ struct hv_kvp_ip_msg {
struct hv_kvp_ipaddr_value  kvp_ip_val;
 } 

[PATCH V5 5/9] Drivers: hv: vmbus: add APIs to send/recv hvsock packets

2015-12-24 Thread Dexuan Cui
This will be used by the coming net/hvsock driver.

Signed-off-by: Dexuan Cui 
---
 drivers/hv/channel.c   | 59 ++
 include/linux/hyperv.h |  9 
 2 files changed, 68 insertions(+)

diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c
index cc49966..ce1b885 100644
--- a/drivers/hv/channel.c
+++ b/drivers/hv/channel.c
@@ -924,6 +924,52 @@ int vmbus_sendpacket_multipagebuffer(struct vmbus_channel 
*channel,
 }
 EXPORT_SYMBOL_GPL(vmbus_sendpacket_multipagebuffer);
 
+/*
+ * vmbus_sendpacket_hvsock - Send the hvsock payload 'buf' of a length 'len'
+ */
+int vmbus_sendpacket_hvsock(struct vmbus_channel *channel, void *buf, u32 len)
+{
+   struct vmpipe_proto_header pipe_hdr;
+   struct vmpacket_descriptor desc;
+   struct kvec bufferlist[4];
+   u32 packetlen_aligned;
+   u32 packetlen;
+   u64 aligned_data = 0;
+   bool signal = false;
+   int ret;
+
+   packetlen = HVSOCK_HEADER_LEN + len;
+   packetlen_aligned = ALIGN(packetlen, sizeof(u64));
+
+   /* Setup the descriptor */
+   desc.type = VM_PKT_DATA_INBAND;
+   /* in 8-bytes granularity */
+   desc.offset8 = sizeof(struct vmpacket_descriptor) >> 3;
+   desc.len8 = (u16)(packetlen_aligned >> 3);
+   desc.flags = 0;
+   desc.trans_id = 0;
+
+   pipe_hdr.pkt_type = 1;
+   pipe_hdr.data_size = len;
+
+   bufferlist[0].iov_base = 
+   bufferlist[0].iov_len  = sizeof(struct vmpacket_descriptor);
+   bufferlist[1].iov_base = _hdr;
+   bufferlist[1].iov_len  = sizeof(struct vmpipe_proto_header);
+   bufferlist[2].iov_base = buf;
+   bufferlist[2].iov_len  = len;
+   bufferlist[3].iov_base = _data;
+   bufferlist[3].iov_len  = packetlen_aligned - packetlen;
+
+   ret = hv_ringbuffer_write(>outbound, bufferlist, 4, );
+
+   if (ret == 0 && signal)
+   vmbus_setevent(channel);
+
+   return ret;
+}
+EXPORT_SYMBOL_GPL(vmbus_sendpacket_hvsock);
+
 /**
  * vmbus_recvpacket() - Retrieve the user packet on the specified channel
  * @channel: Pointer to vmbus_channel structure.
@@ -976,3 +1022,16 @@ int vmbus_recvpacket_raw(struct vmbus_channel *channel, 
void *buffer,
  HV_RINGBUFFER_READ_FLAG_RAW);
 }
 EXPORT_SYMBOL_GPL(vmbus_recvpacket_raw);
+
+/*
+ * vmbus_recvpacket_hvsock - Receive the hvsock payload from the vmbus
+ * ringbuffer into the 'buffer'.
+ */
+int vmbus_recvpacket_hvsock(struct vmbus_channel *channel, void *buffer,
+   u32 bufferlen, u32 *buffer_actual_len)
+{
+   return __vmbus_recvpacket(channel, buffer, bufferlen,
+ buffer_actual_len, NULL,
+ HV_RINGBUFFER_READ_FLAG_HVSOCK);
+}
+EXPORT_SYMBOL_GPL(vmbus_recvpacket_hvsock);
diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
index e005223..646c20d 100644
--- a/include/linux/hyperv.h
+++ b/include/linux/hyperv.h
@@ -908,6 +908,9 @@ extern int vmbus_sendpacket_ctl(struct vmbus_channel 
*channel,
  u32 flags,
  bool kick_q);
 
+extern int vmbus_sendpacket_hvsock(struct vmbus_channel *channel,
+  void *buf, u32 len);
+
 extern int vmbus_sendpacket_pagebuffer(struct vmbus_channel *channel,
struct hv_page_buffer pagebuffers[],
u32 pagecount,
@@ -958,6 +961,9 @@ extern int vmbus_recvpacket_raw(struct vmbus_channel 
*channel,
 u64 *requestid);
 
 
+extern int vmbus_recvpacket_hvsock(struct vmbus_channel *channel, void *buffer,
+  u32 bufferlen, u32 *buffer_actual_len);
+
 extern void vmbus_ontimer(unsigned long data);
 
 /* Base driver object */
@@ -1280,4 +1286,7 @@ struct vmpipe_proto_header {
};
 } __packed;
 
+#define HVSOCK_HEADER_LEN  (sizeof(struct vmpacket_descriptor) + \
+sizeof(struct vmpipe_proto_header))
+
 #endif /* _HYPERV_H */
-- 
2.1.4

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH V5 2/9] Drivers: hv: vmbus: define the new offer type for Hyper-V socket (hvsock)

2015-12-24 Thread Dexuan Cui
A helper function is also added.

Signed-off-by: Dexuan Cui 
---
 include/linux/hyperv.h | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
index e4867a7..c0eddd7 100644
--- a/include/linux/hyperv.h
+++ b/include/linux/hyperv.h
@@ -235,6 +235,7 @@ struct vmbus_channel_offer {
 #define VMBUS_CHANNEL_LOOPBACK_OFFER   0x100
 #define VMBUS_CHANNEL_PARENT_OFFER 0x200
 #define VMBUS_CHANNEL_REQUEST_MONITORED_NOTIFICATION   0x400
+#define VMBUS_CHANNEL_TLNPI_PROVIDER_OFFER 0x2000
 
 struct vmpacket_descriptor {
u16 type;
@@ -769,6 +770,12 @@ struct vmbus_channel {
enum hv_signal_policy  signal_policy;
 };
 
+static inline bool is_hvsock_channel(const struct vmbus_channel *c)
+{
+   return !!(c->offermsg.offer.chn_flags &
+ VMBUS_CHANNEL_TLNPI_PROVIDER_OFFER);
+}
+
 static inline void set_channel_signal_state(struct vmbus_channel *c,
enum hv_signal_policy policy)
 {
-- 
2.1.4

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH V5 6/9] Drivers: hv: vmbus: add a hvsock flag in struct hv_driver

2015-12-24 Thread Dexuan Cui
Only the coming hv_sock driver has a "true" value for this flag.

We treat the hvsock offers/channels as special VMBus devices.
Since the hv_sock driver handles all the hvsock offers/channels, we need to
tweak vmbus_match() for hv_sock driver, so we introduce this flag.

Signed-off-by: Dexuan Cui 
---
 drivers/hv/vmbus_drv.c |  4 
 include/linux/hyperv.h | 14 ++
 2 files changed, 18 insertions(+)

diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
index 328e4c3..c1c9d71 100644
--- a/drivers/hv/vmbus_drv.c
+++ b/drivers/hv/vmbus_drv.c
@@ -562,6 +562,10 @@ static int vmbus_match(struct device *device, struct 
device_driver *driver)
struct hv_driver *drv = drv_to_hv_drv(driver);
struct hv_device *hv_dev = device_to_hv_device(device);
 
+   /* The hv_sock driver handles all hv_sock offers. */
+   if (is_hvsock_channel(hv_dev->channel))
+   return drv->hvsock;
+
if (hv_vmbus_get_id(drv->id_table, _dev->dev_type))
return 1;
 
diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
index 646c20d..b4cc44c 100644
--- a/include/linux/hyperv.h
+++ b/include/linux/hyperv.h
@@ -970,6 +970,20 @@ extern void vmbus_ontimer(unsigned long data);
 struct hv_driver {
const char *name;
 
+   /*
+* A hvsock offer, which has a VMBUS_CHANNEL_TLNPI_PROVIDER_OFFER
+* channel flag, actually doesn't mean a synthetic device because the
+* offer's if_type/if_instance can change for every new hvsock
+* connection.
+*
+* However, to facilitate the notification of new-offer/rescind-offer
+* from vmbus driver to hvsock driver, we can handle hvsock offer as
+* a special vmbus device, and hence we need the below flag to
+* indicate if the driver is the hvsock driver or not: we need to
+* specially treat the hvosck offer & driver in vmbus_match().
+*/
+   bool hvsock;
+
/* the device type supported by this driver */
uuid_le dev_type;
const struct hv_vmbus_device_id *id_table;
-- 
2.1.4

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH V5 3/9] Drivers: hv: vmbus: define a new VMBus message type for hvsock

2015-12-24 Thread Dexuan Cui
A function to send the type of message is also added.

The coming net/hvsock driver will use this function to proactively request
the host to offer a VMBus channel for a new hvsock connection.

Signed-off-by: Dexuan Cui 
---
 drivers/hv/channel.c  | 15 +++
 drivers/hv/channel_mgmt.c |  4 
 include/linux/hyperv.h| 13 +
 3 files changed, 32 insertions(+)

diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c
index 1161d68..eaaa066 100644
--- a/drivers/hv/channel.c
+++ b/drivers/hv/channel.c
@@ -219,6 +219,21 @@ error0:
 }
 EXPORT_SYMBOL_GPL(vmbus_open);
 
+/* Used for Hyper-V Socket: a guest client's connect() to the host */
+int vmbus_send_tl_connect_request(const uuid_le *shv_guest_servie_id,
+ const uuid_le *shv_host_servie_id)
+{
+   struct vmbus_channel_tl_connect_request conn_msg;
+
+   memset(_msg, 0, sizeof(conn_msg));
+   conn_msg.header.msgtype = CHANNELMSG_TL_CONNECT_REQUEST;
+   conn_msg.guest_endpoint_id = *shv_guest_servie_id;
+   conn_msg.host_service_id = *shv_host_servie_id;
+
+   return vmbus_post_msg(_msg, sizeof(conn_msg));
+}
+EXPORT_SYMBOL_GPL(vmbus_send_tl_connect_request);
+
 /*
  * create_gpadl_header - Creates a gpadl for the specified buffer
  */
diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c
index 1c1ad47..4611b50 100644
--- a/drivers/hv/channel_mgmt.c
+++ b/drivers/hv/channel_mgmt.c
@@ -825,6 +825,10 @@ struct vmbus_channel_message_table_entry
{CHANNELMSG_VERSION_RESPONSE,   1, vmbus_onversion_response},
{CHANNELMSG_UNLOAD, 0, NULL},
{CHANNELMSG_UNLOAD_RESPONSE,1, vmbus_unload_response},
+   {CHANNELMSG_18, 0, NULL},
+   {CHANNELMSG_19, 0, NULL},
+   {CHANNELMSG_20, 0, NULL},
+   {CHANNELMSG_TL_CONNECT_REQUEST, 0, NULL},
 };
 
 /*
diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
index c0eddd7..b835d80 100644
--- a/include/linux/hyperv.h
+++ b/include/linux/hyperv.h
@@ -392,6 +392,10 @@ enum vmbus_channel_message_type {
CHANNELMSG_VERSION_RESPONSE = 15,
CHANNELMSG_UNLOAD   = 16,
CHANNELMSG_UNLOAD_RESPONSE  = 17,
+   CHANNELMSG_18   = 18,
+   CHANNELMSG_19   = 19,
+   CHANNELMSG_20   = 20,
+   CHANNELMSG_TL_CONNECT_REQUEST   = 21,
CHANNELMSG_COUNT
 };
 
@@ -562,6 +566,13 @@ struct vmbus_channel_initiate_contact {
u64 monitor_page2;
 } __packed;
 
+/* Hyper-V socket: guest's connect()-ing to host */
+struct vmbus_channel_tl_connect_request {
+   struct vmbus_channel_message_header header;
+   uuid_le guest_endpoint_id;
+   uuid_le host_service_id;
+} __packed;
+
 struct vmbus_channel_version_response {
struct vmbus_channel_message_header header;
u8 version_supported;
@@ -1255,4 +1266,6 @@ void hv_process_channel_removal(struct vmbus_channel 
*channel, u32 relid);
 
 extern __u32 vmbus_proto_version;
 
+int vmbus_send_tl_connect_request(const uuid_le *shv_guest_servie_id,
+ const uuid_le *shv_host_servie_id);
 #endif /* _HYPERV_H */
-- 
2.1.4

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel