Merge pull request #2318 from rn/kern-up

Update kernel to 4.9.40/4.4.79, remove 4.11.x
This commit is contained in:
Rolf Neugebauer
2017-07-28 22:28:10 +01:00
committed by GitHub
539 changed files with 257 additions and 16706 deletions

View File

@@ -1,6 +1,6 @@
# This is a blueprint for building the open source components of Docker for Mac
kernel:
image: linuxkit/kernel:4.9.39
image: linuxkit/kernel:4.9.40
cmdline: "console=ttyS0 page_poison=1"
init:
- linuxkit/vpnkit-expose-port:e2b49a6c56fbf876ea24f0a5ce4ccae5f940d1be # install vpnkit-expose-port and vpnkit-iptables-wrapper on host

View File

@@ -1,5 +1,5 @@
kernel:
image: linuxkit/kernel:4.9.39
image: linuxkit/kernel:4.9.40
cmdline: "console=ttyS0"
init:
- linuxkit/init:4dcee04c04c900a5796dc719f8d16fea7e771059

View File

@@ -1,5 +1,5 @@
kernel:
image: linuxkit/kernel:4.9.39
image: linuxkit/kernel:4.9.40
cmdline: "console=ttyS0"
init:
- linuxkit/init:4dcee04c04c900a5796dc719f8d16fea7e771059

View File

@@ -1,5 +1,5 @@
kernel:
image: linuxkit/kernel:4.9.39
image: linuxkit/kernel:4.9.40
cmdline: "console=tty0 console=ttyS0"
init:
- linuxkit/init:4dcee04c04c900a5796dc719f8d16fea7e771059

View File

@@ -1,5 +1,5 @@
kernel:
image: linuxkit/kernel:4.9.39
image: linuxkit/kernel:4.9.40
cmdline: "console=ttyS0"
init:
- linuxkit/init:4dcee04c04c900a5796dc719f8d16fea7e771059

View File

@@ -1,5 +1,5 @@
kernel:
image: linuxkit/kernel:4.9.39
image: linuxkit/kernel:4.9.40
cmdline: "console=tty0 console=ttyS0"
init:
- linuxkit/init:4dcee04c04c900a5796dc719f8d16fea7e771059

View File

@@ -1,5 +1,5 @@
kernel:
image: linuxkit/kernel:4.9.39
image: linuxkit/kernel:4.9.40
cmdline: "console=tty0 console=ttyS0"
init:
- linuxkit/init:4dcee04c04c900a5796dc719f8d16fea7e771059

View File

@@ -1,5 +1,5 @@
kernel:
image: linuxkit/kernel:4.9.39
image: linuxkit/kernel:4.9.40
cmdline: "console=tty0 console=ttyS0"
init:
- linuxkit/init:4dcee04c04c900a5796dc719f8d16fea7e771059

View File

@@ -1,5 +1,5 @@
kernel:
image: linuxkit/kernel:4.9.39
image: linuxkit/kernel:4.9.40
cmdline: "console=ttyS1"
init:
- linuxkit/init:4dcee04c04c900a5796dc719f8d16fea7e771059

View File

@@ -1,7 +1,7 @@
# Minimal YAML to run a redis server (used at DockerCon'17)
# connect: nc localhost 6379
kernel:
image: linuxkit/kernel:4.9.39
image: linuxkit/kernel:4.9.40
cmdline: "console=tty0 console=ttyS0"
init:
- linuxkit/init:4dcee04c04c900a5796dc719f8d16fea7e771059

View File

@@ -1,5 +1,5 @@
kernel:
image: linuxkit/kernel:4.9.39
image: linuxkit/kernel:4.9.40
cmdline: "console=tty0 console=ttyS0"
init:
- linuxkit/init:4dcee04c04c900a5796dc719f8d16fea7e771059

View File

@@ -1,5 +1,5 @@
kernel:
image: linuxkit/kernel:4.9.39
image: linuxkit/kernel:4.9.40
cmdline: "console=tty0 console=ttyS0"
init:
- linuxkit/init:4dcee04c04c900a5796dc719f8d16fea7e771059

View File

@@ -1,5 +1,5 @@
kernel:
image: linuxkit/kernel:4.9.39
image: linuxkit/kernel:4.9.40
cmdline: "console=tty0"
init:
- linuxkit/init:4dcee04c04c900a5796dc719f8d16fea7e771059

View File

@@ -1,5 +1,5 @@
kernel:
image: linuxkit/kernel:4.9.39
image: linuxkit/kernel:4.9.40
cmdline: "console=ttyS0"
init:
- linuxkit/init:4dcee04c04c900a5796dc719f8d16fea7e771059

View File

@@ -1,5 +1,5 @@
kernel:
image: linuxkit/kernel:4.9.39
image: linuxkit/kernel:4.9.40
cmdline: "console=ttyS0"
init:
- linuxkit/init:4dcee04c04c900a5796dc719f8d16fea7e771059

View File

@@ -1,5 +1,5 @@
kernel:
image: linuxkit/kernel:4.9.39
image: linuxkit/kernel:4.9.40
cmdline: "console=ttyS0"
init:
- linuxkit/init:4dcee04c04c900a5796dc719f8d16fea7e771059

View File

@@ -104,8 +104,6 @@ endef
# Build Targets
# Debug targets only for latest stable and LTS stable
#
$(eval $(call kernel,4.11.12,4.11.x))
$(eval $(call kernel,4.11.12,4.11.x,_dbg))
$(eval $(call kernel,4.9.39,4.9.x))
$(eval $(call kernel,4.9.39,4.9.x,_dbg))
$(eval $(call kernel,4.4.78,4.4.x))
$(eval $(call kernel,4.9.40,4.9.x))
$(eval $(call kernel,4.9.40,4.9.x,_dbg))
$(eval $(call kernel,4.4.79,4.4.x))

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
#
# Automatically generated file; DO NOT EDIT.
# Linux/x86 4.4.78 Kernel Configuration
# Linux/x86 4.4.79 Kernel Configuration
#
CONFIG_64BIT=y
CONFIG_X86_64=y

View File

@@ -1,6 +1,6 @@
#
# Automatically generated file; DO NOT EDIT.
# Linux/x86 4.9.39 Kernel Configuration
# Linux/x86 4.9.40 Kernel Configuration
#
CONFIG_64BIT=y
CONFIG_X86_64=y

View File

@@ -1,149 +0,0 @@
From bb12a92eb84f7303cdf1be8133e59c1ebf50a62b Mon Sep 17 00:00:00 2001
From: Arnaldo Carvalho de Melo <acme@redhat.com>
Date: Thu, 2 Mar 2017 12:55:49 -0300
Subject: [PATCH 01/20] tools build: Add test for sched_getcpu()
Instead of trying to go on adding more ifdef conditions, do a feature
test and define HAVE_SCHED_GETCPU_SUPPORT instead, then use it to
provide the prototype. No need to change the stub, as it is already a
__weak symbol.
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Wang Nan <wangnan0@huawei.com>
Link: http://lkml.kernel.org/n/tip-yge89er9g90sc0v6k0a0r5tr@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
(cherry picked from commit 120010cb1eea151d38a3e66f5ffc79a0c3110292)
---
tools/build/Makefile.feature | 1 +
tools/build/feature/Makefile | 6 +++++-
tools/build/feature/test-all.c | 5 +++++
tools/build/feature/test-sched_getcpu.c | 7 +++++++
tools/perf/Makefile.config | 4 ++++
tools/perf/util/cloexec.h | 6 ------
tools/perf/util/util.h | 4 ++--
7 files changed, 24 insertions(+), 9 deletions(-)
create mode 100644 tools/build/feature/test-sched_getcpu.c
diff --git a/tools/build/Makefile.feature b/tools/build/Makefile.feature
index e3fb5ecbdcb6..523911f316ce 100644
--- a/tools/build/Makefile.feature
+++ b/tools/build/Makefile.feature
@@ -63,6 +63,7 @@ FEATURE_TESTS_BASIC := \
lzma \
get_cpuid \
bpf \
+ sched_getcpu \
sdt
# FEATURE_TESTS_BASIC + FEATURE_TESTS_EXTRA is the complete list
diff --git a/tools/build/feature/Makefile b/tools/build/feature/Makefile
index b564a2eea039..ab1e2bbc2e96 100644
--- a/tools/build/feature/Makefile
+++ b/tools/build/feature/Makefile
@@ -48,7 +48,8 @@ FILES= \
test-get_cpuid.bin \
test-sdt.bin \
test-cxx.bin \
- test-jvmti.bin
+ test-jvmti.bin \
+ test-sched_getcpu.bin
FILES := $(addprefix $(OUTPUT),$(FILES))
@@ -91,6 +92,9 @@ $(OUTPUT)test-libelf.bin:
$(OUTPUT)test-glibc.bin:
$(BUILD)
+$(OUTPUT)test-sched_getcpu.bin:
+ $(BUILD)
+
DWARFLIBS := -ldw
ifeq ($(findstring -static,${LDFLAGS}),-static)
DWARFLIBS += -lelf -lebl -lz -llzma -lbz2
diff --git a/tools/build/feature/test-all.c b/tools/build/feature/test-all.c
index 699e43627397..cc6c7c01f4ca 100644
--- a/tools/build/feature/test-all.c
+++ b/tools/build/feature/test-all.c
@@ -117,6 +117,10 @@
# include "test-pthread-attr-setaffinity-np.c"
#undef main
+#define main main_test_sched_getcpu
+# include "test-sched_getcpu.c"
+#undef main
+
# if 0
/*
* Disable libbabeltrace check for test-all, because the requested
@@ -182,6 +186,7 @@ int main(int argc, char *argv[])
main_test_get_cpuid();
main_test_bpf();
main_test_libcrypto();
+ main_test_sched_getcpu();
main_test_sdt();
return 0;
diff --git a/tools/build/feature/test-sched_getcpu.c b/tools/build/feature/test-sched_getcpu.c
new file mode 100644
index 000000000000..c4a148dd7104
--- /dev/null
+++ b/tools/build/feature/test-sched_getcpu.c
@@ -0,0 +1,7 @@
+#define _GNU_SOURCE
+#include <sched.h>
+
+int main(void)
+{
+ return sched_getcpu();
+}
diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config
index 27c9fbca7bd9..2b656de99495 100644
--- a/tools/perf/Makefile.config
+++ b/tools/perf/Makefile.config
@@ -317,6 +317,10 @@ ifdef NO_DWARF
NO_LIBDW_DWARF_UNWIND := 1
endif
+ifeq ($(feature-sched_getcpu), 1)
+ CFLAGS += -DHAVE_SCHED_GETCPU_SUPPORT
+endif
+
ifndef NO_LIBELF
CFLAGS += -DHAVE_LIBELF_SUPPORT
EXTLIBS += -lelf
diff --git a/tools/perf/util/cloexec.h b/tools/perf/util/cloexec.h
index d0d465953d36..94a5a7d829d5 100644
--- a/tools/perf/util/cloexec.h
+++ b/tools/perf/util/cloexec.h
@@ -3,10 +3,4 @@
unsigned long perf_event_open_cloexec_flag(void);
-#ifdef __GLIBC_PREREQ
-#if !__GLIBC_PREREQ(2, 6) && !defined(__UCLIBC__)
-int sched_getcpu(void) __THROW;
-#endif
-#endif
-
#endif /* __PERF_CLOEXEC_H */
diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h
index c74708da8571..b2cfa47990dc 100644
--- a/tools/perf/util/util.h
+++ b/tools/perf/util/util.h
@@ -355,8 +355,8 @@ void print_binary(unsigned char *data, size_t len,
size_t bytes_per_line, print_binary_t printer,
void *extra);
-#if !defined(__GLIBC__) && !defined(__ANDROID__)
-extern int sched_getcpu(void);
+#ifndef HAVE_SCHED_GETCPU_SUPPORT
+int sched_getcpu(void);
#endif
int is_printable_array(char *p, unsigned int len);
--
2.13.0

View File

@@ -1,34 +0,0 @@
From 3bd49e1e1ef7d5ae237d05a4f2198097c659f15d Mon Sep 17 00:00:00 2001
From: Dexuan Cui <decui@microsoft.com>
Date: Fri, 5 May 2017 16:57:12 -0600
Subject: [PATCH 02/20] vmbus: vmbus_open(): reset onchannel_callback on error
No real issue is observed without the patch, but let's add this
just in case.
Signed-off-by: Dexuan Cui <decui@microsoft.com>
Cc: K. Y. Srinivasan <kys@microsoft.com>
Cc: Haiyang Zhang <haiyangz@microsoft.com>
Cc: Stephen Hemminger <sthemmin@microsoft.com>
Origin: git@github.com:dcui/linux.git
(cherry picked from commit c248b14174e1337c1461f9b13a573ad90a136e1c)
---
drivers/hv/channel.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c
index 321b8833fa6f..628d6fde1887 100644
--- a/drivers/hv/channel.c
+++ b/drivers/hv/channel.c
@@ -220,6 +220,8 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size,
get_order(send_ringbuffer_size + recv_ringbuffer_size));
error_set_chnstate:
newchannel->state = CHANNEL_OPEN_STATE;
+ newchannel->onchannel_callback = NULL;
+ newchannel->channel_callback_context = NULL;
return err;
}
EXPORT_SYMBOL_GPL(vmbus_open);
--
2.13.0

View File

@@ -1,42 +0,0 @@
From 9a9a825baa57486c33d37425ee432e9b0c292b18 Mon Sep 17 00:00:00 2001
From: Dexuan Cui <decui@microsoft.com>
Date: Fri, 5 May 2017 16:57:15 -0600
Subject: [PATCH 03/20] vmbus: add the matching tasklet_enable() in
vmbus_close_internal()
If we disable a tasklet that is scheduled but hasn't started to run,
the tasklet has no chance to run any longer, so later we'll hang
in free_channel() -> tasklet_kill(), because the TASKLET_STATE_SCHED
can't be cleared in tasklet_action().
With the patch, before free_channel() -> tasklet_kill() returns, the
tasklet still has a chance to run with a NULL channel->onchannel_callback,
which will be ignored safely, e.g. by vmbus_on_event().
Fixes: dad72a1d2844 ("vmbus: remove hv_event_tasklet_disable/enable")
Signed-off-by: Dexuan Cui <decui@microsoft.com>
Cc: K. Y. Srinivasan <kys@microsoft.com>
Cc: Haiyang Zhang <haiyangz@microsoft.com>
Cc: Stephen Hemminger <sthemmin@microsoft.com>
Origin: git@github.com:dcui/linux.git
(cherry picked from commit 008d8d8bc0c86473a8549a365bee9a479243e412)
---
drivers/hv/channel.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c
index 628d6fde1887..7cd2bd9fd1f1 100644
--- a/drivers/hv/channel.c
+++ b/drivers/hv/channel.c
@@ -608,6 +608,7 @@ static int vmbus_close_internal(struct vmbus_channel *channel)
get_order(channel->ringbuffer_pagecount * PAGE_SIZE));
out:
+ tasklet_enable(&channel->callback_event);
return ret;
}
--
2.13.0

View File

@@ -1,63 +0,0 @@
From 6a5bc0225d5d1ba564aa1071bfd67ad3ce3799ad Mon Sep 17 00:00:00 2001
From: Dexuan Cui <decui@microsoft.com>
Date: Fri, 5 May 2017 16:57:20 -0600
Subject: [PATCH 04/20] vmbus: remove "goto error_clean_msglist" in
vmbus_open()
This is just a cleanup patch to simplify the code a little.
No semantic change.
Signed-off-by: Dexuan Cui <decui@microsoft.com>
Cc: K. Y. Srinivasan <kys@microsoft.com>
Cc: Haiyang Zhang <haiyangz@microsoft.com>
Cc: Stephen Hemminger <sthemmin@microsoft.com>
Origin: git@github.com:dcui/linux.git
(cherry picked from commit 4713066c11b2396eafd2873cbed7bdd72d1571eb)
---
drivers/hv/channel.c | 18 +++++++-----------
1 file changed, 7 insertions(+), 11 deletions(-)
diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c
index 7cd2bd9fd1f1..db5e6f8730d2 100644
--- a/drivers/hv/channel.c
+++ b/drivers/hv/channel.c
@@ -180,17 +180,18 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size,
ret = vmbus_post_msg(open_msg,
sizeof(struct vmbus_channel_open_channel), true);
- if (ret != 0) {
- err = ret;
- goto error_clean_msglist;
- }
-
- wait_for_completion(&open_info->waitevent);
+ if (ret == 0)
+ wait_for_completion(&open_info->waitevent);
spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags);
list_del(&open_info->msglistentry);
spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags);
+ if (ret != 0) {
+ err = ret;
+ goto error_free_gpadl;
+ }
+
if (newchannel->rescind) {
err = -ENODEV;
goto error_free_gpadl;
@@ -205,11 +206,6 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size,
kfree(open_info);
return 0;
-error_clean_msglist:
- spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags);
- list_del(&open_info->msglistentry);
- spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags);
-
error_free_gpadl:
vmbus_teardown_gpadl(newchannel, newchannel->ringbuffer_gpadlhandle);
kfree(open_info);
--
2.13.0

View File

@@ -1,189 +0,0 @@
From a585c8504fefc755a5f482e613fb81217bff35e0 Mon Sep 17 00:00:00 2001
From: Dexuan Cui <decui@microsoft.com>
Date: Fri, 5 May 2017 16:57:23 -0600
Subject: [PATCH 05/20] vmbus: dynamically enqueue/dequeue a channel on
vmbus_open/close
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
A just-closed channel may have a pending interrupt, and later when a new
channel with the same channel ID is not being fully initialized, the
pending interrupt of the previous channel with the same channel ID can run
the channel callback on the new channel data structure, causing a crash
of NULL pointer dereferencing.
Normally its pretty hard to reproduce the race condition, but it can
indeed happen with specially-designed hv_sock stress test cases.
Signed-off-by: Dexuan Cui <decui@microsoft.com>
Reported-by: Rolf Neugebauer <rolf.neugebauer@docker.com>
Tested-by: Rolf Neugebauer <rolf.neugebauer@docker.com>
Cc: K. Y. Srinivasan <kys@microsoft.com>
Cc: Haiyang Zhang <haiyangz@microsoft.com>
Cc: Stephen Hemminger <sthemmin@microsoft.com>
Origin: git@github.com:dcui/linux.git
(cherry picked from commit 1df677b35ff010d0def33f5420773015815cf843)
---
drivers/hv/channel.c | 12 +++++++++---
drivers/hv/channel_mgmt.c | 50 +++++++++++++++++++++--------------------------
include/linux/hyperv.h | 3 +++
3 files changed, 34 insertions(+), 31 deletions(-)
diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c
index db5e6f8730d2..f288e506fba0 100644
--- a/drivers/hv/channel.c
+++ b/drivers/hv/channel.c
@@ -177,6 +177,8 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size,
&vmbus_connection.chn_msg_list);
spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags);
+ hv_percpu_channel_enq(newchannel);
+
ret = vmbus_post_msg(open_msg,
sizeof(struct vmbus_channel_open_channel), true);
@@ -189,23 +191,25 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size,
if (ret != 0) {
err = ret;
- goto error_free_gpadl;
+ goto error_deq_channel;
}
if (newchannel->rescind) {
err = -ENODEV;
- goto error_free_gpadl;
+ goto error_deq_channel;
}
if (open_info->response.open_result.status) {
err = -EAGAIN;
- goto error_free_gpadl;
+ goto error_deq_channel;
}
newchannel->state = CHANNEL_OPENED_STATE;
kfree(open_info);
return 0;
+error_deq_channel:
+ hv_percpu_channel_deq(newchannel);
error_free_gpadl:
vmbus_teardown_gpadl(newchannel, newchannel->ringbuffer_gpadlhandle);
kfree(open_info);
@@ -551,6 +555,8 @@ static int vmbus_close_internal(struct vmbus_channel *channel)
goto out;
}
+ hv_percpu_channel_deq(channel);
+
channel->state = CHANNEL_OPEN_STATE;
channel->sc_creation_callback = NULL;
/* Stop callback and cancel the timer asap */
diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c
index fbcb06352308..c5a01a4d589e 100644
--- a/drivers/hv/channel_mgmt.c
+++ b/drivers/hv/channel_mgmt.c
@@ -363,6 +363,17 @@ static void percpu_channel_enq(void *arg)
list_add_tail_rcu(&channel->percpu_list, &hv_cpu->chan_list);
}
+void hv_percpu_channel_enq(struct vmbus_channel *channel)
+{
+ if (channel->target_cpu != get_cpu())
+ smp_call_function_single(channel->target_cpu,
+ percpu_channel_enq, channel, true);
+ else
+ percpu_channel_enq(channel);
+
+ put_cpu();
+}
+
static void percpu_channel_deq(void *arg)
{
struct vmbus_channel *channel = arg;
@@ -370,6 +381,17 @@ static void percpu_channel_deq(void *arg)
list_del_rcu(&channel->percpu_list);
}
+void hv_percpu_channel_deq(struct vmbus_channel *channel)
+{
+ if (channel->target_cpu != get_cpu())
+ smp_call_function_single(channel->target_cpu,
+ percpu_channel_deq, channel, true);
+ else
+ percpu_channel_deq(channel);
+
+ put_cpu();
+}
+
static void vmbus_release_relid(u32 relid)
{
@@ -390,15 +412,6 @@ void hv_process_channel_removal(struct vmbus_channel *channel, u32 relid)
BUG_ON(!channel->rescind);
BUG_ON(!mutex_is_locked(&vmbus_connection.channel_mutex));
- if (channel->target_cpu != get_cpu()) {
- put_cpu();
- smp_call_function_single(channel->target_cpu,
- percpu_channel_deq, channel, true);
- } else {
- percpu_channel_deq(channel);
- put_cpu();
- }
-
if (channel->primary_channel == NULL) {
list_del(&channel->listentry);
@@ -491,16 +504,6 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel)
init_vp_index(newchannel, dev_type);
- if (newchannel->target_cpu != get_cpu()) {
- put_cpu();
- smp_call_function_single(newchannel->target_cpu,
- percpu_channel_enq,
- newchannel, true);
- } else {
- percpu_channel_enq(newchannel);
- put_cpu();
- }
-
/*
* This state is used to indicate a successful open
* so that when we do close the channel normally, we
@@ -549,15 +552,6 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel)
list_del(&newchannel->listentry);
mutex_unlock(&vmbus_connection.channel_mutex);
- if (newchannel->target_cpu != get_cpu()) {
- put_cpu();
- smp_call_function_single(newchannel->target_cpu,
- percpu_channel_deq, newchannel, true);
- } else {
- percpu_channel_deq(newchannel);
- put_cpu();
- }
-
vmbus_release_relid(newchannel->offermsg.child_relid);
err_free_chan:
diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
index 970771a5f739..a8bae2caa69f 100644
--- a/include/linux/hyperv.h
+++ b/include/linux/hyperv.h
@@ -1437,6 +1437,9 @@ extern bool vmbus_prep_negotiate_resp(struct icmsg_hdr *icmsghdrp, u8 *buf,
const int *srv_version, int srv_vercnt,
int *nego_fw_version, int *nego_srv_version);
+void hv_percpu_channel_enq(struct vmbus_channel *channel);
+void hv_percpu_channel_deq(struct vmbus_channel *channel);
+
void hv_process_channel_removal(struct vmbus_channel *channel, u32 relid);
void vmbus_setevent(struct vmbus_channel *channel);
--
2.13.0

View File

@@ -1,934 +0,0 @@
From d4e96f82cbb40cde3ee6918f1e228ad1454b7757 Mon Sep 17 00:00:00 2001
From: Dexuan Cui <decui@microsoft.com>
Date: Fri, 5 May 2017 16:57:26 -0600
Subject: [PATCH 06/20] hv_sock: implements Hyper-V transport for Virtual
Sockets (AF_VSOCK)
Hyper-V Sockets (hv_sock) supplies a byte-stream based communication
mechanism between the host and the guest. It uses VMBus ringbuffer as the
transportation layer.
With hv_sock, applications between the host (Windows 10, Windows Server
2016 or newer) and the guest can talk with each other using the traditional
socket APIs.
More info about Hyper-V Sockets is available here:
"Make your own integration services":
https://docs.microsoft.com/en-us/virtualization/hyper-v-on-windows/user-guide/make-integration-service
The patch implements the necessary support in Linux guest by introducing a new
vsock transport for AF_VSOCK.
Signed-off-by: Dexuan Cui <decui@microsoft.com>
Cc: K. Y. Srinivasan <kys@microsoft.com>
Cc: Haiyang Zhang <haiyangz@microsoft.com>
Cc: Stephen Hemminger <sthemmin@microsoft.com>
Cc: Andy King <acking@vmware.com>
Cc: Dmitry Torokhov <dtor@vmware.com>
Cc: George Zhang <georgezhang@vmware.com>
Cc: Jorgen Hansen <jhansen@vmware.com>
Cc: Reilly Grant <grantr@vmware.com>
Cc: Asias He <asias@redhat.com>
Cc: Stefan Hajnoczi <stefanha@redhat.com>
Cc: Vitaly Kuznetsov <vkuznets@redhat.com>
Cc: Cathy Avery <cavery@redhat.com>
Cc: Rolf Neugebauer <rolf.neugebauer@docker.com>
Origin: git@github.com:dcui/linux.git
(cherry picked from commit 3476be340d2ff777609fca3e763da0292acbfc45)
---
MAINTAINERS | 1 +
net/vmw_vsock/Kconfig | 12 +
net/vmw_vsock/Makefile | 3 +
net/vmw_vsock/hyperv_transport.c | 829 +++++++++++++++++++++++++++++++++++++++
4 files changed, 845 insertions(+)
create mode 100644 net/vmw_vsock/hyperv_transport.c
diff --git a/MAINTAINERS b/MAINTAINERS
index 38d3e4ed7208..53bf52ce3173 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -6077,6 +6077,7 @@ F: drivers/net/hyperv/
F: drivers/scsi/storvsc_drv.c
F: drivers/uio/uio_hv_generic.c
F: drivers/video/fbdev/hyperv_fb.c
+F: net/vmw_vsock/hyperv_transport.c
F: include/linux/hyperv.h
F: tools/hv/
F: Documentation/ABI/stable/sysfs-bus-vmbus
diff --git a/net/vmw_vsock/Kconfig b/net/vmw_vsock/Kconfig
index 8831e7c42167..a24369d175fd 100644
--- a/net/vmw_vsock/Kconfig
+++ b/net/vmw_vsock/Kconfig
@@ -46,3 +46,15 @@ config VIRTIO_VSOCKETS_COMMON
This option is selected by any driver which needs to access
the virtio_vsock. The module will be called
vmw_vsock_virtio_transport_common.
+
+config HYPERV_VSOCKETS
+ tristate "Hyper-V transport for Virtual Sockets"
+ depends on VSOCKETS && HYPERV
+ help
+ This module implements a Hyper-V transport for Virtual Sockets.
+
+ Enable this transport if your Virtual Machine host supports Virtual
+ Sockets over Hyper-V VMBus.
+
+ To compile this driver as a module, choose M here: the module will be
+ called hv_sock. If unsure, say N.
diff --git a/net/vmw_vsock/Makefile b/net/vmw_vsock/Makefile
index bc27c70e0e59..f70f3e70ce9e 100644
--- a/net/vmw_vsock/Makefile
+++ b/net/vmw_vsock/Makefile
@@ -2,6 +2,7 @@ obj-$(CONFIG_VSOCKETS) += vsock.o
obj-$(CONFIG_VMWARE_VMCI_VSOCKETS) += vmw_vsock_vmci_transport.o
obj-$(CONFIG_VIRTIO_VSOCKETS) += vmw_vsock_virtio_transport.o
obj-$(CONFIG_VIRTIO_VSOCKETS_COMMON) += vmw_vsock_virtio_transport_common.o
+obj-$(CONFIG_HYPERV_VSOCKETS) += hv_sock.o
vsock-y += af_vsock.o vsock_addr.o
@@ -11,3 +12,5 @@ vmw_vsock_vmci_transport-y += vmci_transport.o vmci_transport_notify.o \
vmw_vsock_virtio_transport-y += virtio_transport.o
vmw_vsock_virtio_transport_common-y += virtio_transport_common.o
+
+hv_sock-y += hyperv_transport.o
diff --git a/net/vmw_vsock/hyperv_transport.c b/net/vmw_vsock/hyperv_transport.c
new file mode 100644
index 000000000000..fd89bf357617
--- /dev/null
+++ b/net/vmw_vsock/hyperv_transport.c
@@ -0,0 +1,829 @@
+/*
+ * Hyper-V transport for vsock
+ *
+ * Hyper-V Sockets supplies a byte-stream based communication mechanism
+ * between the host and the VM. This driver implements the necessary
+ * support in the VM by introducing the new vsock transport.
+ *
+ * Copyright (c) 2017, Microsoft Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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/module.h>
+#include <linux/vmalloc.h>
+#include <linux/hyperv.h>
+#include <net/sock.h>
+#include <net/af_vsock.h>
+
+/* The host side's design of the feature requires 6 exact 4KB pages for
+ * recv/send rings respectively -- this is suboptimal considering memory
+ * consumption, however unluckily we have to live with it, before the
+ * host comes up with a better design in the future.
+ */
+#define PAGE_SIZE_4K 4096
+#define RINGBUFFER_HVS_RCV_SIZE (PAGE_SIZE_4K * 6)
+#define RINGBUFFER_HVS_SND_SIZE (PAGE_SIZE_4K * 6)
+
+/* The MTU is 16KB per the host side's design */
+#define HVS_MTU_SIZE (1024 * 16)
+
+struct vmpipe_proto_header {
+ u32 pkt_type;
+ u32 data_size;
+};
+
+/* For recv, we use the VMBus in-place packet iterator APIs to directly copy
+ * data from the ringbuffer into the userspace buffer.
+ */
+struct hvs_recv_buf {
+ /* The header before the payload data */
+ struct vmpipe_proto_header hdr;
+
+ /* The payload */
+ u8 data[HVS_MTU_SIZE];
+};
+
+/* We can send up to HVS_MTU_SIZE bytes of payload to the host, but let's use
+ * a small size, i.e. HVS_SEND_BUF_SIZE, to minimize the dynamically-allocated
+ * buffer, because tests show there is no significant performance difference.
+ *
+ * Note: the buffer can be eliminated in the future when we add new VMBus
+ * ringbuffer APIs that allow us to directly copy data from userspace buffer
+ * to VMBus ringbuffer.
+ */
+#define HVS_SEND_BUF_SIZE (PAGE_SIZE_4K - sizeof(struct vmpipe_proto_header))
+
+struct hvs_send_buf {
+ /* The header before the payload data */
+ struct vmpipe_proto_header hdr;
+
+ /* The payload */
+ u8 data[HVS_SEND_BUF_SIZE];
+};
+
+#define HVS_HEADER_LEN (sizeof(struct vmpacket_descriptor) + \
+ sizeof(struct vmpipe_proto_header))
+
+/* See 'prev_indices' in hv_ringbuffer_read(), hv_ringbuffer_write(), and
+ * __hv_pkt_iter_next().
+ */
+#define VMBUS_PKT_TRAILER (sizeof(u64))
+
+#define HVS_PKT_LEN(payload_len) (HVS_HEADER_LEN + \
+ ALIGN((payload_len), 8) + \
+ VMBUS_PKT_TRAILER)
+
+/* Per-socket state (accessed via vsk->trans) */
+struct hvsock {
+ struct vsock_sock *vsk;
+
+ uuid_le vm_srv_id;
+ uuid_le host_srv_id;
+
+ struct vmbus_channel *chan;
+ struct vmpacket_descriptor *recv_desc;
+
+ /* The length of the payload not delivered to userland yet */
+ u32 recv_data_len;
+ /* The offset of the payload */
+ u32 recv_data_off;
+};
+
+/* In the VM, we support Hyper-V Sockets with AF_VSOCK, and the endpoint is
+ * <cid, port> (see struct sockaddr_vm). Note: cid is not really used here:
+ * when we write apps to connect to the host, we can only use VMADDR_CID_ANY
+ * or VMADDR_CID_HOST (both are equivalent) as the remote cid, and when we
+ * write apps to bind() & listen() in the VM, we can only use VMADDR_CID_ANY
+ * as the local cid.
+ *
+ * On the host, Hyper-V Sockets are supported by Winsock AF_HYPERV:
+ * https://docs.microsoft.com/en-us/virtualization/hyper-v-on-windows/user-
+ * guide/make-integration-service, and the endpoint is <VmID, ServiceId> with
+ * the below sockaddr:
+ *
+ * struct SOCKADDR_HV
+ * {
+ * ADDRESS_FAMILY Family;
+ * USHORT Reserved;
+ * GUID VmId;
+ * GUID ServiceId;
+ * };
+ * Note: VmID is not used by Linux VM and actually it isn't transmitted via
+ * VMBus, because here it's obvious the host and the VM can easily identify
+ * each other. Though the VmID is useful on the host, especially in the case
+ * of Windows container, Linux VM doesn't need it at all.
+ *
+ * To make use of the AF_VSOCK infrastructure in Linux VM, we have to limit
+ * the available GUID space of SOCKADDR_HV so that we can create a mapping
+ * between AF_VSOCK port and SOCKADDR_HV Service GUID. The rule of writing
+ * Hyper-V Sockets apps on the host and in Linux VM is:
+ *
+ ****************************************************************************
+ * the only valid Service GUIDs, from the perspectives of both the host and *
+ * Linux VM, that can be connected by the other end, must conform to this *
+ * format: <port>-facb-11e6-bd58-64006a7986d3, and the "port" must be in *
+ * this range [0, 0x7FFFFFFF]. *
+ ****************************************************************************
+ *
+ * When we write apps on the host to connect(), the GUID ServiceID is used.
+ * When we write apps in Linux VM to connect(), we only need to specify the
+ * port and the driver will form the GUID and use that to request the host.
+ *
+ * From the perspective of Linux VM:
+ * 1. the local ephemeral port (i.e. the local auto-bound port when we call
+ * connect() without explicit bind()) is generated by __vsock_bind_stream(),
+ * and the range is [1024, 0xFFFFFFFF).
+ * 2. the remote ephemeral port (i.e. the auto-generated remote port for
+ * a connect request initiated by the host's connect()) is generated by
+ * hvs_remote_addr_init() and the range is [0x80000000, 0xFFFFFFFF).
+ */
+
+#define MAX_LISTEN_PORT ((u32)0x7FFFFFFF)
+#define MAX_VM_LISTEN_PORT MAX_LISTEN_PORT
+#define MAX_HOST_LISTEN_PORT MAX_LISTEN_PORT
+#define MIN_HOST_EPHEMERAL_PORT (MAX_HOST_LISTEN_PORT + 1)
+
+/* 00000000-facb-11e6-bd58-64006a7986d3 */
+static const uuid_le srv_id_template =
+ UUID_LE(0x00000000, 0xfacb, 0x11e6, 0xbd, 0x58,
+ 0x64, 0x00, 0x6a, 0x79, 0x86, 0xd3);
+
+static inline bool is_valid_srv_id(const uuid_le *id)
+{
+ return !memcmp(&id->b[4], &srv_id_template.b[4], sizeof(uuid_le) - 4);
+}
+
+static inline unsigned int get_port_by_srv_id(const uuid_le *svr_id)
+{
+ return *((unsigned int *)svr_id);
+}
+
+static inline void hvs_addr_init(struct sockaddr_vm *addr,
+ const uuid_le *svr_id)
+{
+ unsigned int port = get_port_by_srv_id(svr_id);
+
+ vsock_addr_init(addr, VMADDR_CID_ANY, port);
+}
+
+static inline void hvs_remote_addr_init(struct sockaddr_vm *remote,
+ struct sockaddr_vm *local)
+{
+ static u32 host_ephemeral_port = MIN_HOST_EPHEMERAL_PORT;
+ struct sock *sk;
+
+ vsock_addr_init(remote, VMADDR_CID_ANY, VMADDR_PORT_ANY);
+
+ while (1) {
+ /* Wrap around ? */
+ if (host_ephemeral_port < MIN_HOST_EPHEMERAL_PORT ||
+ host_ephemeral_port == VMADDR_PORT_ANY)
+ host_ephemeral_port = MIN_HOST_EPHEMERAL_PORT;
+
+ remote->svm_port = host_ephemeral_port++;
+
+ sk = vsock_find_connected_socket(remote, local);
+ if (!sk) {
+ /* Found an available ephemeral port */
+ return;
+ }
+
+ /* Release refcnt got in vsock_find_connected_socket */
+ sock_put(sk);
+ }
+}
+
+static bool hvs_channel_readable(struct vmbus_channel *chan)
+{
+ u32 readable = hv_get_bytes_to_read(&chan->inbound);
+
+ /* 0-size payload means FIN */
+ return readable >= HVS_PKT_LEN(0);
+}
+
+static int hvs_channel_readable_payload(struct vmbus_channel *chan)
+{
+ u32 readable = hv_get_bytes_to_read(&chan->inbound);
+
+ if (readable > HVS_PKT_LEN(0)) {
+ /* At least we have 1 byte to read. We don't need to return
+ * the exact readable bytes: see vsock_stream_recvmsg() ->
+ * vsock_stream_has_data().
+ */
+ return 1;
+ }
+
+ if (readable == HVS_PKT_LEN(0)) {
+ /* 0-size payload means FIN */
+ return 0;
+ }
+
+ /* No payload or FIN */
+ return -1;
+}
+
+static inline size_t hvs_channel_writable_bytes(struct vmbus_channel *chan)
+{
+ u32 writeable = hv_get_bytes_to_write(&chan->outbound);
+ size_t ret;
+
+ /* The ringbuffer mustn't be 100% full, and we should reserve a
+ * zero-length-payload packet for the FIN: see hv_ringbuffer_write()
+ * and hvs_shutdown().
+ */
+ if (writeable <= HVS_PKT_LEN(1) + HVS_PKT_LEN(0))
+ return 0;
+
+ ret = writeable - HVS_PKT_LEN(1) - HVS_PKT_LEN(0);
+
+ return round_down(ret, 8);
+}
+
+static int hvs_send_data(struct vmbus_channel *chan,
+ struct hvs_send_buf *send_buf, size_t to_write)
+{
+ send_buf->hdr.pkt_type = 1;
+ send_buf->hdr.data_size = to_write;
+ return vmbus_sendpacket(chan, &send_buf->hdr,
+ sizeof(send_buf->hdr) + to_write,
+ 0, VM_PKT_DATA_INBAND, 0);
+}
+
+static void hvs_channel_cb(void *ctx)
+{
+ struct sock *sk = (struct sock *)ctx;
+ struct vsock_sock *vsk = vsock_sk(sk);
+ struct hvsock *hvs = vsk->trans;
+ struct vmbus_channel *chan = hvs->chan;
+
+ if (hvs_channel_readable(chan))
+ sk->sk_data_ready(sk);
+
+ /* Mark it writable only if there is enough space */
+ if (hvs_channel_writable_bytes(chan) >= HVS_SEND_BUF_SIZE)
+ sk->sk_write_space(sk);
+}
+
+static void hvs_close_connection(struct vmbus_channel *chan)
+{
+ struct sock *sk = get_per_channel_state(chan);
+ struct vsock_sock *vsk = vsock_sk(sk);
+
+ sk->sk_state = SS_UNCONNECTED;
+ sock_set_flag(sk, SOCK_DONE);
+ vsk->peer_shutdown |= SEND_SHUTDOWN | RCV_SHUTDOWN;
+
+ sk->sk_state_change(sk);
+}
+
+static void hvs_open_connection(struct vmbus_channel *chan)
+{
+ uuid_le *if_instance, *if_type;
+ unsigned char conn_from_host;
+
+ struct sockaddr_vm addr;
+ struct sock *sk, *new = NULL;
+ struct vsock_sock *vnew;
+ struct hvsock *hvs, *hvs_new;
+ int ret;
+
+ if_type = &chan->offermsg.offer.if_type;
+ if_instance = &chan->offermsg.offer.if_instance;
+ conn_from_host = chan->offermsg.offer.u.pipe.user_def[0];
+
+ /* The host or the VM should only listen on a port in
+ * [0, MAX_LISTEN_PORT]
+ */
+ if (!is_valid_srv_id(if_type) ||
+ get_port_by_srv_id(if_type) > MAX_LISTEN_PORT)
+ return;
+
+ hvs_addr_init(&addr, conn_from_host ? if_type : if_instance);
+ sk = vsock_find_bound_socket(&addr);
+ if (!sk)
+ return;
+
+ if ((conn_from_host && sk->sk_state != VSOCK_SS_LISTEN) ||
+ (!conn_from_host && sk->sk_state != SS_CONNECTING))
+ goto out;
+
+ if (conn_from_host) {
+ if (sk->sk_ack_backlog >= sk->sk_max_ack_backlog)
+ goto out;
+
+ new = __vsock_create(sock_net(sk), NULL, sk, GFP_KERNEL,
+ sk->sk_type, 0);
+ if (!new)
+ goto out;
+
+ new->sk_state = SS_CONNECTING;
+ vnew = vsock_sk(new);
+ hvs_new = vnew->trans;
+ hvs_new->chan = chan;
+ } else {
+ hvs = vsock_sk(sk)->trans;
+ hvs->chan = chan;
+ }
+
+ set_channel_read_mode(chan, HV_CALL_DIRECT);
+ ret = vmbus_open(chan, RINGBUFFER_HVS_SND_SIZE,
+ RINGBUFFER_HVS_RCV_SIZE, NULL, 0,
+ hvs_channel_cb, conn_from_host ? new : sk);
+ if (ret != 0) {
+ if (conn_from_host) {
+ hvs_new->chan = NULL;
+ sock_put(new);
+ } else {
+ hvs->chan = NULL;
+ }
+ goto out;
+ }
+
+ set_per_channel_state(chan, conn_from_host ? new : sk);
+ vmbus_set_chn_rescind_callback(chan, hvs_close_connection);
+
+ /* See hvs_channel_cb() and hvs_notify_poll_out() */
+ set_channel_pending_send_size(chan,
+ HVS_PKT_LEN(HVS_SEND_BUF_SIZE) + 1);
+
+ if (conn_from_host) {
+ new->sk_state = SS_CONNECTED;
+ sk->sk_ack_backlog++;
+
+ hvs_addr_init(&vnew->local_addr, if_type);
+ hvs_remote_addr_init(&vnew->remote_addr, &vnew->local_addr);
+
+ hvs_new->vm_srv_id = *if_type;
+ hvs_new->host_srv_id = *if_instance;
+
+ vsock_insert_connected(vnew);
+ vsock_enqueue_accept(sk, new);
+ } else {
+ sk->sk_state = SS_CONNECTED;
+ sk->sk_socket->state = SS_CONNECTED;
+
+ vsock_insert_connected(vsock_sk(sk));
+ }
+
+ sk->sk_state_change(sk);
+
+out:
+ /* Release refcnt obtained when we called vsock_find_bound_socket() */
+ sock_put(sk);
+}
+
+static u32 hvs_get_local_cid(void)
+{
+ return VMADDR_CID_ANY;
+}
+
+static int hvs_sock_init(struct vsock_sock *vsk, struct vsock_sock *psk)
+{
+ struct hvsock *hvs;
+
+ hvs = kzalloc(sizeof(*hvs), GFP_KERNEL);
+ if (!hvs)
+ return -ENOMEM;
+
+ vsk->trans = hvs;
+ hvs->vsk = vsk;
+
+ return 0;
+}
+
+static int hvs_connect(struct vsock_sock *vsk)
+{
+ struct hvsock *h = vsk->trans;
+
+ h->vm_srv_id = srv_id_template;
+ h->host_srv_id = srv_id_template;
+
+ *((u32 *)&h->vm_srv_id) = vsk->local_addr.svm_port;
+ *((u32 *)&h->host_srv_id) = vsk->remote_addr.svm_port;
+
+ return vmbus_send_tl_connect_request(&h->vm_srv_id, &h->host_srv_id);
+}
+
+static int hvs_shutdown(struct vsock_sock *vsk, int mode)
+{
+ struct vmpipe_proto_header hdr;
+ struct hvs_send_buf *send_buf;
+ struct hvsock *hvs;
+
+ if (!(mode & SEND_SHUTDOWN))
+ return 0;
+
+ hvs = vsk->trans;
+
+ send_buf = (struct hvs_send_buf *)&hdr;
+
+ /* It can't fail: see hvs_channel_writable_bytes(). */
+ (void)hvs_send_data(hvs->chan, send_buf, 0);
+
+ return 0;
+}
+
+static void hvs_release(struct vsock_sock *vsk)
+{
+ struct hvsock *hvs = vsk->trans;
+ struct vmbus_channel *chan = hvs->chan;
+
+ if (chan)
+ hvs_shutdown(vsk, RCV_SHUTDOWN | SEND_SHUTDOWN);
+
+ vsock_remove_sock(vsk);
+}
+
+static void hvs_destruct(struct vsock_sock *vsk)
+{
+ struct hvsock *hvs = vsk->trans;
+ struct vmbus_channel *chan = hvs->chan;
+
+ if (chan)
+ vmbus_hvsock_device_unregister(chan);
+
+ kfree(hvs);
+}
+
+static int hvs_dgram_bind(struct vsock_sock *vsk, struct sockaddr_vm *addr)
+{
+ return -EOPNOTSUPP;
+}
+
+static int hvs_dgram_dequeue(struct vsock_sock *vsk, struct msghdr *msg,
+ size_t len, int flags)
+{
+ return -EOPNOTSUPP;
+}
+
+static int hvs_dgram_enqueue(struct vsock_sock *vsk,
+ struct sockaddr_vm *remote, struct msghdr *msg,
+ size_t dgram_len)
+{
+ return -EOPNOTSUPP;
+}
+
+static bool hvs_dgram_allow(u32 cid, u32 port)
+{
+ return false;
+}
+
+static ssize_t hvs_stream_dequeue(struct vsock_sock *vsk, struct msghdr *msg,
+ size_t len, int flags)
+{
+ struct hvsock *hvs = vsk->trans;
+ bool need_refill = !hvs->recv_desc;
+ struct hvs_recv_buf *recv_buf;
+ u32 payload_len, to_read;
+ int ret;
+
+ if (flags & MSG_PEEK)
+ return -EOPNOTSUPP;
+
+ if (need_refill) {
+ hvs->recv_desc = hv_pkt_iter_first(hvs->chan);
+ recv_buf = (struct hvs_recv_buf *)(hvs->recv_desc + 1);
+
+ payload_len = recv_buf->hdr.data_size;
+ if (payload_len == 0 || payload_len > HVS_MTU_SIZE)
+ return -EIO;
+
+ hvs->recv_data_len = payload_len;
+ hvs->recv_data_off = 0;
+ } else {
+ recv_buf = (struct hvs_recv_buf *)(hvs->recv_desc + 1);
+ }
+
+ to_read = min_t(u32, len, hvs->recv_data_len);
+ ret = memcpy_to_msg(msg, recv_buf->data + hvs->recv_data_off, to_read);
+ if (ret != 0)
+ return ret;
+
+ hvs->recv_data_len -= to_read;
+
+ if (hvs->recv_data_len == 0)
+ hvs->recv_desc = hv_pkt_iter_next(hvs->chan, hvs->recv_desc);
+ else
+ hvs->recv_data_off += to_read;
+
+ return to_read;
+}
+
+static ssize_t hvs_stream_enqueue(struct vsock_sock *vsk, struct msghdr *msg,
+ size_t len)
+{
+ struct hvsock *hvs = vsk->trans;
+ struct vmbus_channel *chan = hvs->chan;
+ struct hvs_send_buf *send_buf;
+ size_t to_write, max_writable, ret;
+
+ BUILD_BUG_ON(sizeof(*send_buf) != PAGE_SIZE_4K);
+
+ send_buf = kmalloc(sizeof(*send_buf), GFP_KERNEL);
+ if (!send_buf)
+ return -ENOMEM;
+
+ max_writable = hvs_channel_writable_bytes(chan);
+ to_write = min_t(size_t, len, max_writable);
+ to_write = min_t(size_t, to_write, HVS_SEND_BUF_SIZE);
+
+ ret = memcpy_from_msg(send_buf->data, msg, to_write);
+ if (ret < 0)
+ goto out;
+
+ ret = hvs_send_data(hvs->chan, send_buf, to_write);
+ if (ret < 0)
+ goto out;
+
+ ret = to_write;
+out:
+ kfree(send_buf);
+ return ret;
+}
+
+static s64 hvs_stream_has_data(struct vsock_sock *vsk)
+{
+ struct hvsock *hvs = vsk->trans;
+ s64 ret;
+
+ switch (hvs_channel_readable_payload(hvs->chan)) {
+ case 1:
+ ret = 1;
+ break;
+ case 0:
+ vsk->peer_shutdown |= SEND_SHUTDOWN;
+ ret = 0;
+ break;
+ default: /* -1 */
+ ret = 0;
+ break;
+ }
+
+ return ret;
+}
+
+static s64 hvs_stream_has_space(struct vsock_sock *vsk)
+{
+ struct hvsock *hvs = vsk->trans;
+
+ return hvs_channel_writable_bytes(hvs->chan);
+}
+
+static u64 hvs_stream_rcvhiwat(struct vsock_sock *vsk)
+{
+ return HVS_MTU_SIZE + 1;
+}
+
+static bool hvs_stream_is_active(struct vsock_sock *vsk)
+{
+ struct hvsock *hvs = vsk->trans;
+
+ return hvs->chan != NULL;
+}
+
+static bool hvs_stream_allow(u32 cid, u32 port)
+{
+ static const u32 valid_cids[] = {
+ VMADDR_CID_ANY,
+ VMADDR_CID_HOST,
+ };
+ int i;
+
+ /* The host's port range [MIN_HOST_EPHEMERAL_PORT, 0xFFFFFFFF) is
+ * reserved as ephemeral ports, which are used as the host's ports
+ * when the host initiates connections.
+ */
+ if (port > MAX_HOST_LISTEN_PORT)
+ return false;
+
+ for (i = 0; i < ARRAY_SIZE(valid_cids); i++) {
+ if (cid == valid_cids[i])
+ return true;
+ }
+
+ return false;
+}
+
+static
+int hvs_notify_poll_in(struct vsock_sock *vsk, size_t target, bool *readable)
+{
+ struct hvsock *hvs = vsk->trans;
+
+ *readable = hvs_channel_readable(hvs->chan);
+ return 0;
+}
+
+static
+int hvs_notify_poll_out(struct vsock_sock *vsk, size_t target, bool *writable)
+{
+ /* Report writable only if there is enough space */
+ *writable = hvs_stream_has_space(vsk) >= HVS_SEND_BUF_SIZE;
+
+ return 0;
+}
+
+static
+int hvs_notify_recv_init(struct vsock_sock *vsk, size_t target,
+ struct vsock_transport_recv_notify_data *d)
+{
+ return 0;
+}
+
+static
+int hvs_notify_recv_pre_block(struct vsock_sock *vsk, size_t target,
+ struct vsock_transport_recv_notify_data *d)
+{
+ return 0;
+}
+
+static
+int hvs_notify_recv_pre_dequeue(struct vsock_sock *vsk, size_t target,
+ struct vsock_transport_recv_notify_data *d)
+{
+ return 0;
+}
+
+static
+int hvs_notify_recv_post_dequeue(struct vsock_sock *vsk, size_t target,
+ ssize_t copied, bool data_read,
+ struct vsock_transport_recv_notify_data *d)
+{
+ return 0;
+}
+
+static
+int hvs_notify_send_init(struct vsock_sock *vsk,
+ struct vsock_transport_send_notify_data *d)
+{
+ return 0;
+}
+
+static
+int hvs_notify_send_pre_block(struct vsock_sock *vsk,
+ struct vsock_transport_send_notify_data *d)
+{
+ return 0;
+}
+
+static
+int hvs_notify_send_pre_enqueue(struct vsock_sock *vsk,
+ struct vsock_transport_send_notify_data *d)
+{
+ return 0;
+}
+
+static
+int hvs_notify_send_post_enqueue(struct vsock_sock *vsk, ssize_t written,
+ struct vsock_transport_send_notify_data *d)
+{
+ return 0;
+}
+
+static void hvs_set_buffer_size(struct vsock_sock *vsk, u64 val)
+{
+ /* Ignored. */
+}
+
+static void hvs_set_min_buffer_size(struct vsock_sock *vsk, u64 val)
+{
+ /* Ignored. */
+}
+
+static void hvs_set_max_buffer_size(struct vsock_sock *vsk, u64 val)
+{
+ /* Ignored. */
+}
+
+static u64 hvs_get_buffer_size(struct vsock_sock *vsk)
+{
+ return -ENOPROTOOPT;
+}
+
+static u64 hvs_get_min_buffer_size(struct vsock_sock *vsk)
+{
+ return -ENOPROTOOPT;
+}
+
+static u64 hvs_get_max_buffer_size(struct vsock_sock *vsk)
+{
+ return -ENOPROTOOPT;
+}
+
+static struct vsock_transport hvs_transport = {
+ .get_local_cid = hvs_get_local_cid,
+
+ .init = hvs_sock_init,
+ .destruct = hvs_destruct,
+ .release = hvs_release,
+ .connect = hvs_connect,
+ .shutdown = hvs_shutdown,
+
+ .dgram_bind = hvs_dgram_bind,
+ .dgram_dequeue = hvs_dgram_dequeue,
+ .dgram_enqueue = hvs_dgram_enqueue,
+ .dgram_allow = hvs_dgram_allow,
+
+ .stream_dequeue = hvs_stream_dequeue,
+ .stream_enqueue = hvs_stream_enqueue,
+ .stream_has_data = hvs_stream_has_data,
+ .stream_has_space = hvs_stream_has_space,
+ .stream_rcvhiwat = hvs_stream_rcvhiwat,
+ .stream_is_active = hvs_stream_is_active,
+ .stream_allow = hvs_stream_allow,
+
+ .notify_poll_in = hvs_notify_poll_in,
+ .notify_poll_out = hvs_notify_poll_out,
+ .notify_recv_init = hvs_notify_recv_init,
+ .notify_recv_pre_block = hvs_notify_recv_pre_block,
+ .notify_recv_pre_dequeue = hvs_notify_recv_pre_dequeue,
+ .notify_recv_post_dequeue = hvs_notify_recv_post_dequeue,
+ .notify_send_init = hvs_notify_send_init,
+ .notify_send_pre_block = hvs_notify_send_pre_block,
+ .notify_send_pre_enqueue = hvs_notify_send_pre_enqueue,
+ .notify_send_post_enqueue = hvs_notify_send_post_enqueue,
+
+ .set_buffer_size = hvs_set_buffer_size,
+ .set_min_buffer_size = hvs_set_min_buffer_size,
+ .set_max_buffer_size = hvs_set_max_buffer_size,
+ .get_buffer_size = hvs_get_buffer_size,
+ .get_min_buffer_size = hvs_get_min_buffer_size,
+ .get_max_buffer_size = hvs_get_max_buffer_size,
+};
+
+static int hvs_probe(struct hv_device *hdev,
+ const struct hv_vmbus_device_id *dev_id)
+{
+ struct vmbus_channel *chan = hdev->channel;
+
+ hvs_open_connection(chan);
+
+ /* Always return success to suppress the unnecessary error message
+ * in vmbus_probe(): on error the host will rescind the device in
+ * 30 seconds and we can do cleanup at that time in
+ * vmbus_onoffer_rescind().
+ */
+ return 0;
+}
+
+static int hvs_remove(struct hv_device *hdev)
+{
+ struct vmbus_channel *chan = hdev->channel;
+
+ vmbus_close(chan);
+
+ return 0;
+}
+
+/* This isn't really used. See vmbus_match() and vmbus_probe() */
+static const struct hv_vmbus_device_id id_table[] = {
+ {},
+};
+
+static struct hv_driver hvs_drv = {
+ .name = "hv_sock",
+ .hvsock = true,
+ .id_table = id_table,
+ .probe = hvs_probe,
+ .remove = hvs_remove,
+};
+
+static int __init hvs_init(void)
+{
+ int ret;
+
+ if (vmbus_proto_version < VERSION_WIN10)
+ return -ENODEV;
+
+ ret = vmbus_driver_register(&hvs_drv);
+ if (ret != 0)
+ return ret;
+
+ ret = vsock_core_init(&hvs_transport);
+ if (ret) {
+ vmbus_driver_unregister(&hvs_drv);
+ return ret;
+ }
+
+ return 0;
+}
+
+static void __exit hvs_exit(void)
+{
+ vsock_core_exit();
+ vmbus_driver_unregister(&hvs_drv);
+}
+
+module_init(hvs_init);
+module_exit(hvs_exit);
+
+MODULE_DESCRIPTION("Hyper-V sockets");
+MODULE_VERSION("1.0.0");
+MODULE_LICENSE("GPL");
--
2.13.0

View File

@@ -1,64 +0,0 @@
From 8c0a1dd39543ded436035c114379acdbc2b020ad Mon Sep 17 00:00:00 2001
From: Dexuan Cui <decui@microsoft.com>
Date: Fri, 5 May 2017 16:57:29 -0600
Subject: [PATCH 07/20] VMCI: only try to load on VMware hypervisor
Without the patch, vmw_vsock_vmci_transport.ko and vmw_vmci.ko can
automatically load when an application creates an AF_VSOCK socket.
This is the expected good behavior on VMware hypervisor, but as we
are adding hv_sock.ko (i.e. Hyper-V transport for AF_VSOCK), we should
make sure vmw_vsock_vmci_transport.ko can't load on Hyper-V, otherwise
there is a -EBUSY conflict when both vmw_vsock_vmci_transport.ko and
hv_sock.ko try to call vsock_core_init().
On the other hand, hv_sock.ko can only load on Hyper-V, because it
depends on hv_vmbus.ko, which deteces Hyper-V in hv_acpi_init().
KVM's vsock_virtio_transport doesn't have the issue because it doesn't
define MODULE_ALIAS_NETPROTO(PF_VSOCK).
Signed-off-by: Dexuan Cui <decui@microsoft.com>
Cc: Alok Kataria <akataria@vmware.com>
Cc: Andy King <acking@vmware.com>
Cc: Adit Ranadive <aditr@vmware.com>
Cc: George Zhang <georgezhang@vmware.com>
Cc: Jorgen Hansen <jhansen@vmware.com>
Cc: K. Y. Srinivasan <kys@microsoft.com>
Cc: Haiyang Zhang <haiyangz@microsoft.com>
Cc: Stephen Hemminger <sthemmin@microsoft.com>
Origin: git@github.com:dcui/linux.git
(cherry picked from commit b5566b1b6e5cb19b381590587f841f950caabe4d)
---
drivers/misc/vmw_vmci/vmci_driver.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/drivers/misc/vmw_vmci/vmci_driver.c b/drivers/misc/vmw_vmci/vmci_driver.c
index d7eaf1eb11e7..1789ea71ff5d 100644
--- a/drivers/misc/vmw_vmci/vmci_driver.c
+++ b/drivers/misc/vmw_vmci/vmci_driver.c
@@ -19,6 +19,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
+#include <linux/hypervisor.h>
#include "vmci_driver.h"
#include "vmci_event.h"
@@ -58,6 +59,13 @@ static int __init vmci_drv_init(void)
int vmci_err;
int error;
+ /*
+ * Check if we are running on VMware's hypervisor and bail out
+ * if we are not.
+ */
+ if (x86_hyper != &x86_hyper_vmware)
+ return -ENODEV;
+
vmci_err = vmci_event_init();
if (vmci_err < VMCI_SUCCESS) {
pr_err("Failed to initialize VMCIEvent (result=%d)\n",
--
2.13.0

View File

@@ -1,30 +0,0 @@
From a1b36bab8fc7abe0e0d246d29f8415e664839520 Mon Sep 17 00:00:00 2001
From: Dexuan Cui <decui@microsoft.com>
Date: Fri, 5 May 2017 16:57:35 -0600
Subject: [PATCH 08/20] hv_sock: add the support of auto-loading
After we disable VMWare virtual sockets driver's auto-loading on Hyper-V,
we can enable hv_sock's auto-loading now.
Signed-off-by: Dexuan Cui <decui@microsoft.com>
Cc: K. Y. Srinivasan <kys@microsoft.com>
Cc: Haiyang Zhang <haiyangz@microsoft.com>
Cc: Stephen Hemminger <sthemmin@microsoft.com>
Origin: git@github.com:dcui/linux.git
(cherry picked from commit 6f1aa69011356ff95ed6c57400095e5f2d9eb900)
---
net/vmw_vsock/hyperv_transport.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/net/vmw_vsock/hyperv_transport.c b/net/vmw_vsock/hyperv_transport.c
index fd89bf357617..f465b0b662df 100644
--- a/net/vmw_vsock/hyperv_transport.c
+++ b/net/vmw_vsock/hyperv_transport.c
@@ -827,3 +827,4 @@ module_exit(hvs_exit);
MODULE_DESCRIPTION("Hyper-V sockets");
MODULE_VERSION("1.0.0");
MODULE_LICENSE("GPL");
+MODULE_ALIAS_NETPROTO(PF_VSOCK);
--
2.13.0

View File

@@ -1,430 +0,0 @@
From 80879b7b52cd2abd8731c3b34f6d5ea3cc4ad2d2 Mon Sep 17 00:00:00 2001
From: Dexuan Cui <decui@microsoft.com>
Date: Fri, 5 May 2017 18:52:02 -0600
Subject: [PATCH 09/20] tools: hv_sock: 2 simple test cases.
Please read this document first:
https://docs.microsoft.com/en-us/virtualization/hyper-v-on-windows/user-guide/make-integration-service
And you may want to have a look at
https://github.com/dcui/linux/commit/691aff936c0fa6fc24e2662c0e8cc6ab65509600#diff-2cf9109d84c1ba75b09e40090f4a2176R100
Signed-off-by: Dexuan Cui <decui@microsoft.com>
Origin: git@github.com:dcui/linux.git
(cherry picked from commit 2fac74605d2db862caaaf4890239b57095fba832)
---
tools/hv/hv_sock/test-001/client_in_vm.c | 38 +++++++++
tools/hv/hv_sock/test-001/server_on_host.c | 128 +++++++++++++++++++++++++++++
tools/hv/hv_sock/test-002/client_on_host.c | 127 ++++++++++++++++++++++++++++
tools/hv/hv_sock/test-002/server_in_vm.c | 85 +++++++++++++++++++
4 files changed, 378 insertions(+)
create mode 100644 tools/hv/hv_sock/test-001/client_in_vm.c
create mode 100644 tools/hv/hv_sock/test-001/server_on_host.c
create mode 100644 tools/hv/hv_sock/test-002/client_on_host.c
create mode 100644 tools/hv/hv_sock/test-002/server_in_vm.c
diff --git a/tools/hv/hv_sock/test-001/client_in_vm.c b/tools/hv/hv_sock/test-001/client_in_vm.c
new file mode 100644
index 000000000000..2e2371b13fa7
--- /dev/null
+++ b/tools/hv/hv_sock/test-001/client_in_vm.c
@@ -0,0 +1,38 @@
+/* The program runs in Linux VM. */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/socket.h>
+#include <linux/vm_sockets.h>
+
+int main()
+{
+ int fd;
+
+ struct sockaddr_vm sa = {
+ .svm_family = AF_VSOCK,
+ .svm_reserved1 = 0,
+ .svm_cid = VMADDR_CID_ANY,
+ };
+
+ /* Connecting to the host's 00000808-facb-11e6-bd58-64006a7986d3 */
+ sa.svm_port = 0x808;
+
+ fd = socket(AF_VSOCK, SOCK_STREAM, 0);
+ if (fd < 0) {
+ perror("socket");
+ return -1;
+ }
+
+ if (connect(fd, (struct sockaddr*)&sa, sizeof(sa)) != 0) {
+ perror("connect");
+ return -1;
+ }
+
+ printf("Connected to the host.\n");
+
+ close(fd);
+ printf("Closed the connection.\n");
+
+ return 0;
+}
diff --git a/tools/hv/hv_sock/test-001/server_on_host.c b/tools/hv/hv_sock/test-001/server_on_host.c
new file mode 100644
index 000000000000..22c48e8d3789
--- /dev/null
+++ b/tools/hv/hv_sock/test-001/server_on_host.c
@@ -0,0 +1,128 @@
+/* The program runs on Windows 10 or Windows Server 2016 host or newer. */
+
+#include <stdio.h>
+#include <stdint.h>
+#include <winsock2.h>
+#include <ws2def.h>
+#include <initguid.h>
+
+#pragma comment(lib, "ws2_32.lib")
+
+#ifndef AF_HYPERV
+#define AF_HYPERV 34
+#define HV_PROTOCOL_RAW 1
+
+typedef struct _SOCKADDR_HV
+{
+ ADDRESS_FAMILY Family;
+ USHORT Reserved;
+ GUID VmId;
+ GUID ServiceId;
+} SOCKADDR_HV, *PSOCKADDR_HV;
+
+DEFINE_GUID(HV_GUID_SELF, 0x00000000, 0x0000, 0x0000,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
+#endif /* AF_HYPERV */
+
+#define VMADDR_PORT_ANY 0xFFFFFFFF
+
+/* 00000000-facb-11e6-bd58-64006a7986d3 */
+DEFINE_GUID(HVSOCK_LINUX_TEMPLATE, 0x00000000, 0xfacb, 0x11e6,
+ 0xbd, 0x58, 0x64, 0x00, 0x6a, 0x79, 0x86, 0xd3);
+
+static const GUID VsockServiceIdTemplate = HVSOCK_LINUX_TEMPLATE;
+
+bool TryConvertVsockPortToServiceId(uint32_t port, GUID *serviceId)
+{
+ if (port == VMADDR_PORT_ANY)
+ return false;
+
+ *serviceId = VsockServiceIdTemplate;
+ serviceId->Data1 = port;
+ return true;
+}
+
+bool TryConvertServiceIdToVsockPort(const GUID *serviceId, uint32_t *port)
+{
+ if (memcmp(&serviceId->Data2, &VsockServiceIdTemplate.Data2,
+ sizeof(GUID) - sizeof(uint32_t)) != 0 ||
+ serviceId->Data1 == VMADDR_PORT_ANY) {
+ return false;
+ }
+
+ *port = serviceId->Data1;
+ return true;
+}
+
+int CreateListenSocket(uint32_t port, SOCKET *result_fd)
+{
+ SOCKADDR_HV localAddr;
+ SOCKET fd;
+ int ret;
+
+ fd = socket(AF_HYPERV, SOCK_STREAM, HV_PROTOCOL_RAW);
+ if (fd == INVALID_SOCKET) {
+ printf("socket() failed: error = %d\n", WSAGetLastError());
+ return -1;
+ }
+
+ memset(&localAddr, 0, sizeof(SOCKADDR_HV));
+ localAddr.Family = AF_HYPERV;
+ localAddr.VmId = HV_GUID_SELF;
+ TryConvertVsockPortToServiceId(port, &localAddr.ServiceId);
+
+ ret = bind(fd, (SOCKADDR *)&localAddr, sizeof(SOCKADDR_HV));
+ if (ret == SOCKET_ERROR) {
+ printf("bind() failed: error = %d\n", WSAGetLastError());
+ goto err;
+ }
+
+ ret = listen(fd, 10);
+ if (ret == SOCKET_ERROR) {
+ printf("listen() failed: error = %d\n", WSAGetLastError());
+ goto err;
+ }
+
+ *result_fd = fd;
+ printf("Listening on fd = 0x%d, local port = 0x%x\n", fd, port);
+ return 0;
+err:
+ closesocket(fd);
+ return -1;
+}
+
+int main()
+{
+ WSADATA wsaData;
+ SOCKADDR_HV remoteAddr;
+ int remoteAddrLen;
+ SOCKET fd;
+ SOCKET children[100];
+ int i, ret;
+
+ // Initialize Winsock
+ ret = WSAStartup(MAKEWORD(2, 2), &wsaData);
+ if (ret != NO_ERROR) {
+ printf("WSAStartup() failed with error: %d\n", ret);
+ return -1;
+ }
+
+ // We'll listen on 00000808-facb-11e6-bd58-64006a7986d3
+ if (CreateListenSocket(0x808, &fd) < 0) {
+ printf("failed to listen!\n");
+ ret = -1;
+ goto out;
+ }
+
+ for (i = 0; i < ARRAYSIZE(children); i++) {
+ remoteAddrLen = sizeof(SOCKADDR_HV);
+ children[i] = accept(fd, (sockaddr *)&remoteAddr, &remoteAddrLen);
+ closesocket(children[i]);
+ printf("Got a connection and closed it.\n");
+ }
+
+ closesocket(fd);
+out:
+ WSACleanup();
+ return ret;
+}
diff --git a/tools/hv/hv_sock/test-002/client_on_host.c b/tools/hv/hv_sock/test-002/client_on_host.c
new file mode 100644
index 000000000000..ed5ae99fbfba
--- /dev/null
+++ b/tools/hv/hv_sock/test-002/client_on_host.c
@@ -0,0 +1,127 @@
+/* The program runs on Windows 10 or Windows Server 2016 host or newer. */
+
+#include <stdio.h>
+#include <stdint.h>
+#include <winsock2.h>
+#include <ws2def.h>
+#include <initguid.h>
+#include <rpc.h> /* for UuidFromStringA() */
+#pragma comment(lib, "ws2_32.lib")
+#pragma comment(lib, "rpcrt4.lib")
+
+#ifndef AF_HYPERV
+#define AF_HYPERV 34
+#define HV_PROTOCOL_RAW 1
+
+typedef struct _SOCKADDR_HV
+{
+ ADDRESS_FAMILY Family;
+ USHORT Reserved;
+ GUID VmId;
+ GUID ServiceId;
+}SOCKADDR_HV, *PSOCKADDR_HV;
+
+DEFINE_GUID(HV_GUID_SELF, 0x00000000, 0x0000, 0x0000,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
+#endif /* AF_HYPERV */
+
+#define VMADDR_PORT_ANY 0xFFFFFFFF
+
+/* 00000000-facb-11e6-bd58-64006a7986d3 */
+DEFINE_GUID(HVSOCK_LINUX_TEMPLATE, 0x00000000, 0xfacb, 0x11e6,
+ 0xbd, 0x58, 0x64, 0x00, 0x6a, 0x79, 0x86, 0xd3);
+
+static const GUID VsockServiceIdTemplate = HVSOCK_LINUX_TEMPLATE;
+
+bool TryConvertVsockPortToServiceId(uint32_t port, GUID *serviceId)
+{
+ if (port == VMADDR_PORT_ANY)
+ return false;
+
+ *serviceId = VsockServiceIdTemplate;
+ serviceId->Data1 = port;
+ return true;
+}
+
+bool TryConvertServiceIdToVsockPort(const GUID *serviceId, uint32_t *port)
+{
+ if (memcmp(&serviceId->Data2, &VsockServiceIdTemplate.Data2,
+ sizeof(GUID) - sizeof(uint32_t)) != 0 ||
+ serviceId->Data1 == VMADDR_PORT_ANY) {
+ return false;
+ }
+
+ *port = serviceId->Data1;
+ return true;
+}
+
+int ConnectToVM(const SOCKADDR_HV *remoteAddr, SOCKET *result_fd)
+{
+ SOCKADDR_HV localAddr;
+ SOCKET fd;
+ uint32_t port;
+ int ret;
+
+ fd = socket(AF_HYPERV, SOCK_STREAM, HV_PROTOCOL_RAW);
+ if (fd == INVALID_SOCKET) {
+ printf("socket() failed with error: %d\n", WSAGetLastError());
+ return -1;
+ }
+
+ ret = connect(fd, (SOCKADDR *)remoteAddr, sizeof(SOCKADDR_HV));
+ if (ret == SOCKET_ERROR) {
+ printf("connect() failed: error = %d\n", WSAGetLastError());
+ closesocket(fd);
+ return -1;
+ }
+
+ *result_fd = fd;
+ printf("Connected to the VM: fd = 0x%x\n", fd);
+ return 0;
+}
+
+int main()
+{
+ const char *msg = "***Hello! This message is from the host!***\n";
+ WSADATA wsaData;
+ SOCKADDR_HV remoteAddr;
+ SOCKET fd;
+ int ret;
+
+ // Initialize Winsock
+ ret = WSAStartup(MAKEWORD(2, 2), &wsaData);
+ if (ret != NO_ERROR) {
+ printf("WSAStartup() failed with error: %d\n", ret);
+ return -1;
+ }
+
+ memset(&remoteAddr, 0, sizeof(SOCKADDR_HV));
+ remoteAddr.Family = AF_HYPERV;
+
+ // The Linux VM is listening in Vsock port 0x2017
+ TryConvertVsockPortToServiceId(0x2017, &remoteAddr.ServiceId);
+
+ // This is the "remote" VM's VMID got by the PowerShell command
+ // "Get-VM -Name <the_VM_name> | ft id".
+ //
+ // Change it for your own VM.
+ if (UuidFromStringA((RPC_CSTR)"c2624c46-1212-484a-8e28-83dd15fef815",
+ &remoteAddr.VmId) != RPC_S_OK) {
+ printf("Failed to parse the remote VMID: %d\n", GetLastError());
+ ret = -1;
+ goto out;
+ }
+
+ if (ConnectToVM(&remoteAddr, &fd) < 0) {
+ printf("Failed to connect to the VM!\n");
+ ret = -1;
+ goto out;
+ }
+ ret = send(fd, msg, strlen(msg), 0);
+ printf("Sent a msg to the VM: msg_len = %d.\nExited.\n", ret);
+
+ closesocket(fd);
+out:
+ WSACleanup();
+ return ret;
+}
diff --git a/tools/hv/hv_sock/test-002/server_in_vm.c b/tools/hv/hv_sock/test-002/server_in_vm.c
new file mode 100644
index 000000000000..fb4370c53152
--- /dev/null
+++ b/tools/hv/hv_sock/test-002/server_in_vm.c
@@ -0,0 +1,85 @@
+/* The program runs in Linux VM. */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/select.h>
+#include <netdb.h>
+#include <linux/vm_sockets.h>
+
+int main()
+{
+ uint32_t port = 0x2017;
+
+ int listen_fd;
+ int client_fd;
+
+ struct sockaddr_vm sa_listen = {
+ .svm_family = AF_VSOCK,
+ .svm_reserved1 = 0,
+ .svm_cid = VMADDR_CID_ANY,
+ };
+
+ struct sockaddr_vm sa_client;
+ socklen_t socklen_client;
+
+ char buf[4096];
+ int len;
+
+ /* We'll listen on 00002017-facb-11e6-bd58-64006a7986d3 */
+ sa_listen.svm_port = port;
+
+ listen_fd = socket(AF_VSOCK, SOCK_STREAM, 0);
+ if (listen_fd < 0) {
+ perror("socket()");
+ exit(-1);
+ }
+
+ if (bind(listen_fd, (struct sockaddr *)&sa_listen,
+ sizeof(sa_listen)) != 0) {
+ perror("bind()");
+ goto err;
+ }
+
+ if (listen(listen_fd, 10) != 0) {
+ perror("listen()");
+ goto err;
+ }
+
+ printf("Listening on port 0x%x...\n", port);
+
+ socklen_client = sizeof(sa_client);
+ client_fd = accept(listen_fd, (struct sockaddr*)&sa_client,
+ &socklen_client);
+ if (client_fd < 0) {
+ perror("accept()");
+ goto err;
+ }
+
+ printf("Got a connection from the host: cid=0x%x, port=0x%x.\n",
+ sa_client.svm_cid, sa_client.svm_port);
+
+ do {
+ printf("Reading data from the connection...\n");
+ len = read(client_fd, buf, sizeof(buf));
+ if (len > 0) {
+ printf("Read %d bytes:\n", len);
+ fflush(stdout);
+ write(STDOUT_FILENO, buf, len);
+ }
+ } while (len > 0);
+
+ printf("The other end closed the connection.\n");
+
+ close(client_fd);
+ close(listen_fd);
+ return 0;
+err:
+ close(listen_fd);
+ return -1;
+}
--
2.13.0

View File

@@ -1,370 +0,0 @@
From fd279095dc63cec1b1aabb2fc7a1efe0c8c220d2 Mon Sep 17 00:00:00 2001
From: stephen hemminger <stephen@networkplumber.org>
Date: Mon, 27 Feb 2017 10:26:48 -0800
Subject: [PATCH 10/20] vmbus: introduce in-place packet iterator
This is mostly just a refactoring of previous functions
(get_pkt_next_raw, put_pkt_raw and commit_rd_index) to make it easier
to use for other drivers and NAPI.
Signed-off-by: Stephen Hemminger <sthemmin@microsoft.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Origin: git@github.com:dcui/linux.git
(cherry picked from commit 2e307800c6a01cd789afe34eccbcabf384959b3f)
---
drivers/hv/ring_buffer.c | 94 +++++++++++++++++++++++++++++++++++++++++++-
drivers/net/hyperv/netvsc.c | 34 +++++-----------
include/linux/hyperv.h | 96 ++++++++++++++-------------------------------
3 files changed, 133 insertions(+), 91 deletions(-)
diff --git a/drivers/hv/ring_buffer.c b/drivers/hv/ring_buffer.c
index 87799e81af97..c3f1a9e33cef 100644
--- a/drivers/hv/ring_buffer.c
+++ b/drivers/hv/ring_buffer.c
@@ -32,6 +32,8 @@
#include "hyperv_vmbus.h"
+#define VMBUS_PKT_TRAILER 8
+
/*
* When we write to the ring buffer, check if the host needs to
* be signaled. Here is the details of this protocol:
@@ -336,6 +338,12 @@ int hv_ringbuffer_write(struct vmbus_channel *channel,
return 0;
}
+static inline void
+init_cached_read_index(struct hv_ring_buffer_info *rbi)
+{
+ rbi->cached_read_index = rbi->ring_buffer->read_index;
+}
+
int hv_ringbuffer_read(struct vmbus_channel *channel,
void *buffer, u32 buflen, u32 *buffer_actual_len,
u64 *requestid, bool raw)
@@ -366,7 +374,8 @@ int hv_ringbuffer_read(struct vmbus_channel *channel,
return ret;
}
- init_cached_read_index(channel);
+ init_cached_read_index(inring_info);
+
next_read_location = hv_get_next_read_location(inring_info);
next_read_location = hv_copyfrom_ringbuffer(inring_info, &desc,
sizeof(desc),
@@ -410,3 +419,86 @@ int hv_ringbuffer_read(struct vmbus_channel *channel,
return ret;
}
+
+/*
+ * Determine number of bytes available in ring buffer after
+ * the current iterator (priv_read_index) location.
+ *
+ * This is similar to hv_get_bytes_to_read but with private
+ * read index instead.
+ */
+static u32 hv_pkt_iter_avail(const struct hv_ring_buffer_info *rbi)
+{
+ u32 priv_read_loc = rbi->priv_read_index;
+ u32 write_loc = READ_ONCE(rbi->ring_buffer->write_index);
+
+ if (write_loc >= priv_read_loc)
+ return write_loc - priv_read_loc;
+ else
+ return (rbi->ring_datasize - priv_read_loc) + write_loc;
+}
+
+/*
+ * Get first vmbus packet from ring buffer after read_index
+ *
+ * If ring buffer is empty, returns NULL and no other action needed.
+ */
+struct vmpacket_descriptor *hv_pkt_iter_first(struct vmbus_channel *channel)
+{
+ struct hv_ring_buffer_info *rbi = &channel->inbound;
+
+ /* set state for later hv_signal_on_read() */
+ init_cached_read_index(rbi);
+
+ if (hv_pkt_iter_avail(rbi) < sizeof(struct vmpacket_descriptor))
+ return NULL;
+
+ return hv_get_ring_buffer(rbi) + rbi->priv_read_index;
+}
+EXPORT_SYMBOL_GPL(hv_pkt_iter_first);
+
+/*
+ * Get next vmbus packet from ring buffer.
+ *
+ * Advances the current location (priv_read_index) and checks for more
+ * data. If the end of the ring buffer is reached, then return NULL.
+ */
+struct vmpacket_descriptor *
+__hv_pkt_iter_next(struct vmbus_channel *channel,
+ const struct vmpacket_descriptor *desc)
+{
+ struct hv_ring_buffer_info *rbi = &channel->inbound;
+ u32 packetlen = desc->len8 << 3;
+ u32 dsize = rbi->ring_datasize;
+
+ /* bump offset to next potential packet */
+ rbi->priv_read_index += packetlen + VMBUS_PKT_TRAILER;
+ if (rbi->priv_read_index >= dsize)
+ rbi->priv_read_index -= dsize;
+
+ /* more data? */
+ if (hv_pkt_iter_avail(rbi) < sizeof(struct vmpacket_descriptor))
+ return NULL;
+ else
+ return hv_get_ring_buffer(rbi) + rbi->priv_read_index;
+}
+EXPORT_SYMBOL_GPL(__hv_pkt_iter_next);
+
+/*
+ * Update host ring buffer after iterating over packets.
+ */
+void hv_pkt_iter_close(struct vmbus_channel *channel)
+{
+ struct hv_ring_buffer_info *rbi = &channel->inbound;
+
+ /*
+ * Make sure all reads are done before we update the read index since
+ * the writer may start writing to the read area once the read index
+ * is updated.
+ */
+ virt_rmb();
+ rbi->ring_buffer->read_index = rbi->priv_read_index;
+
+ hv_signal_on_read(channel);
+}
+EXPORT_SYMBOL_GPL(hv_pkt_iter_close);
diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c
index 15ef713d96c0..ab9fe48ec133 100644
--- a/drivers/net/hyperv/netvsc.c
+++ b/drivers/net/hyperv/netvsc.c
@@ -646,14 +646,11 @@ static void netvsc_send_tx_complete(struct netvsc_device *net_device,
static void netvsc_send_completion(struct netvsc_device *net_device,
struct vmbus_channel *incoming_channel,
struct hv_device *device,
- struct vmpacket_descriptor *packet)
+ const struct vmpacket_descriptor *desc)
{
- struct nvsp_message *nvsp_packet;
+ struct nvsp_message *nvsp_packet = hv_pkt_data(desc);
struct net_device *ndev = hv_get_drvdata(device);
- nvsp_packet = (struct nvsp_message *)((unsigned long)packet +
- (packet->offset8 << 3));
-
switch (nvsp_packet->hdr.msg_type) {
case NVSP_MSG_TYPE_INIT_COMPLETE:
case NVSP_MSG1_TYPE_SEND_RECV_BUF_COMPLETE:
@@ -667,7 +664,7 @@ static void netvsc_send_completion(struct netvsc_device *net_device,
case NVSP_MSG1_TYPE_SEND_RNDIS_PKT_COMPLETE:
netvsc_send_tx_complete(net_device, incoming_channel,
- device, packet);
+ device, desc);
break;
default:
@@ -1070,9 +1067,11 @@ static void netvsc_receive(struct net_device *ndev,
struct net_device_context *net_device_ctx,
struct hv_device *device,
struct vmbus_channel *channel,
- struct vmtransfer_page_packet_header *vmxferpage_packet,
+ const struct vmpacket_descriptor *desc,
struct nvsp_message *nvsp)
{
+ const struct vmtransfer_page_packet_header *vmxferpage_packet
+ = container_of(desc, const struct vmtransfer_page_packet_header, d);
char *recv_buf = net_device->recv_buf;
u32 status = NVSP_STAT_SUCCESS;
int i;
@@ -1180,12 +1179,10 @@ static void netvsc_process_raw_pkt(struct hv_device *device,
struct netvsc_device *net_device,
struct net_device *ndev,
u64 request_id,
- struct vmpacket_descriptor *desc)
+ const struct vmpacket_descriptor *desc)
{
struct net_device_context *net_device_ctx = netdev_priv(ndev);
- struct nvsp_message *nvmsg
- = (struct nvsp_message *)((unsigned long)desc
- + (desc->offset8 << 3));
+ struct nvsp_message *nvmsg = hv_pkt_data(desc);
switch (desc->type) {
case VM_PKT_COMP:
@@ -1194,9 +1191,7 @@ static void netvsc_process_raw_pkt(struct hv_device *device,
case VM_PKT_DATA_USING_XFER_PAGES:
netvsc_receive(ndev, net_device, net_device_ctx,
- device, channel,
- (struct vmtransfer_page_packet_header *)desc,
- nvmsg);
+ device, channel, desc, nvmsg);
break;
case VM_PKT_DATA_INBAND:
@@ -1218,7 +1213,6 @@ void netvsc_channel_cb(void *context)
struct netvsc_device *net_device;
struct vmpacket_descriptor *desc;
struct net_device *ndev;
- bool need_to_commit = false;
if (channel->primary_channel != NULL)
device = channel->primary_channel->device_obj;
@@ -1237,20 +1231,12 @@ void netvsc_channel_cb(void *context)
netvsc_channel_idle(net_device, q_idx)))
return;
- /* commit_rd_index() -> hv_signal_on_read() needs this. */
- init_cached_read_index(channel);
-
- while ((desc = get_next_pkt_raw(channel)) != NULL) {
+ foreach_vmbus_pkt(desc, channel) {
netvsc_process_raw_pkt(device, channel, net_device,
ndev, desc->trans_id, desc);
- put_pkt_raw(channel, desc);
- need_to_commit = true;
}
- if (need_to_commit)
- commit_rd_index(channel);
-
netvsc_chk_recv_comp(net_device, channel, q_idx);
}
diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
index a8bae2caa69f..ba93b7e4a972 100644
--- a/include/linux/hyperv.h
+++ b/include/linux/hyperv.h
@@ -1511,14 +1511,6 @@ static inline void hv_signal_on_read(struct vmbus_channel *channel)
return;
}
-static inline void
-init_cached_read_index(struct vmbus_channel *channel)
-{
- struct hv_ring_buffer_info *rbi = &channel->inbound;
-
- rbi->cached_read_index = rbi->ring_buffer->read_index;
-}
-
/*
* Mask off host interrupt callback notifications
*/
@@ -1552,76 +1544,48 @@ static inline u32 hv_end_read(struct hv_ring_buffer_info *rbi)
/*
* An API to support in-place processing of incoming VMBUS packets.
*/
-#define VMBUS_PKT_TRAILER 8
-static inline struct vmpacket_descriptor *
-get_next_pkt_raw(struct vmbus_channel *channel)
+/* Get data payload associated with descriptor */
+static inline void *hv_pkt_data(const struct vmpacket_descriptor *desc)
{
- struct hv_ring_buffer_info *ring_info = &channel->inbound;
- u32 priv_read_loc = ring_info->priv_read_index;
- void *ring_buffer = hv_get_ring_buffer(ring_info);
- u32 dsize = ring_info->ring_datasize;
- /*
- * delta is the difference between what is available to read and
- * what was already consumed in place. We commit read index after
- * the whole batch is processed.
- */
- u32 delta = priv_read_loc >= ring_info->ring_buffer->read_index ?
- priv_read_loc - ring_info->ring_buffer->read_index :
- (dsize - ring_info->ring_buffer->read_index) + priv_read_loc;
- u32 bytes_avail_toread = (hv_get_bytes_to_read(ring_info) - delta);
-
- if (bytes_avail_toread < sizeof(struct vmpacket_descriptor))
- return NULL;
-
- return ring_buffer + priv_read_loc;
+ return (void *)((unsigned long)desc + (desc->offset8 << 3));
}
-/*
- * A helper function to step through packets "in-place"
- * This API is to be called after each successful call
- * get_next_pkt_raw().
- */
-static inline void put_pkt_raw(struct vmbus_channel *channel,
- struct vmpacket_descriptor *desc)
+/* Get data size associated with descriptor */
+static inline u32 hv_pkt_datalen(const struct vmpacket_descriptor *desc)
{
- struct hv_ring_buffer_info *ring_info = &channel->inbound;
- u32 packetlen = desc->len8 << 3;
- u32 dsize = ring_info->ring_datasize;
-
- /*
- * Include the packet trailer.
- */
- ring_info->priv_read_index += packetlen + VMBUS_PKT_TRAILER;
- ring_info->priv_read_index %= dsize;
+ return (desc->len8 << 3) - (desc->offset8 << 3);
}
+
+struct vmpacket_descriptor *
+hv_pkt_iter_first(struct vmbus_channel *channel);
+
+struct vmpacket_descriptor *
+__hv_pkt_iter_next(struct vmbus_channel *channel,
+ const struct vmpacket_descriptor *pkt);
+
+void hv_pkt_iter_close(struct vmbus_channel *channel);
+
/*
- * This call commits the read index and potentially signals the host.
- * Here is the pattern for using the "in-place" consumption APIs:
- *
- * init_cached_read_index();
- *
- * while (get_next_pkt_raw() {
- * process the packet "in-place";
- * put_pkt_raw();
- * }
- * if (packets processed in place)
- * commit_rd_index();
+ * Get next packet descriptor from iterator
+ * If at end of list, return NULL and update host.
*/
-static inline void commit_rd_index(struct vmbus_channel *channel)
+static inline struct vmpacket_descriptor *
+hv_pkt_iter_next(struct vmbus_channel *channel,
+ const struct vmpacket_descriptor *pkt)
{
- struct hv_ring_buffer_info *ring_info = &channel->inbound;
- /*
- * Make sure all reads are done before we update the read index since
- * the writer may start writing to the read area once the read index
- * is updated.
- */
- virt_rmb();
- ring_info->ring_buffer->read_index = ring_info->priv_read_index;
+ struct vmpacket_descriptor *nxt;
+
+ nxt = __hv_pkt_iter_next(channel, pkt);
+ if (!nxt)
+ hv_pkt_iter_close(channel);
- hv_signal_on_read(channel);
+ return nxt;
}
+#define foreach_vmbus_pkt(pkt, channel) \
+ for (pkt = hv_pkt_iter_first(channel); pkt; \
+ pkt = hv_pkt_iter_next(channel, pkt))
#endif /* _HYPERV_H */
--
2.13.0

View File

@@ -1,113 +0,0 @@
From 06e8641dae17f95f8358bd6ac206ba5d68c2d31f Mon Sep 17 00:00:00 2001
From: Dexuan Cui <decui@microsoft.com>
Date: Tue, 16 May 2017 22:14:03 +0800
Subject: [PATCH 11/20] hvsock: fix a race in hvs_stream_dequeue()
If hv_pkt_iter_next() returns a non-NULL pointer, we must update
the recv_data_len/data_off info, otherwise the received data will
be silently dropped, and let's fix hvs_stream_has_data() accordingly.
Thank Rolf for finding this!
Reported-by: Rolf Neugebauer <rolf.neugebauer@docker.com>
Signed-off-by: Dexuan Cui <decui@microsoft.com>
Origin: git@github.com:dcui/linux.git
(cherry picked from commit 83c8635b893bbc0b5b329c632cea0382d5479763)
---
net/vmw_vsock/hyperv_transport.c | 50 +++++++++++++++++++++++++++++-----------
1 file changed, 36 insertions(+), 14 deletions(-)
diff --git a/net/vmw_vsock/hyperv_transport.c b/net/vmw_vsock/hyperv_transport.c
index f465b0b662df..30154836acd0 100644
--- a/net/vmw_vsock/hyperv_transport.c
+++ b/net/vmw_vsock/hyperv_transport.c
@@ -476,13 +476,33 @@ static bool hvs_dgram_allow(u32 cid, u32 port)
return false;
}
+static int hvs_update_recv_data(struct hvsock *hvs)
+{
+ struct hvs_recv_buf *recv_buf;
+ u32 payload_len;
+
+ recv_buf = (struct hvs_recv_buf *)(hvs->recv_desc + 1);
+ payload_len = recv_buf->hdr.data_size;
+
+ if (payload_len > HVS_MTU_SIZE)
+ return -EIO;
+
+ if (payload_len == 0)
+ hvs->vsk->peer_shutdown |= SEND_SHUTDOWN;
+
+ hvs->recv_data_len = payload_len;
+ hvs->recv_data_off = 0;
+
+ return 0;
+}
+
static ssize_t hvs_stream_dequeue(struct vsock_sock *vsk, struct msghdr *msg,
size_t len, int flags)
{
struct hvsock *hvs = vsk->trans;
bool need_refill = !hvs->recv_desc;
struct hvs_recv_buf *recv_buf;
- u32 payload_len, to_read;
+ u32 to_read;
int ret;
if (flags & MSG_PEEK)
@@ -490,29 +510,28 @@ static ssize_t hvs_stream_dequeue(struct vsock_sock *vsk, struct msghdr *msg,
if (need_refill) {
hvs->recv_desc = hv_pkt_iter_first(hvs->chan);
- recv_buf = (struct hvs_recv_buf *)(hvs->recv_desc + 1);
-
- payload_len = recv_buf->hdr.data_size;
- if (payload_len == 0 || payload_len > HVS_MTU_SIZE)
- return -EIO;
-
- hvs->recv_data_len = payload_len;
- hvs->recv_data_off = 0;
- } else {
- recv_buf = (struct hvs_recv_buf *)(hvs->recv_desc + 1);
+ ret = hvs_update_recv_data(hvs);
+ if (ret)
+ return ret;
}
+ recv_buf = (struct hvs_recv_buf *)(hvs->recv_desc + 1);
to_read = min_t(u32, len, hvs->recv_data_len);
ret = memcpy_to_msg(msg, recv_buf->data + hvs->recv_data_off, to_read);
if (ret != 0)
return ret;
hvs->recv_data_len -= to_read;
-
- if (hvs->recv_data_len == 0)
+ if (hvs->recv_data_len == 0) {
hvs->recv_desc = hv_pkt_iter_next(hvs->chan, hvs->recv_desc);
- else
+ if (hvs->recv_desc) {
+ ret = hvs_update_recv_data(hvs);
+ if (ret)
+ return ret;
+ }
+ } else {
hvs->recv_data_off += to_read;
+ }
return to_read;
}
@@ -554,6 +573,9 @@ static s64 hvs_stream_has_data(struct vsock_sock *vsk)
struct hvsock *hvs = vsk->trans;
s64 ret;
+ if (hvs->recv_data_len > 0)
+ return 1;
+
switch (hvs_channel_readable_payload(hvs->chan)) {
case 1:
ret = 1;
--
2.13.0

View File

@@ -1,49 +0,0 @@
From b9500355b558a265bcbf1256ed5bda639bec7688 Mon Sep 17 00:00:00 2001
From: Dexuan Cui <decui@microsoft.com>
Date: Fri, 19 May 2017 21:49:59 +0800
Subject: [PATCH 12/20] hvsock: fix vsock_dequeue/enqueue_accept race
Signed-off-by: Dexuan Cui <decui@microsoft.com>
Origin: git@github.com:dcui/linux.git
(cherry picked from commit a2c08e77b8ceb1f146cdc5136e85e7a4c2c9b7cb)
---
net/vmw_vsock/af_vsock.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c
index 6f7f6757ceef..717db396f59e 100644
--- a/net/vmw_vsock/af_vsock.c
+++ b/net/vmw_vsock/af_vsock.c
@@ -126,6 +126,7 @@ static struct proto vsock_proto = {
static const struct vsock_transport *transport;
static DEFINE_MUTEX(vsock_register_mutex);
+static DEFINE_SPINLOCK(vsock_accept_queue_lock);
/**** EXPORTS ****/
@@ -406,7 +407,10 @@ void vsock_enqueue_accept(struct sock *listener, struct sock *connected)
sock_hold(connected);
sock_hold(listener);
+
+ spin_lock(&vsock_accept_queue_lock);
list_add_tail(&vconnected->accept_queue, &vlistener->accept_queue);
+ spin_unlock(&vsock_accept_queue_lock);
}
EXPORT_SYMBOL_GPL(vsock_enqueue_accept);
@@ -423,7 +427,10 @@ static struct sock *vsock_dequeue_accept(struct sock *listener)
vconnected = list_entry(vlistener->accept_queue.next,
struct vsock_sock, accept_queue);
+ spin_lock(&vsock_accept_queue_lock);
list_del_init(&vconnected->accept_queue);
+ spin_unlock(&vsock_accept_queue_lock);
+
sock_put(listener);
/* The caller will need a reference on the connected socket so we let
* it call sock_put().
--
2.13.0

View File

@@ -1,290 +0,0 @@
From a25d315ebedd8a3e18da1db4d95d06ea93136fa6 Mon Sep 17 00:00:00 2001
From: "K. Y. Srinivasan" <kys@microsoft.com>
Date: Sun, 30 Apr 2017 16:21:18 -0700
Subject: [PATCH 13/20] Drivers: hv: vmbus: Fix rescind handling
Fix the rescind handling. This patch addresses the following rescind
scenario that is currently not handled correctly:
If a rescind were to be received while the offer is still being
peocessed, we will be blocked indefinitely since the rescind message
is handled on the same work element as the offer message. Fix this
issue.
I would like to thank Dexuan Cui <decui@microsoft.com> and
Long Li <longli@microsoft.com> for working with me on this patch.
Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Origin: git@github.com:dcui/linux.git
(cherry picked from commit be1ce15dfbdfe3f42c8ed23c5904674d5d90b545)
---
drivers/hv/channel.c | 8 ++++--
drivers/hv/channel_mgmt.c | 69 ++++++++++++++++++++++++++++++++++++-----------
drivers/hv/connection.c | 7 +++--
drivers/hv/hyperv_vmbus.h | 7 +++++
drivers/hv/vmbus_drv.c | 29 +++++++++++++++++++-
5 files changed, 99 insertions(+), 21 deletions(-)
diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c
index f288e506fba0..2dab00019933 100644
--- a/drivers/hv/channel.c
+++ b/drivers/hv/channel.c
@@ -635,9 +635,13 @@ void vmbus_close(struct vmbus_channel *channel)
*/
list_for_each_safe(cur, tmp, &channel->sc_list) {
cur_channel = list_entry(cur, struct vmbus_channel, sc_list);
- if (cur_channel->state != CHANNEL_OPENED_STATE)
- continue;
vmbus_close_internal(cur_channel);
+ if (cur_channel->rescind) {
+ mutex_lock(&vmbus_connection.channel_mutex);
+ hv_process_channel_removal(cur_channel,
+ cur_channel->offermsg.child_relid);
+ mutex_unlock(&vmbus_connection.channel_mutex);
+ }
}
/*
* Now close the primary.
diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c
index c5a01a4d589e..292717d922e0 100644
--- a/drivers/hv/channel_mgmt.c
+++ b/drivers/hv/channel_mgmt.c
@@ -441,7 +441,6 @@ void vmbus_free_channels(void)
{
struct vmbus_channel *channel, *tmp;
- mutex_lock(&vmbus_connection.channel_mutex);
list_for_each_entry_safe(channel, tmp, &vmbus_connection.chn_list,
listentry) {
/* hv_process_channel_removal() needs this */
@@ -449,7 +448,6 @@ void vmbus_free_channels(void)
vmbus_device_unregister(channel->device_obj);
}
- mutex_unlock(&vmbus_connection.channel_mutex);
}
/*
@@ -496,8 +494,10 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel)
list_add_tail(&newchannel->sc_list, &channel->sc_list);
channel->num_sc++;
spin_unlock_irqrestore(&channel->lock, flags);
- } else
+ } else {
+ atomic_dec(&vmbus_connection.offer_in_progress);
goto err_free_chan;
+ }
}
dev_type = hv_get_dev_type(newchannel);
@@ -514,6 +514,7 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel)
if (!fnew) {
if (channel->sc_creation_callback != NULL)
channel->sc_creation_callback(newchannel);
+ atomic_dec(&vmbus_connection.offer_in_progress);
return;
}
@@ -535,9 +536,7 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel)
* binding which eventually invokes the device driver's AddDevice()
* method.
*/
- mutex_lock(&vmbus_connection.channel_mutex);
ret = vmbus_device_register(newchannel->device_obj);
- mutex_unlock(&vmbus_connection.channel_mutex);
if (ret != 0) {
pr_err("unable to add child device object (relid %d)\n",
@@ -545,6 +544,8 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel)
kfree(newchannel->device_obj);
goto err_deq_chan;
}
+
+ atomic_dec(&vmbus_connection.offer_in_progress);
return;
err_deq_chan:
@@ -791,6 +792,7 @@ static void vmbus_onoffer(struct vmbus_channel_message_header *hdr)
newchannel = alloc_channel();
if (!newchannel) {
vmbus_release_relid(offer->child_relid);
+ atomic_dec(&vmbus_connection.offer_in_progress);
pr_err("Unable to allocate channel object\n");
return;
}
@@ -837,16 +839,38 @@ static void vmbus_onoffer_rescind(struct vmbus_channel_message_header *hdr)
rescind = (struct vmbus_channel_rescind_offer *)hdr;
+ /*
+ * The offer msg and the corresponding rescind msg
+ * from the host are guranteed to be ordered -
+ * offer comes in first and then the rescind.
+ * Since we process these events in work elements,
+ * and with preemption, we may end up processing
+ * the events out of order. Given that we handle these
+ * work elements on the same CPU, this is possible only
+ * in the case of preemption. In any case wait here
+ * until the offer processing has moved beyond the
+ * point where the channel is discoverable.
+ */
+
+ while (atomic_read(&vmbus_connection.offer_in_progress) != 0) {
+ /*
+ * We wait here until any channel offer is currently
+ * being processed.
+ */
+ msleep(1);
+ }
+
mutex_lock(&vmbus_connection.channel_mutex);
channel = relid2channel(rescind->child_relid);
+ mutex_unlock(&vmbus_connection.channel_mutex);
if (channel == NULL) {
/*
- * This is very impossible, because in
- * vmbus_process_offer(), we have already invoked
- * vmbus_release_relid() on error.
+ * We failed in processing the offer message;
+ * we would have cleaned up the relid in that
+ * failure path.
*/
- goto out;
+ return;
}
spin_lock_irqsave(&channel->lock, flags);
@@ -858,7 +882,7 @@ static void vmbus_onoffer_rescind(struct vmbus_channel_message_header *hdr)
if (channel->device_obj) {
if (channel->chn_rescind_callback) {
channel->chn_rescind_callback(channel);
- goto out;
+ return;
}
/*
* We will have to unregister this device from the
@@ -869,13 +893,26 @@ static void vmbus_onoffer_rescind(struct vmbus_channel_message_header *hdr)
vmbus_device_unregister(channel->device_obj);
put_device(dev);
}
- } else {
- hv_process_channel_removal(channel,
- channel->offermsg.child_relid);
}
-
-out:
- mutex_unlock(&vmbus_connection.channel_mutex);
+ if (channel->primary_channel != NULL) {
+ /*
+ * Sub-channel is being rescinded. Following is the channel
+ * close sequence when initiated from the driveri (refer to
+ * vmbus_close() for details):
+ * 1. Close all sub-channels first
+ * 2. Then close the primary channel.
+ */
+ if (channel->state == CHANNEL_OPEN_STATE) {
+ /*
+ * The channel is currently not open;
+ * it is safe for us to cleanup the channel.
+ */
+ mutex_lock(&vmbus_connection.channel_mutex);
+ hv_process_channel_removal(channel,
+ channel->offermsg.child_relid);
+ mutex_unlock(&vmbus_connection.channel_mutex);
+ }
+ }
}
void vmbus_hvsock_device_unregister(struct vmbus_channel *channel)
diff --git a/drivers/hv/connection.c b/drivers/hv/connection.c
index a8366fec1458..13e2e148067b 100644
--- a/drivers/hv/connection.c
+++ b/drivers/hv/connection.c
@@ -93,10 +93,13 @@ static int vmbus_negotiate_version(struct vmbus_channel_msginfo *msginfo,
* all the CPUs. This is needed for kexec to work correctly where
* the CPU attempting to connect may not be CPU 0.
*/
- if (version >= VERSION_WIN8_1)
+ if (version >= VERSION_WIN8_1) {
msg->target_vcpu = hv_context.vp_index[smp_processor_id()];
- else
+ vmbus_connection.connect_cpu = smp_processor_id();
+ } else {
msg->target_vcpu = 0;
+ vmbus_connection.connect_cpu = 0;
+ }
/*
* Add to list before we send the request since we may
diff --git a/drivers/hv/hyperv_vmbus.h b/drivers/hv/hyperv_vmbus.h
index 884f83bba1ab..f37921517650 100644
--- a/drivers/hv/hyperv_vmbus.h
+++ b/drivers/hv/hyperv_vmbus.h
@@ -314,6 +314,13 @@ enum vmbus_connect_state {
#define MAX_SIZE_CHANNEL_MESSAGE HV_MESSAGE_PAYLOAD_BYTE_COUNT
struct vmbus_connection {
+ /*
+ * CPU on which the initial host contact was made.
+ */
+ int connect_cpu;
+
+ atomic_t offer_in_progress;
+
enum vmbus_connect_state conn_state;
atomic_t next_gpadl_handle;
diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
index 8370b9dc6037..1024000af956 100644
--- a/drivers/hv/vmbus_drv.c
+++ b/drivers/hv/vmbus_drv.c
@@ -800,8 +800,10 @@ static void vmbus_device_release(struct device *device)
struct hv_device *hv_dev = device_to_hv_device(device);
struct vmbus_channel *channel = hv_dev->channel;
+ mutex_lock(&vmbus_connection.channel_mutex);
hv_process_channel_removal(channel,
channel->offermsg.child_relid);
+ mutex_unlock(&vmbus_connection.channel_mutex);
kfree(hv_dev);
}
@@ -879,7 +881,32 @@ void vmbus_on_msg_dpc(unsigned long data)
INIT_WORK(&ctx->work, vmbus_onmessage_work);
memcpy(&ctx->msg, msg, sizeof(*msg));
- queue_work(vmbus_connection.work_queue, &ctx->work);
+ /*
+ * The host can generate a rescind message while we
+ * may still be handling the original offer. We deal with
+ * this condition by ensuring the processing is done on the
+ * same CPU.
+ */
+ switch (hdr->msgtype) {
+ case CHANNELMSG_RESCIND_CHANNELOFFER:
+ /*
+ * If we are handling the rescind message;
+ * schedule the work on the global work queue.
+ */
+ schedule_work_on(vmbus_connection.connect_cpu,
+ &ctx->work);
+ break;
+
+ case CHANNELMSG_OFFERCHANNEL:
+ atomic_inc(&vmbus_connection.offer_in_progress);
+ queue_work_on(vmbus_connection.connect_cpu,
+ vmbus_connection.work_queue,
+ &ctx->work);
+ break;
+
+ default:
+ queue_work(vmbus_connection.work_queue, &ctx->work);
+ }
} else
entry->message_handler(hdr);
--
2.13.0

View File

@@ -1,246 +0,0 @@
From 5a81156246d3fbb68c671eab68156260f2c58332 Mon Sep 17 00:00:00 2001
From: Dexuan Cui <decui@microsoft.com>
Date: Mon, 5 Jun 2017 16:13:18 +0800
Subject: [PATCH 14/20] vmbus: fix hv_percpu_channel_deq/enq race
Signed-off-by: Dexuan Cui <decui@microsoft.com>
Origin: git@github.com:dcui/linux.git
(cherry picked from commit 8457502df9dd379ddbdfa42a8c9a6421bb3482f1)
---
drivers/hv/channel_mgmt.c | 32 +++++++++++++++++++++----
drivers/hv/connection.c | 11 +++++++++
drivers/hv/hyperv_vmbus.h | 1 +
drivers/hv/vmbus_drv.c | 59 ++++++++++++++++++++++++++++++++++++++++++++---
4 files changed, 95 insertions(+), 8 deletions(-)
diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c
index 292717d922e0..b9a5a15370c9 100644
--- a/drivers/hv/channel_mgmt.c
+++ b/drivers/hv/channel_mgmt.c
@@ -365,11 +365,16 @@ static void percpu_channel_enq(void *arg)
void hv_percpu_channel_enq(struct vmbus_channel *channel)
{
+ unsigned long flags;
+
if (channel->target_cpu != get_cpu())
smp_call_function_single(channel->target_cpu,
percpu_channel_enq, channel, true);
- else
+ else {
+ local_irq_save(flags);
percpu_channel_enq(channel);
+ local_irq_restore(flags);
+ }
put_cpu();
}
@@ -383,11 +388,16 @@ static void percpu_channel_deq(void *arg)
void hv_percpu_channel_deq(struct vmbus_channel *channel)
{
+ unsigned long flags;
+
if (channel->target_cpu != get_cpu())
smp_call_function_single(channel->target_cpu,
percpu_channel_deq, channel, true);
- else
+ else {
+ local_irq_save(flags);
percpu_channel_deq(channel);
+ local_irq_restore(flags);
+ }
put_cpu();
}
@@ -495,7 +505,6 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel)
channel->num_sc++;
spin_unlock_irqrestore(&channel->lock, flags);
} else {
- atomic_dec(&vmbus_connection.offer_in_progress);
goto err_free_chan;
}
}
@@ -549,6 +558,7 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel)
return;
err_deq_chan:
+ atomic_dec(&vmbus_connection.offer_in_progress);
mutex_lock(&vmbus_connection.channel_mutex);
list_del(&newchannel->listentry);
mutex_unlock(&vmbus_connection.channel_mutex);
@@ -915,16 +925,28 @@ static void vmbus_onoffer_rescind(struct vmbus_channel_message_header *hdr)
}
}
+static void vmbus_stop_rescind_handling_work(struct work_struct *work)
+{
+ atomic_inc(&vmbus_connection.offer_in_progress);
+}
+
void vmbus_hvsock_device_unregister(struct vmbus_channel *channel)
{
- mutex_lock(&vmbus_connection.channel_mutex);
+ struct work_struct work;
BUG_ON(!is_hvsock_channel(channel));
+ /* Prevent chn_rescind_callback from running in the rescind path */
+ INIT_WORK(&work, vmbus_stop_rescind_handling_work);
+ queue_work_on(vmbus_connection.connect_cpu,
+ vmbus_connection.work_queue_rescind, &work);
+ flush_work(&work);
+
channel->rescind = true;
vmbus_device_unregister(channel->device_obj);
- mutex_unlock(&vmbus_connection.channel_mutex);
+ /* Unblock the rescind handling */
+ atomic_dec(&vmbus_connection.offer_in_progress);
}
EXPORT_SYMBOL_GPL(vmbus_hvsock_device_unregister);
diff --git a/drivers/hv/connection.c b/drivers/hv/connection.c
index 13e2e148067b..9e4a3d099836 100644
--- a/drivers/hv/connection.c
+++ b/drivers/hv/connection.c
@@ -156,6 +156,12 @@ int vmbus_connect(void)
goto cleanup;
}
+ vmbus_connection.work_queue_rescind = create_workqueue("hv_vmbus_rsd");
+ if (!vmbus_connection.work_queue_rescind) {
+ ret = -ENOMEM;
+ goto cleanup;
+ }
+
INIT_LIST_HEAD(&vmbus_connection.chn_msg_list);
spin_lock_init(&vmbus_connection.channelmsg_lock);
@@ -246,6 +252,11 @@ void vmbus_disconnect(void)
*/
vmbus_initiate_unload(false);
+ if (vmbus_connection.work_queue_rescind) {
+ drain_workqueue(vmbus_connection.work_queue_rescind);
+ destroy_workqueue(vmbus_connection.work_queue_rescind);
+ }
+
if (vmbus_connection.work_queue) {
drain_workqueue(vmbus_connection.work_queue);
destroy_workqueue(vmbus_connection.work_queue);
diff --git a/drivers/hv/hyperv_vmbus.h b/drivers/hv/hyperv_vmbus.h
index f37921517650..23b2bcbd174a 100644
--- a/drivers/hv/hyperv_vmbus.h
+++ b/drivers/hv/hyperv_vmbus.h
@@ -350,6 +350,7 @@ struct vmbus_connection {
struct mutex channel_mutex;
struct workqueue_struct *work_queue;
+ struct workqueue_struct *work_queue_rescind;
};
diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
index 1024000af956..be43e22ecd66 100644
--- a/drivers/hv/vmbus_drv.c
+++ b/drivers/hv/vmbus_drv.c
@@ -839,6 +839,52 @@ static void vmbus_onmessage_work(struct work_struct *work)
kfree(ctx);
}
+static void vmbus_dispatch_msg_work(struct work_struct *work)
+{
+ struct vmbus_channel_message_header *hdr;
+ struct onmessage_work_context *ctx, *context;
+
+ ctx = container_of(work, struct onmessage_work_context, work);
+ hdr = (struct vmbus_channel_message_header *)ctx->msg.u.payload;
+
+ context = kmalloc(sizeof(*context), GFP_KERNEL | __GFP_NOFAIL);
+ INIT_WORK(&context->work, vmbus_onmessage_work);
+ memcpy(&context->msg, &ctx->msg, sizeof(struct hv_message));
+
+ /*
+ * The host can generate a rescind message while we
+ * may still be handling the original offer. We deal with
+ * this condition by ensuring the processing is done on the
+ * same CPU.
+ */
+ switch (hdr->msgtype) {
+ case CHANNELMSG_RESCIND_CHANNELOFFER:
+ /*
+ * If we are handling the rescind message;
+ * schedule the work on the global work queue.
+ */
+ queue_work_on(vmbus_connection.connect_cpu,
+ vmbus_connection.work_queue_rescind,
+ &context->work);
+ break;
+
+ case CHANNELMSG_OFFERCHANNEL:
+ /* XXX */
+ flush_workqueue(vmbus_connection.work_queue_rescind);
+
+ atomic_inc(&vmbus_connection.offer_in_progress);
+ queue_work_on(vmbus_connection.connect_cpu,
+ vmbus_connection.work_queue,
+ &context->work);
+ break;
+
+ default:
+ queue_work(vmbus_connection.work_queue, &context->work);
+ }
+
+ kfree(ctx);
+}
+
static void hv_process_timer_expiration(struct hv_message *msg,
struct hv_per_cpu_context *hv_cpu)
{
@@ -878,9 +924,10 @@ void vmbus_on_msg_dpc(unsigned long data)
if (ctx == NULL)
return;
- INIT_WORK(&ctx->work, vmbus_onmessage_work);
+ INIT_WORK(&ctx->work, vmbus_dispatch_msg_work);
memcpy(&ctx->msg, msg, sizeof(*msg));
+#if 0
/*
* The host can generate a rescind message while we
* may still be handling the original offer. We deal with
@@ -893,8 +940,9 @@ void vmbus_on_msg_dpc(unsigned long data)
* If we are handling the rescind message;
* schedule the work on the global work queue.
*/
- schedule_work_on(vmbus_connection.connect_cpu,
- &ctx->work);
+ queue_work_on(vmbus_connection.connect_cpu,
+ vmbus_connection.work_queue_rescind,
+ &ctx->work);
break;
case CHANNELMSG_OFFERCHANNEL:
@@ -907,6 +955,9 @@ void vmbus_on_msg_dpc(unsigned long data)
default:
queue_work(vmbus_connection.work_queue, &ctx->work);
}
+#else
+ schedule_work(&ctx->work);
+#endif
} else
entry->message_handler(hdr);
@@ -1204,6 +1255,8 @@ int vmbus_device_register(struct hv_device *child_device_obj)
child_device_obj->device.parent = &hv_acpi_dev->dev;
child_device_obj->device.release = vmbus_device_release;
+ if (is_hvsock_channel(child_device_obj->channel))
+ dev_set_uevent_suppress(&child_device_obj->device, 1);
/*
* Register with the LDM. This will kick off the driver/device
* binding...which will eventually call vmbus_match() and vmbus_probe()
--
2.13.0

View File

@@ -1,119 +0,0 @@
From c4a8351a7b13a078bb3a8c9d3c9c9ccbebf6120e Mon Sep 17 00:00:00 2001
From: Dexuan Cui <decui@microsoft.com>
Date: Mon, 5 Jun 2017 21:32:00 +0800
Subject: [PATCH 15/20] vmbus: add vmbus onoffer/onoffer_rescind sync.
Signed-off-by: Dexuan Cui <decui@microsoft.com>
Origin: git@github.com:dcui/linux.git
(cherry picked from commit 1b91aa6d0e745d9765e3d90058928829f0b0bd40)
---
drivers/hv/channel_mgmt.c | 25 +++++++++++++++++++------
drivers/hv/hyperv_vmbus.h | 1 +
drivers/hv/vmbus_drv.c | 1 +
3 files changed, 21 insertions(+), 6 deletions(-)
diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c
index b9a5a15370c9..52c7e811738f 100644
--- a/drivers/hv/channel_mgmt.c
+++ b/drivers/hv/channel_mgmt.c
@@ -467,6 +467,7 @@ void vmbus_free_channels(void)
static void vmbus_process_offer(struct vmbus_channel *newchannel)
{
struct vmbus_channel *channel;
+ struct hv_device *device_obj;
bool fnew = true;
unsigned long flags;
u16 dev_type;
@@ -524,6 +525,7 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel)
if (channel->sc_creation_callback != NULL)
channel->sc_creation_callback(newchannel);
atomic_dec(&vmbus_connection.offer_in_progress);
+ atomic_dec(&vmbus_connection.register_in_progress);
return;
}
@@ -532,33 +534,36 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel)
* We need to set the DeviceObject field before calling
* vmbus_child_dev_add()
*/
- newchannel->device_obj = vmbus_device_create(
+ device_obj = vmbus_device_create(
&newchannel->offermsg.offer.if_type,
&newchannel->offermsg.offer.if_instance,
newchannel);
- if (!newchannel->device_obj)
+ if (!device_obj)
goto err_deq_chan;
- newchannel->device_obj->device_id = dev_type;
+ device_obj->device_id = dev_type;
/*
* Add the new device to the bus. This will kick off device-driver
* binding which eventually invokes the device driver's AddDevice()
* method.
*/
- ret = vmbus_device_register(newchannel->device_obj);
+ atomic_dec(&vmbus_connection.offer_in_progress);
+ ret = vmbus_device_register(device_obj);
if (ret != 0) {
pr_err("unable to add child device object (relid %d)\n",
newchannel->offermsg.child_relid);
- kfree(newchannel->device_obj);
+ kfree(device_obj);
goto err_deq_chan;
}
+ newchannel->device_obj = device_obj;
+ atomic_dec(&vmbus_connection.register_in_progress);
- atomic_dec(&vmbus_connection.offer_in_progress);
return;
err_deq_chan:
atomic_dec(&vmbus_connection.offer_in_progress);
+ atomic_dec(&vmbus_connection.register_in_progress);
mutex_lock(&vmbus_connection.channel_mutex);
list_del(&newchannel->listentry);
mutex_unlock(&vmbus_connection.channel_mutex);
@@ -889,6 +894,14 @@ static void vmbus_onoffer_rescind(struct vmbus_channel_message_header *hdr)
vmbus_rescind_cleanup(channel);
+ while (atomic_read(&vmbus_connection.register_in_progress) != 0) {
+ /*
+ * We wait here until any channel offer is currently
+ * being processed.
+ */
+ msleep(1);
+ }
+
if (channel->device_obj) {
if (channel->chn_rescind_callback) {
channel->chn_rescind_callback(channel);
diff --git a/drivers/hv/hyperv_vmbus.h b/drivers/hv/hyperv_vmbus.h
index 23b2bcbd174a..0d22b842a469 100644
--- a/drivers/hv/hyperv_vmbus.h
+++ b/drivers/hv/hyperv_vmbus.h
@@ -320,6 +320,7 @@ struct vmbus_connection {
int connect_cpu;
atomic_t offer_in_progress;
+ atomic_t register_in_progress;
enum vmbus_connect_state conn_state;
diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
index be43e22ecd66..822daa0936c2 100644
--- a/drivers/hv/vmbus_drv.c
+++ b/drivers/hv/vmbus_drv.c
@@ -873,6 +873,7 @@ static void vmbus_dispatch_msg_work(struct work_struct *work)
flush_workqueue(vmbus_connection.work_queue_rescind);
atomic_inc(&vmbus_connection.offer_in_progress);
+ atomic_inc(&vmbus_connection.register_in_progress);
queue_work_on(vmbus_connection.connect_cpu,
vmbus_connection.work_queue,
&context->work);
--
2.13.0

View File

@@ -1,133 +0,0 @@
From c37cb78a5ceb29847b10914eed0df53434528e12 Mon Sep 17 00:00:00 2001
From: Dexuan Cui <decui@microsoft.com>
Date: Wed, 21 Jun 2017 22:30:42 +0800
Subject: [PATCH 16/20] hv-sock: a temporary workaround for the
pending_send_size issue
While I'm trying to find out the root cause, I believe this can work
as a good temporary workround for internal uses...
Signed-off-by: Dexuan Cui <decui@microsoft.com>
Origin: git@github.com:dcui/linux.git
(cherry picked from commit 531389d1dc73e2be3ee5dbf2091b6f5e74d9764c)
---
net/vmw_vsock/af_vsock.c | 7 +++++--
net/vmw_vsock/hyperv_transport.c | 30 ++++++++++++++++++++++++------
2 files changed, 29 insertions(+), 8 deletions(-)
diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c
index 717db396f59e..7a3fd62ae7c4 100644
--- a/net/vmw_vsock/af_vsock.c
+++ b/net/vmw_vsock/af_vsock.c
@@ -1544,7 +1544,7 @@ static int vsock_stream_sendmsg(struct socket *sock, struct msghdr *msg,
struct sock *sk;
struct vsock_sock *vsk;
ssize_t total_written;
- long timeout;
+ long timeout, timeout_once;
int err;
struct vsock_transport_send_notify_data send_data;
@@ -1615,7 +1615,7 @@ static int vsock_stream_sendmsg(struct socket *sock, struct msghdr *msg,
}
release_sock(sk);
- timeout = schedule_timeout(timeout);
+ timeout_once = schedule_timeout(1);
lock_sock(sk);
if (signal_pending(current)) {
err = sock_intr_errno(timeout);
@@ -1625,6 +1625,9 @@ static int vsock_stream_sendmsg(struct socket *sock, struct msghdr *msg,
err = -EAGAIN;
finish_wait(sk_sleep(sk), &wait);
goto out_err;
+ } else {
+ if (timeout_once == 0)
+ timeout--;
}
prepare_to_wait(sk_sleep(sk), &wait,
diff --git a/net/vmw_vsock/hyperv_transport.c b/net/vmw_vsock/hyperv_transport.c
index 30154836acd0..b8bf1446ae13 100644
--- a/net/vmw_vsock/hyperv_transport.c
+++ b/net/vmw_vsock/hyperv_transport.c
@@ -268,7 +268,7 @@ static void hvs_channel_cb(void *ctx)
sk->sk_data_ready(sk);
/* Mark it writable only if there is enough space */
- if (hvs_channel_writable_bytes(chan) >= HVS_SEND_BUF_SIZE)
+ if (hv_get_bytes_to_write(&chan->outbound) > 0)
sk->sk_write_space(sk);
}
@@ -350,9 +350,11 @@ static void hvs_open_connection(struct vmbus_channel *chan)
set_per_channel_state(chan, conn_from_host ? new : sk);
vmbus_set_chn_rescind_callback(chan, hvs_close_connection);
+#if 0
/* See hvs_channel_cb() and hvs_notify_poll_out() */
set_channel_pending_send_size(chan,
HVS_PKT_LEN(HVS_SEND_BUF_SIZE) + 1);
+#endif
if (conn_from_host) {
new->sk_state = SS_CONNECTED;
@@ -542,7 +544,7 @@ static ssize_t hvs_stream_enqueue(struct vsock_sock *vsk, struct msghdr *msg,
struct hvsock *hvs = vsk->trans;
struct vmbus_channel *chan = hvs->chan;
struct hvs_send_buf *send_buf;
- size_t to_write, max_writable, ret;
+ ssize_t to_write, max_writable, ret;
BUILD_BUG_ON(sizeof(*send_buf) != PAGE_SIZE_4K);
@@ -551,8 +553,8 @@ static ssize_t hvs_stream_enqueue(struct vsock_sock *vsk, struct msghdr *msg,
return -ENOMEM;
max_writable = hvs_channel_writable_bytes(chan);
- to_write = min_t(size_t, len, max_writable);
- to_write = min_t(size_t, to_write, HVS_SEND_BUF_SIZE);
+ to_write = min_t(ssize_t, len, max_writable);
+ to_write = min_t(ssize_t, to_write, HVS_SEND_BUF_SIZE);
ret = memcpy_from_msg(send_buf->data, msg, to_write);
if (ret < 0)
@@ -595,8 +597,22 @@ static s64 hvs_stream_has_data(struct vsock_sock *vsk)
static s64 hvs_stream_has_space(struct vsock_sock *vsk)
{
struct hvsock *hvs = vsk->trans;
+ s64 ret;
- return hvs_channel_writable_bytes(hvs->chan);
+ ret = hvs_channel_writable_bytes(hvs->chan);
+ if (ret > 0) {
+ set_channel_pending_send_size(hvs->chan, 0);
+ } else {
+ /* See hvs_channel_cb() and hvs_notify_poll_out() */
+ set_channel_pending_send_size(hvs->chan,
+ HVS_PKT_LEN(HVS_SEND_BUF_SIZE) + 1);
+
+ ret = hvs_channel_writable_bytes(hvs->chan);
+ if (ret > 0)
+ set_channel_pending_send_size(hvs->chan, 0);
+ }
+
+ return ret;
}
static u64 hvs_stream_rcvhiwat(struct vsock_sock *vsk)
@@ -646,8 +662,10 @@ int hvs_notify_poll_in(struct vsock_sock *vsk, size_t target, bool *readable)
static
int hvs_notify_poll_out(struct vsock_sock *vsk, size_t target, bool *writable)
{
+ struct hvsock *hvs = vsk->trans;
+
/* Report writable only if there is enough space */
- *writable = hvs_stream_has_space(vsk) >= HVS_SEND_BUF_SIZE;
+ *writable = hvs_channel_writable_bytes(hvs->chan) > 0;
return 0;
}
--
2.13.0

View File

@@ -1,41 +0,0 @@
From ffadbd2c58fd82ada7d3722f767256f502f06b67 Mon Sep 17 00:00:00 2001
From: Dexuan Cui <decui@microsoft.com>
Date: Wed, 28 Jun 2017 23:50:38 +0800
Subject: [PATCH 17/20] vmbus: fix the missed signaling in hv_signal_on_read()
There is an off-by-one bug here, which can cause host-to-guest write to stall.
When cur_write_sz == pending_sz, we shouldn't signal the host because it's
meaningless: the ring mustn't be 100% full.
But when cached_write_sz == pending_sz, we must signal the host.
Signed-off-by: John Starks <John.Starks@microsoft.com>
Signed-off-by: Dexuan Cui <decui@microsoft.com>
Origin: git@github.com:dcui/linux.git
(cherry picked from commit c49aced6328557e6c1f5cf6f58e1fae96fb58fa0)
---
include/linux/hyperv.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
index ba93b7e4a972..246bc6baf745 100644
--- a/include/linux/hyperv.h
+++ b/include/linux/hyperv.h
@@ -1501,11 +1501,11 @@ static inline void hv_signal_on_read(struct vmbus_channel *channel)
cur_write_sz = hv_get_bytes_to_write(rbi);
- if (cur_write_sz < pending_sz)
+ if (cur_write_sz <= pending_sz)
return;
cached_write_sz = hv_get_cached_bytes_to_write(rbi);
- if (cached_write_sz < pending_sz)
+ if (cached_write_sz <= pending_sz)
vmbus_setevent(channel);
return;
--
2.13.0

View File

@@ -1,41 +0,0 @@
From 24978998cc7847584de70d51741a314441c2f14f Mon Sep 17 00:00:00 2001
From: Dexuan Cui <decui@microsoft.com>
Date: Fri, 7 Jul 2017 09:15:29 +0800
Subject: [PATCH 18/20] hv-sock: avoid double FINs if shutdown() is called
The host expects a single FIN.
Signed-off-by: Dexuan Cui <decui@microsoft.com>
Origin: git@github.com:dcui/linux.git
(cherry picked from commit 651dae7de6c6f066c08845ec7335bfb231d5eabe)
---
net/vmw_vsock/hyperv_transport.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/net/vmw_vsock/hyperv_transport.c b/net/vmw_vsock/hyperv_transport.c
index b8bf1446ae13..50e4bc822c69 100644
--- a/net/vmw_vsock/hyperv_transport.c
+++ b/net/vmw_vsock/hyperv_transport.c
@@ -95,6 +95,9 @@ struct hvsock {
u32 recv_data_len;
/* The offset of the payload */
u32 recv_data_off;
+
+ /* Have we sent the zero-length packet (FIN)? */
+ unsigned long fin_sent;
};
/* In the VM, we support Hyper-V Sockets with AF_VSOCK, and the endpoint is
@@ -425,6 +428,9 @@ static int hvs_shutdown(struct vsock_sock *vsk, int mode)
hvs = vsk->trans;
+ if (test_and_set_bit(0, &hvs->fin_sent))
+ return 0;
+
send_buf = (struct hvs_send_buf *)&hdr;
/* It can't fail: see hvs_channel_writable_bytes(). */
--
2.13.0

View File

@@ -1,151 +0,0 @@
From 50dd511f73c22341384c355105ebbd775d986fff Mon Sep 17 00:00:00 2001
From: Cheng-mean Liu <soccerl@microsoft.com>
Date: Tue, 11 Jul 2017 16:50:36 -0700
Subject: [PATCH 19/20] Added vsock transport support to 9pfs
Signed-off-by: Cheng-mean Liu <soccerl@microsoft.com>
Origin: https://github.com/Microsoft/opengcs/blob/master/kernelconfig/4.11/patch_9pfs_vsock-transport.patch
---
net/9p/trans_fd.c | 85 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 84 insertions(+), 1 deletion(-)
diff --git a/net/9p/trans_fd.c b/net/9p/trans_fd.c
index 7bc2208b6cc4..dc34352145df 100644
--- a/net/9p/trans_fd.c
+++ b/net/9p/trans_fd.c
@@ -44,8 +44,9 @@
#include <net/9p/9p.h>
#include <net/9p/client.h>
#include <net/9p/transport.h>
-
#include <linux/syscalls.h> /* killme */
+//#include <linux/kgdb.h>
+#include <linux/vm_sockets.h>
#define P9_PORT 564
#define MAX_SOCK_BUF (64*1024)
@@ -155,6 +156,7 @@ struct p9_trans_fd {
struct p9_conn conn;
};
+
static void p9_poll_workfn(struct work_struct *work);
static DEFINE_SPINLOCK(p9_poll_lock);
@@ -740,6 +742,7 @@ static int parse_opts(char *params, struct p9_fd_opts *opts)
opts->wfd = ~0;
opts->privport = 0;
+
if (!params)
return 0;
@@ -1035,6 +1038,72 @@ p9_fd_create(struct p9_client *client, const char *addr, char *args)
return 0;
}
+static int
+p9_fd_create_vsock(struct p9_client *client, const char *addr, char *args)
+{
+ int err;
+ struct socket *csocket;
+ struct sockaddr_vm server_socket_addr;
+ struct p9_fd_opts opts;
+
+ err = parse_opts(args, &opts);
+ if (err < 0)
+ return err;
+
+ csocket = NULL;
+
+ // for debugging purpose only
+ pr_err("%s:%s\n", __func__, addr);
+ // kgdb_breakpoint();
+
+ // create socket
+ err = __sock_create(current->nsproxy->net_ns,
+ AF_VSOCK,
+ SOCK_STREAM,
+ 0,
+ &csocket, 1);
+ if (err) {
+ pr_err("%s:__sock_create (%d): problem creating socket (err=%d)\n",
+ __func__, task_pid_nr(current), err);
+ return err;
+ }
+
+ // server socket address information
+ memset((char *)&server_socket_addr, 0, sizeof(struct sockaddr_vm));
+ server_socket_addr.svm_family = AF_VSOCK;
+ server_socket_addr.svm_reserved1 = 0;
+ server_socket_addr.svm_cid = VMADDR_CID_HOST;
+
+ /* Connecting to the host's 0000pppp-facb-11e6-bd58-64006a7986d3 */
+ server_socket_addr.svm_port = opts.port;
+
+ pr_err("%s:opts.port=(%d)(0x%x)\n", __func__, opts.port, opts.port);
+ pr_err("%s: service_id:(hex) 0000%x%x-facb-11e6-bd58-64006a7986d3\n",
+ __func__,
+ (__u8)((opts.port & 0xff00) >> 8),
+ (__u8)(opts.port & 0x00ff));
+
+ pr_err("%s: connecting", __func__);
+ err = csocket->ops->connect(csocket,
+ (struct sockaddr *)&server_socket_addr,
+ sizeof(struct sockaddr_vm), 0);
+ if (err < 0) {
+ pr_err("%s:connect (%d): problem connecting socket to %s (err = %d)\n",
+ __func__, task_pid_nr(current), addr, err);
+ sock_release(csocket);
+ return err;
+ }
+
+ pr_err("%s: open socket", __func__);
+ err = p9_socket_open(client, csocket);
+ if (err < 0) {
+ pr_err("%s: p9_socket_open failed\n", __func__);
+ }
+
+ pr_err("Leaving %s\n", __func__);
+ return err;
+}
+
static struct p9_trans_module p9_tcp_trans = {
.name = "tcp",
.maxsize = MAX_SOCK_BUF,
@@ -1071,6 +1140,18 @@ static struct p9_trans_module p9_fd_trans = {
.owner = THIS_MODULE,
};
+static struct p9_trans_module p9_vsock_trans = {
+ .name = "vsock",
+ .maxsize = MAX_SOCK_BUF,
+ .def = 0,
+ .create = p9_fd_create_vsock,
+ .close = p9_fd_close,
+ .request = p9_fd_request,
+ .cancel = p9_fd_cancel,
+ .cancelled = p9_fd_cancelled,
+ .owner = THIS_MODULE,
+};
+
/**
* p9_poll_proc - poll worker thread
* @a: thread state and arguments
@@ -1108,6 +1189,7 @@ int p9_trans_fd_init(void)
v9fs_register_trans(&p9_tcp_trans);
v9fs_register_trans(&p9_unix_trans);
v9fs_register_trans(&p9_fd_trans);
+ v9fs_register_trans(&p9_vsock_trans);
return 0;
}
@@ -1118,4 +1200,5 @@ void p9_trans_fd_exit(void)
v9fs_unregister_trans(&p9_tcp_trans);
v9fs_unregister_trans(&p9_unix_trans);
v9fs_unregister_trans(&p9_fd_trans);
+ v9fs_unregister_trans(&p9_vsock_trans);
}
--
2.13.0

View File

@@ -1,28 +0,0 @@
From b3452a81e2e3be6bce0e71da7a87650024358862 Mon Sep 17 00:00:00 2001
From: Cheng-mean Liu <soccerl@microsoft.com>
Date: Tue, 11 Jul 2017 16:58:26 -0700
Subject: [PATCH 20/20] NVDIMM: reducded ND_MIN_NAMESPACE_SIZE from 4MB to 4KB
(page size)
Signed-off-by: Cheng-mean Liu <soccerl@microsoft.com>
Origin: https://github.com/Microsoft/opengcs/blob/master/kernelconfig/4.11/patch_lower-the-minimum-PMEM-size.patch
---
include/uapi/linux/ndctl.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/include/uapi/linux/ndctl.h b/include/uapi/linux/ndctl.h
index ede5c6a62164..47760821c5b5 100644
--- a/include/uapi/linux/ndctl.h
+++ b/include/uapi/linux/ndctl.h
@@ -259,7 +259,7 @@ enum nd_driver_flags {
};
enum {
- ND_MIN_NAMESPACE_SIZE = 0x00400000,
+ ND_MIN_NAMESPACE_SIZE = 0x00001000,
};
enum ars_masks {
--
2.13.0

View File

@@ -1,4 +1,4 @@
From 4ac367a181ff922cde2b8fcf9777ef283d20d1ab Mon Sep 17 00:00:00 2001
From a8262618ffb93ddfc9a31c0fcc18a6418bb09442 Mon Sep 17 00:00:00 2001
From: Stefan Hajnoczi <stefanha@redhat.com>
Date: Thu, 17 Dec 2015 16:53:43 +0800
Subject: [PATCH 01/44] virtio: make find_vqs() checkpatch.pl-friendly

View File

@@ -1,4 +1,4 @@
From cc9f1ba7084a2da776c85d96ac6b932d1b0eec96 Mon Sep 17 00:00:00 2001
From b7b9964016ef38bb1b7417ac1e41bdc7b88d845b Mon Sep 17 00:00:00 2001
From: Julia Lawall <julia.lawall@lip6.fr>
Date: Sat, 21 Nov 2015 18:39:17 +0100
Subject: [PATCH 02/44] VSOCK: constify vmci_transport_notify_ops structures

View File

@@ -1,4 +1,4 @@
From 640770eaa047cca786f9d197f07d0768dc9ad67e Mon Sep 17 00:00:00 2001
From 61393dfb17726f9ea39e866616443d5423ccd551 Mon Sep 17 00:00:00 2001
From: Claudio Imbrenda <imbrenda@linux.vnet.ibm.com>
Date: Tue, 22 Mar 2016 17:05:52 +0100
Subject: [PATCH 03/44] AF_VSOCK: Shrink the area influenced by prepare_to_wait

View File

@@ -1,4 +1,4 @@
From 9ec4f27ca444c9e6ec9d165eb3bfc2cb369deb2f Mon Sep 17 00:00:00 2001
From b0e6543e72880bbd88d53f8773a95fd65b232350 Mon Sep 17 00:00:00 2001
From: Stefan Hajnoczi <stefanha@redhat.com>
Date: Thu, 23 Jun 2016 16:28:58 +0100
Subject: [PATCH 04/44] vsock: make listener child lock ordering explicit

View File

@@ -1,4 +1,4 @@
From 442d54559a617e1423f77d0b5a77c775db90eaa4 Mon Sep 17 00:00:00 2001
From 462af6f438e7c3bff26f5e63a3d8483729e995ff Mon Sep 17 00:00:00 2001
From: Stefan Hajnoczi <stefanha@redhat.com>
Date: Thu, 28 Jul 2016 15:36:30 +0100
Subject: [PATCH 05/44] VSOCK: transport-specific vsock_transport functions

View File

@@ -1,4 +1,4 @@
From 8c63f10477d507fb0de62ea68c72579b0f94bf4b Mon Sep 17 00:00:00 2001
From ec29b99493aa633f18c8b04a4d07583f49b8d794 Mon Sep 17 00:00:00 2001
From: Stefan Hajnoczi <stefanha@redhat.com>
Date: Thu, 28 Jul 2016 15:36:31 +0100
Subject: [PATCH 06/44] VSOCK: defer sock removal to transports

View File

@@ -1,4 +1,4 @@
From 7e97ae305fb6a9bfecf9ea11b7f277acd027437b Mon Sep 17 00:00:00 2001
From 81b74380ad017a68ab76c0bcccec822a223766a0 Mon Sep 17 00:00:00 2001
From: Asias He <asias@redhat.com>
Date: Thu, 28 Jul 2016 15:36:32 +0100
Subject: [PATCH 07/44] VSOCK: Introduce virtio_vsock_common.ko

View File

@@ -1,4 +1,4 @@
From 5977791db4a275aa997a14b69caeef51312811c0 Mon Sep 17 00:00:00 2001
From a23d576bcb843f4abd42b723092ca543e11ec116 Mon Sep 17 00:00:00 2001
From: Asias He <asias@redhat.com>
Date: Thu, 28 Jul 2016 15:36:33 +0100
Subject: [PATCH 08/44] VSOCK: Introduce virtio_transport.ko

View File

@@ -1,4 +1,4 @@
From e8eaefe81e90819725422b190cd7f605f419b639 Mon Sep 17 00:00:00 2001
From 2021cb3e9fc8095b20356eb81ace7c8a95a3c507 Mon Sep 17 00:00:00 2001
From: Asias He <asias@redhat.com>
Date: Thu, 28 Jul 2016 15:36:34 +0100
Subject: [PATCH 09/44] VSOCK: Introduce vhost_vsock.ko

View File

@@ -1,4 +1,4 @@
From ea07f564d0ab66d96254e72547ce47b66b1eff0e Mon Sep 17 00:00:00 2001
From a84199937b74ebac680977557e6db30fff430a7d Mon Sep 17 00:00:00 2001
From: Asias He <asias@redhat.com>
Date: Thu, 28 Jul 2016 15:36:35 +0100
Subject: [PATCH 10/44] VSOCK: Add Makefile and Kconfig

View File

@@ -1,4 +1,4 @@
From 3c6aca1c5a5cdd4d8c5fae142e562cc9d18fed8f Mon Sep 17 00:00:00 2001
From e30c9afcbf64d70886c327a31acca2e92d9cbc9c Mon Sep 17 00:00:00 2001
From: Wei Yongjun <weiyj.lk@gmail.com>
Date: Tue, 2 Aug 2016 13:50:42 +0000
Subject: [PATCH 11/44] VSOCK: Use kvfree()

View File

@@ -1,4 +1,4 @@
From cc9691364a9bd547ff3321df137ac175fbe881fc Mon Sep 17 00:00:00 2001
From 30ffe7877ee1b234ace799892bec752abd9b1778 Mon Sep 17 00:00:00 2001
From: Stefan Hajnoczi <stefanha@redhat.com>
Date: Thu, 4 Aug 2016 14:52:53 +0100
Subject: [PATCH 12/44] vhost/vsock: fix vhost virtio_vsock_pkt use-after-free

View File

@@ -1,4 +1,4 @@
From f20901bb9e7d4ba20ae082aced945ebf59255e86 Mon Sep 17 00:00:00 2001
From 5a9ef4f81a8daaff33291665448fd479c9f25932 Mon Sep 17 00:00:00 2001
From: Stefan Hajnoczi <stefanha@redhat.com>
Date: Fri, 5 Aug 2016 13:52:09 +0100
Subject: [PATCH 13/44] virtio-vsock: fix include guard typo

View File

@@ -1,4 +1,4 @@
From 1b8f610817bb035624c27dfbb94356ddd3b5baa1 Mon Sep 17 00:00:00 2001
From c55296754e43ddcef82429fadad3901344835b76 Mon Sep 17 00:00:00 2001
From: Gerard Garcia <ggarcia@deic.uab.cat>
Date: Wed, 10 Aug 2016 17:24:34 +0200
Subject: [PATCH 14/44] vhost/vsock: drop space available check for TX vq

View File

@@ -1,4 +1,4 @@
From b91ce5fdd93d620b5e89c873d358ff01233347e1 Mon Sep 17 00:00:00 2001
From 1b724918842edde613129a78146792617e0ea397 Mon Sep 17 00:00:00 2001
From: Ian Campbell <ian.campbell@docker.com>
Date: Mon, 4 Apr 2016 14:50:10 +0100
Subject: [PATCH 15/44] VSOCK: Only allow host network namespace to use

View File

@@ -1,4 +1,4 @@
From 42a0a1ca17e1ed49a196457f078f5d0d562c6177 Mon Sep 17 00:00:00 2001
From f421c2802a624f35321db2916bc34e3cafd90c06 Mon Sep 17 00:00:00 2001
From: Jake Oshins <jakeo@microsoft.com>
Date: Mon, 14 Dec 2015 16:01:41 -0800
Subject: [PATCH 16/44] drivers:hv: Define the channel type for Hyper-V PCI

View File

@@ -1,4 +1,4 @@
From a74bccfb3791a6ec84af9ff3ee22620e0eb61b79 Mon Sep 17 00:00:00 2001
From 7fa0a526af7ca35e84330cd68850829cf03138b6 Mon Sep 17 00:00:00 2001
From: "K. Y. Srinivasan" <kys@microsoft.com>
Date: Mon, 14 Dec 2015 16:01:43 -0800
Subject: [PATCH 17/44] Drivers: hv: vmbus: Use uuid_le type consistently

View File

@@ -1,4 +1,4 @@
From 8eef71c96ad05e14a207d58e0e16b5181efcc9a7 Mon Sep 17 00:00:00 2001
From 175d708f36661f78494db427c398ce0d3e10d18c Mon Sep 17 00:00:00 2001
From: "K. Y. Srinivasan" <kys@microsoft.com>
Date: Mon, 14 Dec 2015 16:01:44 -0800
Subject: [PATCH 18/44] Drivers: hv: vmbus: Use uuid_le_cmp() for comparing

View File

@@ -1,4 +1,4 @@
From 6a7340526afa83da9fcaea781c5f4457c6748689 Mon Sep 17 00:00:00 2001
From 52b22bfa0e8a815659391a8461aab63e56d44f51 Mon Sep 17 00:00:00 2001
From: Dexuan Cui <decui@microsoft.com>
Date: Mon, 14 Dec 2015 16:01:48 -0800
Subject: [PATCH 19/44] Drivers: hv: vmbus: do sanity check of channel state in

View File

@@ -1,4 +1,4 @@
From e282bb6e3b5be332ebe9178386e3027df97d3891 Mon Sep 17 00:00:00 2001
From 114beaac74c6041e091987056d9a45fa2927b394 Mon Sep 17 00:00:00 2001
From: Dexuan Cui <decui@microsoft.com>
Date: Mon, 14 Dec 2015 16:01:50 -0800
Subject: [PATCH 20/44] Drivers: hv: vmbus: release relid on error in

View File

@@ -1,4 +1,4 @@
From 0d97416c675c36cd374b510cac1cbcc0138fa6f2 Mon Sep 17 00:00:00 2001
From 8074afce2d2b36aa70caf4f7a918ecea049d2ee5 Mon Sep 17 00:00:00 2001
From: Dexuan Cui <decui@microsoft.com>
Date: Mon, 14 Dec 2015 16:01:51 -0800
Subject: [PATCH 21/44] Drivers: hv: vmbus: channge

View File

@@ -1,4 +1,4 @@
From a46cccadda1f6e28211efcfe44788ed5d919f54f Mon Sep 17 00:00:00 2001
From 1ac4b2082c105b696887eda48d162c4ab9a4a0fe Mon Sep 17 00:00:00 2001
From: Vitaly Kuznetsov <vkuznets@redhat.com>
Date: Mon, 14 Dec 2015 19:02:00 -0800
Subject: [PATCH 22/44] Drivers: hv: remove code duplication between

View File

@@ -1,4 +1,4 @@
From b479c088909f96621976b0c664e9da941734fb59 Mon Sep 17 00:00:00 2001
From e6249932fe52287f2fff1e1711bebb16a0d1566d Mon Sep 17 00:00:00 2001
From: Dexuan Cui <decui@microsoft.com>
Date: Mon, 21 Dec 2015 12:21:22 -0800
Subject: [PATCH 23/44] Drivers: hv: vmbus: fix the building warning with

View File

@@ -1,4 +1,4 @@
From 1d07474bec008bbac993a5a3d7dfe67ae86ac0a3 Mon Sep 17 00:00:00 2001
From 81b67af158a293cffff2f8718253ea35e99fafce Mon Sep 17 00:00:00 2001
From: "K. Y. Srinivasan" <kys@microsoft.com>
Date: Tue, 15 Dec 2015 16:27:27 -0800
Subject: [PATCH 24/44] Drivers: hv: vmbus: Treat Fibre Channel devices as

View File

@@ -1,4 +1,4 @@
From c13b93c734b47bcc5e50e6bdd685a8a73275e2e5 Mon Sep 17 00:00:00 2001
From 5982b4583c0def309a86b8cc903d398504bceffa Mon Sep 17 00:00:00 2001
From: "K. Y. Srinivasan" <kys@microsoft.com>
Date: Fri, 25 Dec 2015 20:00:30 -0800
Subject: [PATCH 25/44] Drivers: hv: vmbus: Add vendor and device atttributes

View File

@@ -1,4 +1,4 @@
From bbb5cc56af647bed0c6dac2f11ece5401d0a2e3a Mon Sep 17 00:00:00 2001
From 6f189bbd2d5a1c710f6bf85d17b1602dc5a1cb51 Mon Sep 17 00:00:00 2001
From: Dexuan Cui <decui@microsoft.com>
Date: Wed, 27 Jan 2016 22:29:37 -0800
Subject: [PATCH 26/44] Drivers: hv: vmbus: add a helper function to set a

View File

@@ -1,4 +1,4 @@
From 332ee8dc89152134ccd2c7eae06a0dc13821205c Mon Sep 17 00:00:00 2001
From 4d70af363fc983efdcf618710bcc6f3225c81c74 Mon Sep 17 00:00:00 2001
From: Dexuan Cui <decui@microsoft.com>
Date: Wed, 27 Jan 2016 22:29:38 -0800
Subject: [PATCH 27/44] Drivers: hv: vmbus: define the new offer type for

View File

@@ -1,4 +1,4 @@
From e8dc54b09565790a6ee0c21c53a3b1756261c437 Mon Sep 17 00:00:00 2001
From 5dde03cba293b7ff88bfbfa8fc0dafd75086cb8a Mon Sep 17 00:00:00 2001
From: Dexuan Cui <decui@microsoft.com>
Date: Wed, 27 Jan 2016 22:29:39 -0800
Subject: [PATCH 28/44] Drivers: hv: vmbus: vmbus_sendpacket_ctl: hvsock: avoid

View File

@@ -1,4 +1,4 @@
From df742cbadcad1e5adcc447c923cddd841d1c8faf Mon Sep 17 00:00:00 2001
From c3df3af43f85c3266d6b64ff846ad4d88b1d1057 Mon Sep 17 00:00:00 2001
From: Dexuan Cui <decui@microsoft.com>
Date: Wed, 27 Jan 2016 22:29:40 -0800
Subject: [PATCH 29/44] Drivers: hv: vmbus: define a new VMBus message type for

View File

@@ -1,4 +1,4 @@
From 4724c559cf0e5d1c82356e059a7d9b58559c37ff Mon Sep 17 00:00:00 2001
From b44626bff30e94557101c43c885a2e55f2d78fec Mon Sep 17 00:00:00 2001
From: Dexuan Cui <decui@microsoft.com>
Date: Wed, 27 Jan 2016 22:29:41 -0800
Subject: [PATCH 30/44] Drivers: hv: vmbus: add a hvsock flag in struct

View File

@@ -1,4 +1,4 @@
From 476fc7c2424506110f138ca0a1846a2d53abbdea Mon Sep 17 00:00:00 2001
From d71980eca1f0bbd48d04c7b03d0a1be00733b041 Mon Sep 17 00:00:00 2001
From: Dexuan Cui <decui@microsoft.com>
Date: Wed, 27 Jan 2016 22:29:42 -0800
Subject: [PATCH 31/44] Drivers: hv: vmbus: add a per-channel rescind callback

View File

@@ -1,4 +1,4 @@
From 9a44c2e4c6bf43133b3b0720ce03788f241a6687 Mon Sep 17 00:00:00 2001
From 34d89b9d1939346dc3310c4bf52327c679f8016f Mon Sep 17 00:00:00 2001
From: Dexuan Cui <decui@microsoft.com>
Date: Wed, 27 Jan 2016 22:29:43 -0800
Subject: [PATCH 32/44] Drivers: hv: vmbus: add an API

View File

@@ -1,4 +1,4 @@
From 700f83603f2b35a799797f9f538b2796c00d132e Mon Sep 17 00:00:00 2001
From 5fb78acabe811cc07a3621b0934aaf22114e5271 Mon Sep 17 00:00:00 2001
From: "K. Y. Srinivasan" <kys@microsoft.com>
Date: Wed, 27 Jan 2016 22:29:45 -0800
Subject: [PATCH 33/44] Drivers: hv: vmbus: Give control over how the ring

View File

@@ -1,4 +1,4 @@
From aa8592e8828e686184098a8f47a3e035528062ac Mon Sep 17 00:00:00 2001
From e472566d8ac7b0fc7de35b2cd63e1d5763073586 Mon Sep 17 00:00:00 2001
From: Vitaly Kuznetsov <vkuznets@redhat.com>
Date: Fri, 26 Feb 2016 15:13:16 -0800
Subject: [PATCH 34/44] Drivers: hv: vmbus: avoid wait_for_completion() on

View File

@@ -1,4 +1,4 @@
From 285a023864b8ca507229d44b0324c46ac811e019 Mon Sep 17 00:00:00 2001
From 712870ab4806a0d234e89f934d7e85fd08481431 Mon Sep 17 00:00:00 2001
From: Vitaly Kuznetsov <vkuznets@redhat.com>
Date: Fri, 26 Feb 2016 15:13:18 -0800
Subject: [PATCH 35/44] Drivers: hv: vmbus: avoid unneeded compiler

View File

@@ -1,4 +1,4 @@
From 07d32add1034937896be713083c10c00365a338a Mon Sep 17 00:00:00 2001
From 34a5094cbc81e2eb954d9388d24c37c4217a432e Mon Sep 17 00:00:00 2001
From: Tom Herbert <tom@herbertland.com>
Date: Mon, 7 Mar 2016 14:11:06 -0800
Subject: [PATCH 36/44] kcm: Kernel Connection Multiplexor module

View File

@@ -1,4 +1,4 @@
From 120cdcd571fbae88b4f2069f0730b8815e9608ce Mon Sep 17 00:00:00 2001
From 4ed0a8cd7d1245d4579ccba60828d5adbc13edc9 Mon Sep 17 00:00:00 2001
From: Dexuan Cui <decui@microsoft.com>
Date: Mon, 21 Mar 2016 02:51:09 -0700
Subject: [PATCH 37/44] net: add the AF_KCM entries to family name tables

View File

@@ -1,4 +1,4 @@
From 414524da056efb9ad3941c004d839c7744f917a8 Mon Sep 17 00:00:00 2001
From e55c6e1fc2c82587cf01a20dc2c8e6b1de675371 Mon Sep 17 00:00:00 2001
From: Courtney Cavin <courtney.cavin@sonymobile.com>
Date: Wed, 27 Apr 2016 12:13:03 -0700
Subject: [PATCH 38/44] net: Add Qualcomm IPC router

View File

@@ -1,4 +1,4 @@
From 11a83ef09e103b830dcb978dfccded4cc9772a79 Mon Sep 17 00:00:00 2001
From e203cb08b2dee0a6a19872a7a4ab8eee5d41ae7e Mon Sep 17 00:00:00 2001
From: Dexuan Cui <decui@microsoft.com>
Date: Sun, 15 May 2016 09:53:11 -0700
Subject: [PATCH 39/44] hv_sock: introduce Hyper-V Sockets

View File

@@ -1,4 +1,4 @@
From 74b2d25f22b1e81a95223255ad28f4522d3ebb96 Mon Sep 17 00:00:00 2001
From 9921cf1b2ceae6040664dacfcf76c3e60b9545a0 Mon Sep 17 00:00:00 2001
From: Dexuan Cui <decui@microsoft.com>
Date: Mon, 21 Mar 2016 02:53:08 -0700
Subject: [PATCH 40/44] net: add the AF_HYPERV entries to family name tables

View File

@@ -1,4 +1,4 @@
From e3f96f5db36343c6436af78a533dbbe249e65c6b Mon Sep 17 00:00:00 2001
From 11809ac04aff8b5f09b031c0754179d4a1d9821f Mon Sep 17 00:00:00 2001
From: Dexuan Cui <decui@microsoft.com>
Date: Sat, 21 May 2016 16:55:50 +0800
Subject: [PATCH 41/44] Drivers: hv: vmbus: fix the race when querying &

View File

@@ -1,4 +1,4 @@
From dc04c8b54a7af915e0d91bdd0b26aa7469e35213 Mon Sep 17 00:00:00 2001
From af58f93c1817ef3224ad97a36fcf5253f655c1cd Mon Sep 17 00:00:00 2001
From: Rolf Neugebauer <rolf.neugebauer@gmail.com>
Date: Mon, 23 May 2016 18:55:45 +0100
Subject: [PATCH 42/44] vmbus: Don't spam the logs with unknown GUIDs

View File

@@ -1,4 +1,4 @@
From 3288cdc152f465a53e8851d3f04cf61feceb7a6b Mon Sep 17 00:00:00 2001
From 710468214f017884a3877d9b6857d953abbf65f9 Mon Sep 17 00:00:00 2001
From: James Bottomley <James.Bottomley@HansenPartnership.com>
Date: Wed, 17 Feb 2016 16:49:38 -0800
Subject: [PATCH 43/44] fs: add filp_clone_open API

View File

@@ -1,4 +1,4 @@
From 74ffff76b3ef41ea6fff355f93f41740a62f3369 Mon Sep 17 00:00:00 2001
From 26b1f600e37c1450f27a5f84bc46eae91a7d4123 Mon Sep 17 00:00:00 2001
From: James Bottomley <James.Bottomley@HansenPartnership.com>
Date: Wed, 17 Feb 2016 16:51:16 -0800
Subject: [PATCH 44/44] binfmt_misc: add persistent opened binary handler for

View File

@@ -1,4 +1,4 @@
From 4ae703e17e07a95332a6e0ad5806e17f25daf78f Mon Sep 17 00:00:00 2001
From 927f144eea8aef2a4b135e2bc75cc926d2860ded Mon Sep 17 00:00:00 2001
From: Arnaldo Carvalho de Melo <acme@redhat.com>
Date: Thu, 2 Mar 2017 12:55:49 -0300
Subject: [PATCH 01/13] tools build: Add test for sched_getcpu()

View File

@@ -1,4 +1,4 @@
From 5e6d4f7cb9880aa8466ff98e56690bd13fd54df6 Mon Sep 17 00:00:00 2001
From 0b92a0b9372018ea1aa31ab21a5cc38999e3c044 Mon Sep 17 00:00:00 2001
From: Arnaldo Carvalho de Melo <acme@redhat.com>
Date: Thu, 13 Oct 2016 17:12:35 -0300
Subject: [PATCH 02/13] perf jit: Avoid returning garbage for a ret variable

View File

@@ -1,4 +1,4 @@
From dd53a1fc57f6a549aeb50dae4b4567690a16c120 Mon Sep 17 00:00:00 2001
From 5f1affbf0c0a56d8ca8f3eebf9cef5dc7666653f Mon Sep 17 00:00:00 2001
From: Dexuan Cui <decui@microsoft.com>
Date: Sat, 23 Jul 2016 01:35:51 +0000
Subject: [PATCH 03/13] hv_sock: introduce Hyper-V Sockets

View File

@@ -1,4 +1,4 @@
From b85149ae2f7a39acd91f8847bfc5a7a188681681 Mon Sep 17 00:00:00 2001
From 4c2129f12714d828d4f08c206eec55ca95d2aee6 Mon Sep 17 00:00:00 2001
From: Rolf Neugebauer <rolf.neugebauer@gmail.com>
Date: Mon, 23 May 2016 18:55:45 +0100
Subject: [PATCH 04/13] vmbus: Don't spam the logs with unknown GUIDs

View File

@@ -1,4 +1,4 @@
From f6107bf72b7891d10d1d56bdf5316bfd91c177dc Mon Sep 17 00:00:00 2001
From eeb4f66a6a96395a0c8a5697f4d07ca5d7bdc790 Mon Sep 17 00:00:00 2001
From: Alex Ng <alexng@messages.microsoft.com>
Date: Sun, 6 Nov 2016 13:14:07 -0800
Subject: [PATCH 05/13] Drivers: hv: utils: Fix the mapping between host

View File

@@ -1,4 +1,4 @@
From b1fa05201756d5ce898c4ec183737041284624c7 Mon Sep 17 00:00:00 2001
From d1743ac42c72e802d489ce3a0a0ecb7f6e4da6c8 Mon Sep 17 00:00:00 2001
From: Alex Ng <alexng@messages.microsoft.com>
Date: Sun, 6 Nov 2016 13:14:10 -0800
Subject: [PATCH 06/13] Drivers: hv: vss: Improve log messages.

View File

@@ -1,4 +1,4 @@
From 1b1406809c1c2fdac0cb1fd2d85400dee09f2887 Mon Sep 17 00:00:00 2001
From 80e748520b93c668c7765f444c4eba74a9b9d82a Mon Sep 17 00:00:00 2001
From: Alex Ng <alexng@messages.microsoft.com>
Date: Sun, 6 Nov 2016 13:14:11 -0800
Subject: [PATCH 07/13] Drivers: hv: vss: Operation timeouts should match host

View File

@@ -1,4 +1,4 @@
From 66955115f0d8764a93c4ec9291d917d4a8be3e8f Mon Sep 17 00:00:00 2001
From 4791ec941b0f98858a7168cc07f845e12a1d1d32 Mon Sep 17 00:00:00 2001
From: Alex Ng <alexng@messages.microsoft.com>
Date: Sat, 28 Jan 2017 12:37:17 -0700
Subject: [PATCH 08/13] Drivers: hv: vmbus: Use all supported IC versions to

View File

@@ -1,4 +1,4 @@
From c6ad5884453c734b343c608ea8a504743549d836 Mon Sep 17 00:00:00 2001
From 0915eada2751cd773bacdf5d9fd20bbd66e2b795 Mon Sep 17 00:00:00 2001
From: Alex Ng <alexng@messages.microsoft.com>
Date: Sat, 28 Jan 2017 12:37:18 -0700
Subject: [PATCH 09/13] Drivers: hv: Log the negotiated IC versions.

View File

@@ -1,4 +1,4 @@
From eb533e334d182ea553c138576788771e55f0f484 Mon Sep 17 00:00:00 2001
From b4b729fd7ba75c2d6eca85a912e7808a1e8dde56 Mon Sep 17 00:00:00 2001
From: Dexuan Cui <decui@microsoft.com>
Date: Sun, 26 Mar 2017 16:42:20 +0800
Subject: [PATCH 10/13] vmbus: fix missed ring events on boot

View File

@@ -1,4 +1,4 @@
From 830ea2549499b58f3b49e304d84f79c1f377883e Mon Sep 17 00:00:00 2001
From 4506b21a50f4c006c239d29b78b9fbb286e44f91 Mon Sep 17 00:00:00 2001
From: Dexuan Cui <decui@microsoft.com>
Date: Wed, 29 Mar 2017 18:37:10 +0800
Subject: [PATCH 11/13] vmbus: remove "goto error_clean_msglist" in

View File

@@ -1,4 +1,4 @@
From 958ee135863de8865c62920bdff7bbea4199bf44 Mon Sep 17 00:00:00 2001
From 519aaaf7dca397866f9a0a78a681bb7ef0e40c58 Mon Sep 17 00:00:00 2001
From: Dexuan Cui <decui@microsoft.com>
Date: Fri, 24 Mar 2017 20:53:18 +0800
Subject: [PATCH 12/13] vmbus: dynamically enqueue/dequeue the channel on

View File

@@ -1,4 +1,4 @@
From 34b5cdf37eacf3a82a9f47d8728c13acc11baed7 Mon Sep 17 00:00:00 2001
From 81ea7047d239760c4445d0c2a0abed3fe7fe1925 Mon Sep 17 00:00:00 2001
From: Dexuan Cui <decui@microsoft.com>
Date: Thu, 6 Jul 2017 21:37:11 +0000
Subject: [PATCH 13/13] vmbus: fix the missed signaling in hv_signal_on_read()

View File

@@ -1,5 +1,5 @@
kernel:
image: linuxkit/kernel:4.9.39
image: linuxkit/kernel:4.9.40
cmdline: "console=tty0 console=ttyS0"
init:
- linuxkit/init:4dcee04c04c900a5796dc719f8d16fea7e771059

View File

@@ -1,5 +1,5 @@
kernel:
image: linuxkit/kernel:4.9.39
image: linuxkit/kernel:4.9.40
cmdline: "console=ttyS0 page_poison=1"
init:
- linuxkit/init:4dcee04c04c900a5796dc719f8d16fea7e771059

Some files were not shown because too many files have changed in this diff Show More