Home Home > GIT Browse
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHannes Reinecke <hare@suse.de>2015-04-30 13:15:16 +0200
committerHannes Reinecke <hare@suse.de>2015-04-30 13:15:16 +0200
commitc86eb37868b984771fb99ee68d52af103c8539eb (patch)
tree8206d91983a2935a61afdc842097fe5ccf6a9741
parent6a838b13bbb1290d46b51a4f3a4032e60b6a725c (diff)
parentd4f05af2af8e36c1aefb7c52bf201a2f8bacbd87 (diff)
Merge branch 'SLE11-SP4' of kerncvs.suse.de:/home/git/kernel-source into SLE11-SP4rpm-3.0.101-58
-rw-r--r--patches.suse/msft-hv-0742-hyperv-Implement-netvsc_get_channels-ethool-op.patch101
-rw-r--r--patches.suse/msft-hv-0743-Drivers-hv-vmbus-prevent-cpu-offlining-on-newer-hype.patch96
-rw-r--r--patches.suse/msft-hv-0744-Drivers-hv-vmbus-rename-channel-work-queues.patch81
-rw-r--r--patches.suse/msft-hv-0745-Drivers-hv-vmbus-avoid-double-kfree-for-device_obj.patch48
-rw-r--r--patches.suse/msft-hv-0746-Drivers-hv-vmbus-teardown-hv_vmbus_con-workqueue-and.patch125
-rw-r--r--patches.suse/msft-hv-0747-drivers-hv-vmbus-Teardown-synthetic-interrupt-contro.patch93
-rw-r--r--patches.suse/msft-hv-0748-Drivers-hv-vmbus-Teardown-clockevent-devices-on-modu.patch106
-rw-r--r--patches.suse/msft-hv-0749-hv-hv_util-move-vmbus_open-to-a-later-place.patch53
-rw-r--r--patches.suse/msft-hv-0750-hv-vmbus_post_msg-retry-the-hypercall-on-some-transi.patch73
-rw-r--r--patches.suse/msft-hv-0751-hv-vmbus_open-reset-the-channel-state-on-ENOMEM.patch47
-rw-r--r--patches.suse/msft-hv-0752-hv-channel-match-var-type-to-return-type-of-wait_for.patch32
-rw-r--r--patches.suse/msft-hv-0753-hv-channel_mgmt-match-var-type-to-return-type-of-wai.patch32
-rw-r--r--patches.suse/msft-hv-0754-hv-hv_balloon-match-var-type-to-return-type-of-wait_.patch32
-rw-r--r--patches.suse/msft-hv-0755-Drivers-hv-vmbus-Fix-a-bug-in-the-error-path-in-vmbu.patch50
-rw-r--r--patches.suse/msft-hv-0756-Drivers-hv-vmbus-Add-support-for-the-NetworkDirect-G.patch52
-rw-r--r--patches.suse/msft-hv-0757-Drivers-hv-vmbus-Properly-handle-child-device-remove.patch45
-rw-r--r--patches.suse/msft-hv-0758-Drivers-hv-vmbus-Introduce-a-function-to-remove-a-re.patch157
-rw-r--r--patches.suse/msft-hv-0759-Drivers-hv-vmbus-Handle-both-rescind-and-offer-messa.patch192
-rw-r--r--patches.suse/msft-hv-0760-Drivers-hv-vmbus-Remove-the-channel-from-the-channel.patch60
-rw-r--r--patches.suse/msft-hv-0761-Drivers-hv-util-On-device-remove-close-the-channel-a.patch32
-rw-r--r--patches.suse/msft-hv-0762-Drivers-hv-vmbus-Get-rid-of-some-unnecessary-message.patch46
-rw-r--r--patches.suse/msft-hv-0763-Drivers-hv-hv_balloon-eliminate-the-trylock-path-in-.patch142
-rw-r--r--patches.suse/msft-hv-0764-Drivers-hv-hv_balloon-report-offline-pages-as-being-.patch104
-rw-r--r--patches.suse/msft-hv-0765-Drivers-hv-hv_balloon-refuse-to-balloon-below-the-fl.patch48
-rw-r--r--patches.suse/msft-hv-0766-Drivers-hv-vmbus-Add-support-for-VMBus-panic-notifie.patch113
-rw-r--r--patches.suse/msft-hv-0767-Drivers-hv-vmbus-Use-a-round-robin-algorithm-for-pic.patch101
-rw-r--r--patches.suse/msft-hv-0768-Drivers-hv-vmbus-Suport-an-API-to-send-pagebuffers-w.patch104
-rw-r--r--patches.suse/msft-hv-0769-Drivers-hv-vmbus-Suport-an-API-to-send-packet-with-a.patch104
-rw-r--r--patches.suse/msft-hv-0770-mei-bus-can-be-static.patch32
-rw-r--r--patches.suse/msft-hv-0771-hyperv-hyperv_fb-match-wait_for_completion_timeout-r.patch42
-rw-r--r--patches.suse/msft-hv-0772-Drivers-hv-vmbus-Perform-device-register-in-the-per-.patch281
-rw-r--r--patches.suse/msft-hv-0773-Drivers-hv-hv_balloon-keep-locks-balanced-on-add_mem.patch45
-rw-r--r--patches.suse/msft-hv-0774-Drivers-hv-hv_balloon-don-t-lose-memory-when-onlinin.patch132
-rw-r--r--patches.suse/msft-hv-0775-Drivers-hv-vmbus-Correcting-truncation-error-for-con.patch51
-rw-r--r--patches.suse/msft-hv-0776-hv-vmbus-missing-curly-braces-in-vmbus_process_offer.patch39
-rw-r--r--patches.suse/msft-hv-0778-Drivers-hv-vmbus-Fix-a-bug-in-rescind-processing-in-.patch56
-rw-r--r--patches.suse/msft-hv-0779-hv-hypervvssd-call-endmntent-before-call-setmntent-a.patch61
-rw-r--r--patches.suse/msft-hv-0780-Drivers-hv-vmbus-Export-the-vmbus_sendpacket_pagebuf.patch29
-rw-r--r--patches.suse/msft-hv-0781-Drivers-hv-vmbus-Fix-a-siganlling-host-signalling-is.patch65
-rw-r--r--patches.suse/msft-hv-0782-Drivers-hv-vmbus-Don-t-wait-after-requesting-offers.patch54
-rw-r--r--patches.suse/msft-hv-0784-hv_netvsc-remove-vmbus_are_subchannels_present-in-rn.patch31
-rw-r--r--patches.suse/msft-hv-0785-hv_netvsc-Cleanup-the-test-for-freeing-skb-when-we-u.patch47
-rw-r--r--patches.suse/msft-hv-0787-hv-run-non-blocking-message-handlers-in-the-dispatch.patch166
-rw-r--r--patches.suse/msft-hv-0788-hv-don-t-schedule-new-works-in-vmbus_onoffer-vmbus_o.patch295
-rw-r--r--patches.suse/msft-hv-0789-hv-remove-the-per-channel-workqueue.patch90
-rw-r--r--patches.suse/msft-hv-0790-Drivers-hv-hv_balloon-do-not-online-pages-in-offline.patch51
-rw-r--r--patches.suse/msft-hv-0791-Drivers-hv-hv_balloon-eliminate-jumps-in-piecewiese-.patch57
-rw-r--r--patches.suse/msft-hv-0792-Drivers-hv-hv_balloon-survive-ballooning-request-wit.patch123
-rw-r--r--patches.suse/msft-hv-0793-hv_vmbus-Add-gradually-increased-delay-for-retries-i.patch54
-rw-r--r--patches.suse/msft-hv-0794-Drivers-hv-hv_balloon-correctly-handle-val.freeram-n.patch39
-rw-r--r--patches.suse/msft-hv-0795-Drivers-hv-hv_balloon-correctly-handle-num_pages-INT.patch58
-rw-r--r--patches.suse/suse-hv-module-unload.patch52
-rw-r--r--series.conf53
53 files changed, 4272 insertions, 0 deletions
diff --git a/patches.suse/msft-hv-0742-hyperv-Implement-netvsc_get_channels-ethool-op.patch b/patches.suse/msft-hv-0742-hyperv-Implement-netvsc_get_channels-ethool-op.patch
new file mode 100644
index 0000000000..5b7473d510
--- /dev/null
+++ b/patches.suse/msft-hv-0742-hyperv-Implement-netvsc_get_channels-ethool-op.patch
@@ -0,0 +1,101 @@
+From: Andrew Schwartzmeyer <andrew@schwartzmeyer.com>
+Date: Thu, 26 Feb 2015 16:27:14 -0800
+Patch-mainline: v4.1-rc1
+Subject: hyperv: Implement netvsc_get_channels() ethool op
+Git-commit: 59995370dbca7636c105ddadc0447fab86ad3887
+References: fate#317533
+
+This adds support for reporting the actual and maximum combined channels
+count of the hv_netvsc driver via 'ethtool --show-channels'.
+
+This required adding 'max_chn' to 'struct netvsc_device', and assigning
+it 'rsscap.num_recv_que' in 'rndis_filter_device_add'. Now we can access
+the combined maximum channel count via 'struct netvsc_device' in the
+ethtool callback.
+
+Signed-off-by: Andrew Schwartzmeyer <andrew@schwartzmeyer.com>
+Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Acked-by: <ohering@suse.de>
+---
+ drivers/net/hyperv/hyperv_net.h | 1 +
+ drivers/net/hyperv/netvsc_drv.c | 14 ++++++++++++++
+ drivers/net/hyperv/rndis_filter.c | 6 +++++-
+ 3 files changed, 20 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h
+index 384ca4f..4815843 100644
+--- a/drivers/net/hyperv/hyperv_net.h
++++ b/drivers/net/hyperv/hyperv_net.h
+@@ -634,6 +634,7 @@ struct netvsc_device {
+
+ struct vmbus_channel *chn_table[NR_CPUS];
+ u32 send_table[VRSS_SEND_TAB_SIZE];
++ u32 max_chn;
+ u32 num_chn;
+ atomic_t queue_sends[NR_CPUS];
+
+diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
+index 15d82ed..a06bd66 100644
+--- a/drivers/net/hyperv/netvsc_drv.c
++++ b/drivers/net/hyperv/netvsc_drv.c
+@@ -687,6 +687,19 @@ static void netvsc_get_drvinfo(struct net_device *net,
+ strcpy(info->fw_version, "N/A");
+ }
+
++static void netvsc_get_channels(struct net_device *net,
++ struct ethtool_channels *channel)
++{
++ struct net_device_context *net_device_ctx = netdev_priv(net);
++ struct hv_device *dev = net_device_ctx->device_ctx;
++ struct netvsc_device *nvdev = hv_get_drvdata(dev);
++
++ if (nvdev) {
++ channel->max_combined = nvdev->max_chn;
++ channel->combined_count = nvdev->num_chn;
++ }
++}
++
+ static int netvsc_change_mtu(struct net_device *ndev, int mtu)
+ {
+ struct net_device_context *ndevctx = netdev_priv(ndev);
+@@ -760,6 +773,7 @@ static void netvsc_poll_controller(struct net_device *net)
+ static const struct ethtool_ops ethtool_ops = {
+ .get_drvinfo = netvsc_get_drvinfo,
+ .get_link = ethtool_op_get_link,
++ .get_channels = netvsc_get_channels,
+ };
+
+ static const struct net_device_ops device_ops = {
+diff --git a/drivers/net/hyperv/rndis_filter.c b/drivers/net/hyperv/rndis_filter.c
+index 7816d98..ca81de0 100644
+--- a/drivers/net/hyperv/rndis_filter.c
++++ b/drivers/net/hyperv/rndis_filter.c
+@@ -1027,6 +1027,7 @@ int rndis_filter_device_add(struct hv_device *dev,
+
+ /* Initialize the rndis device */
+ net_device = hv_get_drvdata(dev);
++ net_device->max_chn = 1;
+ net_device->num_chn = 1;
+
+ net_device->extension = rndis_device;
+@@ -1094,6 +1095,7 @@ int rndis_filter_device_add(struct hv_device *dev,
+ if (ret || rsscap.num_recv_que < 2)
+ goto out;
+
++ net_device->max_chn = rsscap.num_recv_que;
+ net_device->num_chn = (num_online_cpus() < rsscap.num_recv_que) ?
+ num_online_cpus() : rsscap.num_recv_que;
+ if (net_device->num_chn == 1)
+@@ -1140,8 +1142,10 @@ int rndis_filter_device_add(struct hv_device *dev,
+ ret = rndis_filter_set_rss_param(rndis_device, net_device->num_chn);
+
+ out:
+- if (ret)
++ if (ret) {
++ net_device->max_chn = 1;
+ net_device->num_chn = 1;
++ }
+ return 0; /* return 0 because primary channel can be used alone */
+
+ err_dev_remv:
diff --git a/patches.suse/msft-hv-0743-Drivers-hv-vmbus-prevent-cpu-offlining-on-newer-hype.patch b/patches.suse/msft-hv-0743-Drivers-hv-vmbus-prevent-cpu-offlining-on-newer-hype.patch
new file mode 100644
index 0000000000..c2cb55f1c1
--- /dev/null
+++ b/patches.suse/msft-hv-0743-Drivers-hv-vmbus-prevent-cpu-offlining-on-newer-hype.patch
@@ -0,0 +1,96 @@
+From: Vitaly Kuznetsov <vkuznets@redhat.com>
+Date: Fri, 27 Feb 2015 11:25:51 -0800
+Patch-mainline: v4.1-rc1
+Subject: Drivers: hv: vmbus: prevent cpu offlining on newer hypervisors
+Git-commit: e513229b4c386e6c9f66298c13fde92f73e6e1ac
+References: fate#317533
+
+When an SMP Hyper-V guest is running on top of 2012R2 Server and secondary
+cpus are sent offline (with echo 0 > /sys/devices/system/cpu/cpu$cpu/online)
+the system freeze is observed. This happens due to the fact that on newer
+hypervisors (Win8, WS2012R2, ...) vmbus channel handlers are distributed
+across all cpus (see init_vp_index() function in drivers/hv/channel_mgmt.c)
+and on cpu offlining nobody reassigns them to CPU0. Prevent cpu offlining
+when vmbus is loaded until the issue is fixed host-side.
+
+This patch also disables hibernation but it is OK as it is also broken (MCE
+error is hit on resume). Suspend still works.
+
+Tested with WS2008R2 and WS2012R2.
+
+Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
+Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Acked-by: <ohering@suse.de>
+---
+ drivers/hv/vmbus_drv.c | 36 ++++++++++++++++++++++++++++++++++++
+ 1 file changed, 36 insertions(+)
+
+diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
+index f518b8d7..3b18a66 100644
+--- a/drivers/hv/vmbus_drv.c
++++ b/drivers/hv/vmbus_drv.c
+@@ -33,6 +33,7 @@
+ #include <linux/hyperv.h>
+ #include <linux/kernel_stat.h>
+ #include <linux/clockchips.h>
++#include <linux/cpu.h>
+ #include <asm/hyperv.h>
+ #include <asm/hypervisor.h>
+ #include <asm/mshyperv.h>
+@@ -704,6 +705,39 @@ static void vmbus_isr(void)
+ desc->action->handler(irq, desc->action->dev_id);
+ }
+
++#ifdef CONFIG_HOTPLUG_CPU
++static int hyperv_cpu_disable(void)
++{
++ return -ENOSYS;
++}
++
++static void hv_cpu_hotplug_quirk(bool vmbus_loaded)
++{
++ static void *previous_cpu_disable;
++
++ /*
++ * Offlining a CPU when running on newer hypervisors (WS2012R2, Win8,
++ * ...) is not supported at this moment as channel interrupts are
++ * distributed across all of them.
++ */
++
++ if ((vmbus_proto_version == VERSION_WS2008) ||
++ (vmbus_proto_version == VERSION_WIN7))
++ return;
++
++ if (vmbus_loaded) {
++ previous_cpu_disable = smp_ops.cpu_disable;
++ smp_ops.cpu_disable = hyperv_cpu_disable;
++ pr_notice("CPU offlining is not supported by hypervisor\n");
++ } else if (previous_cpu_disable)
++ smp_ops.cpu_disable = previous_cpu_disable;
++}
++#else
++static void hv_cpu_hotplug_quirk(bool vmbus_loaded)
++{
++}
++#endif
++
+ /*
+ * vmbus_bus_init -Main vmbus driver initialization routine.
+ *
+@@ -744,6 +778,7 @@ static int vmbus_bus_init(int irq)
+ if (ret)
+ goto err_alloc;
+
++ hv_cpu_hotplug_quirk(true);
+ vmbus_request_offers();
+
+ return 0;
+@@ -997,6 +1032,7 @@ static void __exit vmbus_exit(void)
+ bus_unregister(&hv_bus);
+ hv_cleanup();
+ acpi_bus_unregister_driver(&vmbus_acpi_driver);
++ hv_cpu_hotplug_quirk(false);
+ }
+
+
diff --git a/patches.suse/msft-hv-0744-Drivers-hv-vmbus-rename-channel-work-queues.patch b/patches.suse/msft-hv-0744-Drivers-hv-vmbus-rename-channel-work-queues.patch
new file mode 100644
index 0000000000..c276610076
--- /dev/null
+++ b/patches.suse/msft-hv-0744-Drivers-hv-vmbus-rename-channel-work-queues.patch
@@ -0,0 +1,81 @@
+From: Vitaly Kuznetsov <vkuznets@redhat.com>
+Date: Fri, 27 Feb 2015 11:25:52 -0800
+Patch-mainline: v4.1-rc1
+Subject: Drivers: hv: vmbus: rename channel work queues
+Git-commit: bc63b6f634d91a0b2a7f3ba4f266e55fec369de3
+References: fate#317533
+
+All channel work queues are named 'hv_vmbus_ctl', this makes them
+indistinguishable in ps output and makes it hard to link to the corresponding
+vmbus device. Rename them to hv_vmbus_ctl/N and make vmbus device names match,
+e.g. now vmbus_1 device is served by hv_vmbus_ctl/1 work queue.
+
+Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
+Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Acked-by: <ohering@suse.de>
+---
+ drivers/hv/channel_mgmt.c | 5 ++++-
+ drivers/hv/vmbus_drv.c | 6 ++----
+ include/linux/hyperv.h | 3 +++
+ 3 files changed, 9 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c
+index 3736f71..ba4b25f 100644
+--- a/drivers/hv/channel_mgmt.c
++++ b/drivers/hv/channel_mgmt.c
+@@ -139,19 +139,22 @@ EXPORT_SYMBOL_GPL(vmbus_prep_negotiate_resp);
+ */
+ static struct vmbus_channel *alloc_channel(void)
+ {
++ static atomic_t chan_num = ATOMIC_INIT(0);
+ struct vmbus_channel *channel;
+
+ channel = kzalloc(sizeof(*channel), GFP_ATOMIC);
+ if (!channel)
+ return NULL;
+
++ channel->id = atomic_inc_return(&chan_num);
+ spin_lock_init(&channel->inbound_lock);
+ spin_lock_init(&channel->lock);
+
+ INIT_LIST_HEAD(&channel->sc_list);
+ INIT_LIST_HEAD(&channel->percpu_list);
+
+- channel->controlwq = create_workqueue("hv_vmbus_ctl");
++ channel->controlwq = alloc_workqueue("hv_vmbus_ctl/%d", WQ_MEM_RECLAIM,
++ 1, channel->id);
+ if (!channel->controlwq) {
+ kfree(channel);
+ return NULL;
+diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
+index 3b18a66..e334ccc 100644
+--- a/drivers/hv/vmbus_drv.c
++++ b/drivers/hv/vmbus_drv.c
+@@ -875,10 +875,8 @@ int vmbus_device_register(struct hv_device *child_device_obj)
+ {
+ int ret = 0;
+
+- static atomic_t device_num = ATOMIC_INIT(0);
+-
+- dev_set_name(&child_device_obj->device, "vmbus_0_%d",
+- atomic_inc_return(&device_num));
++ dev_set_name(&child_device_obj->device, "vmbus_%d",
++ child_device_obj->channel->id);
+
+ child_device_obj->device.bus = &hv_bus;
+ child_device_obj->device.parent = &hv_acpi_dev->dev;
+diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
+index 5a2ba67..26a32b7 100644
+--- a/include/linux/hyperv.h
++++ b/include/linux/hyperv.h
+@@ -646,6 +646,9 @@ struct hv_input_signal_event_buffer {
+ };
+
+ struct vmbus_channel {
++ /* Unique channel id */
++ int id;
++
+ struct list_head listentry;
+
+ struct hv_device *device_obj;
diff --git a/patches.suse/msft-hv-0745-Drivers-hv-vmbus-avoid-double-kfree-for-device_obj.patch b/patches.suse/msft-hv-0745-Drivers-hv-vmbus-avoid-double-kfree-for-device_obj.patch
new file mode 100644
index 0000000000..fb3d8b0e53
--- /dev/null
+++ b/patches.suse/msft-hv-0745-Drivers-hv-vmbus-avoid-double-kfree-for-device_obj.patch
@@ -0,0 +1,48 @@
+From: Vitaly Kuznetsov <vkuznets@redhat.com>
+Date: Fri, 27 Feb 2015 11:25:53 -0800
+Patch-mainline: v4.1-rc1
+Subject: Drivers: hv: vmbus: avoid double kfree for device_obj
+Git-commit: adcde069a85cb6674bdcf5f49f434d18b2db6e58
+References: fate#317533
+
+On driver shutdown device_obj is being freed twice:
+1) In vmbus_free_channels()
+2) vmbus_device_release() (which is being triggered by device_unregister() in
+ vmbus_device_unregister().
+This double kfree leads to the following sporadic crash on driver unload:
+
+[ 23.469876] general protection fault: 0000 [#1] SMP
+[ 23.470036] Modules linked in: hv_vmbus(-)
+[ 23.470036] CPU: 2 PID: 213 Comm: rmmod Not tainted 3.19.0-rc5_bug923184+ #488
+[ 23.470036] Hardware name: Microsoft Corporation Virtual Machine/Virtual Machine, BIOS 090006 05/23/2012
+[ 23.470036] task: ffff880036ef1cb0 ti: ffff880036ce8000 task.ti: ffff880036ce8000
+[ 23.470036] RIP: 0010:[<ffffffff811d2e1b>] [<ffffffff811d2e1b>] __kmalloc_node_track_caller+0xdb/0x1e0
+[ 23.470036] RSP: 0018:ffff880036cebcc8 EFLAGS: 00010246
+...
+
+When this crash does not happen on driver unload the similar one is expected if
+we try to load hv_vmbus again.
+
+Remove kfree from vmbus_free_channels() as freeing it from
+vmbus_device_release() seems right.
+
+Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
+Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Acked-by: <ohering@suse.de>
+---
+ drivers/hv/channel_mgmt.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c
+index ba4b25f..36bacc7 100644
+--- a/drivers/hv/channel_mgmt.c
++++ b/drivers/hv/channel_mgmt.c
+@@ -262,7 +262,6 @@ void vmbus_free_channels(void)
+
+ list_for_each_entry(channel, &vmbus_connection.chn_list, listentry) {
+ vmbus_device_unregister(channel->device_obj);
+- kfree(channel->device_obj);
+ free_channel(channel);
+ }
+ }
diff --git a/patches.suse/msft-hv-0746-Drivers-hv-vmbus-teardown-hv_vmbus_con-workqueue-and.patch b/patches.suse/msft-hv-0746-Drivers-hv-vmbus-teardown-hv_vmbus_con-workqueue-and.patch
new file mode 100644
index 0000000000..1247eded21
--- /dev/null
+++ b/patches.suse/msft-hv-0746-Drivers-hv-vmbus-teardown-hv_vmbus_con-workqueue-and.patch
@@ -0,0 +1,125 @@
+From: Vitaly Kuznetsov <vkuznets@redhat.com>
+Date: Fri, 27 Feb 2015 11:25:54 -0800
+Patch-mainline: v4.1-rc1
+Subject: Drivers: hv: vmbus: teardown hv_vmbus_con workqueue and vmbus_connection pages on shutdown
+Git-commit: 09a196288ec4617a920e051af6651ce03968c8b9
+References: fate#317533
+
+We need to destroy hv_vmbus_con on module shutdown, otherwise the following
+crash is sometimes observed:
+
+[ 76.569845] hv_vmbus: Hyper-V Host Build:9600-6.3-17-0.17039; Vmbus version:3.0
+[ 82.598859] BUG: unable to handle kernel paging request at ffffffffa0003480
+[ 82.599287] IP: [<ffffffffa0003480>] 0xffffffffa0003480
+[ 82.599287] PGD 1f34067 PUD 1f35063 PMD 3f72d067 PTE 0
+[ 82.599287] Oops: 0010 [#1] SMP
+[ 82.599287] Modules linked in: [last unloaded: hv_vmbus]
+[ 82.599287] CPU: 0 PID: 26 Comm: kworker/0:1 Not tainted 3.19.0-rc5_bug923184+ #488
+[ 82.599287] Hardware name: Microsoft Corporation Virtual Machine/Virtual Machine, BIOS Hyper-V UEFI Release v1.0 11/26/2012
+[ 82.599287] Workqueue: hv_vmbus_con 0xffffffffa0003480
+[ 82.599287] task: ffff88007b6ddfa0 ti: ffff88007f8f8000 task.ti: ffff88007f8f8000
+[ 82.599287] RIP: 0010:[<ffffffffa0003480>] [<ffffffffa0003480>] 0xffffffffa0003480
+[ 82.599287] RSP: 0018:ffff88007f8fbe00 EFLAGS: 00010202
+...
+
+To avoid memory leaks we need to free monitor_pages and int_page for
+vmbus_connection. Implement vmbus_disconnect() function by separating cleanup
+path from vmbus_connect().
+
+As we use hv_vmbus_con to release channels (see free_channel() in channel_mgmt.c)
+we need to make sure the work was done before we remove the queue, do that with
+drain_workqueue(). We also need to avoid handling messages which can (potentially)
+create new channels, so set vmbus_connection.conn_state = DISCONNECTED at the very
+beginning of vmbus_exit() and check for that in vmbus_onmessage_work().
+
+Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
+Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Acked-by: <ohering@suse.de>
+---
+ drivers/hv/connection.c | 17 ++++++++++++-----
+ drivers/hv/hyperv_vmbus.h | 1 +
+ drivers/hv/vmbus_drv.c | 6 ++++++
+ 3 files changed, 19 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/hv/connection.c b/drivers/hv/connection.c
+index a63a795..c4acd1c 100644
+--- a/drivers/hv/connection.c
++++ b/drivers/hv/connection.c
+@@ -216,10 +216,21 @@ int vmbus_connect(void)
+
+ cleanup:
+ pr_err("Unable to connect to host\n");
++
+ vmbus_connection.conn_state = DISCONNECTED;
++ vmbus_disconnect();
++
++ kfree(msginfo);
++
++ return ret;
++}
+
+- if (vmbus_connection.work_queue)
++void vmbus_disconnect(void)
++{
++ if (vmbus_connection.work_queue) {
++ drain_workqueue(vmbus_connection.work_queue);
+ destroy_workqueue(vmbus_connection.work_queue);
++ }
+
+ if (vmbus_connection.int_page) {
+ free_pages((unsigned long)vmbus_connection.int_page, 0);
+@@ -230,10 +241,6 @@ cleanup:
+ free_pages((unsigned long)vmbus_connection.monitor_pages[1], 0);
+ vmbus_connection.monitor_pages[0] = NULL;
+ vmbus_connection.monitor_pages[1] = NULL;
+-
+- kfree(msginfo);
+-
+- return ret;
+ }
+
+ /*
+diff --git a/drivers/hv/hyperv_vmbus.h b/drivers/hv/hyperv_vmbus.h
+index 44b1c94..6cf2de9 100644
+--- a/drivers/hv/hyperv_vmbus.h
++++ b/drivers/hv/hyperv_vmbus.h
+@@ -692,6 +692,7 @@ void vmbus_free_channels(void);
+ /* Connection interface */
+
+ int vmbus_connect(void);
++void vmbus_disconnect(void);
+
+ int vmbus_post_msg(void *buffer, size_t buflen);
+
+diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
+index e334ccc..76db97d 100644
+--- a/drivers/hv/vmbus_drv.c
++++ b/drivers/hv/vmbus_drv.c
+@@ -574,6 +574,10 @@ static void vmbus_onmessage_work(struct work_struct *work)
+ {
+ struct onmessage_work_context *ctx;
+
++ /* Do not process messages if we're in DISCONNECTED state */
++ if (vmbus_connection.conn_state == DISCONNECTED)
++ return;
++
+ ctx = container_of(work, struct onmessage_work_context,
+ work);
+ vmbus_onmessage(&ctx->msg);
+@@ -897,13 +901,14 @@ cleanup:
+
+ static void __exit vmbus_exit(void)
+ {
+-
++ vmbus_connection.conn_state = DISCONNECTED;
+ free_irq(irq, hv_acpi_dev);
+ vmbus_free_channels();
+ bus_unregister(&hv_bus);
+ hv_cleanup();
+ acpi_bus_unregister_driver(&vmbus_acpi_driver);
+ hv_cpu_hotplug_quirk(false);
++ vmbus_disconnect();
+ }
+
+
diff --git a/patches.suse/msft-hv-0747-drivers-hv-vmbus-Teardown-synthetic-interrupt-contro.patch b/patches.suse/msft-hv-0747-drivers-hv-vmbus-Teardown-synthetic-interrupt-contro.patch
new file mode 100644
index 0000000000..cdad0e006c
--- /dev/null
+++ b/patches.suse/msft-hv-0747-drivers-hv-vmbus-Teardown-synthetic-interrupt-contro.patch
@@ -0,0 +1,93 @@
+From: Vitaly Kuznetsov <vkuznets@redhat.com>
+Date: Fri, 27 Feb 2015 11:25:55 -0800
+Patch-mainline: v4.1-rc1
+Subject: drivers: hv: vmbus: Teardown synthetic interrupt controllers on module unload
+Git-commit: e72e7ac583ee8adddbc668cdefde7d7d3021be79
+References: fate#317533
+
+SynIC has to be switched off when we unload the module, otherwise registered
+memory pages can get corrupted after (as Hyper-V host still writes there) and
+we see the following crashes for random processes:
+
+[ 89.116774] BUG: Bad page map in process sh pte:4989c716 pmd:36f81067
+[ 89.159454] addr:0000000000437000 vm_flags:00000875 anon_vma: (null) mapping:ffff88007bba55a0 index:37
+[ 89.226146] vma->vm_ops->fault: filemap_fault+0x0/0x410
+[ 89.257776] vma->vm_file->f_op->mmap: generic_file_mmap+0x0/0x60
+[ 89.297570] CPU: 0 PID: 215 Comm: sh Tainted: G B 3.19.0-rc5_bug923184+ #488
+[ 89.353738] Hardware name: Microsoft Corporation Virtual Machine/Virtual Machine, BIOS 090006 05/23/2012
+[ 89.409138] 0000000000000000 000000004e083d7b ffff880036e9fa18 ffffffff81a68d31
+[ 89.468724] 0000000000000000 0000000000437000 ffff880036e9fa68 ffffffff811a1e3a
+[ 89.519233] 000000004989c716 0000000000000037 ffffea0001edc340 0000000000437000
+[ 89.575751] Call Trace:
+[ 89.591060] [<ffffffff81a68d31>] dump_stack+0x45/0x57
+[ 89.625164] [<ffffffff811a1e3a>] print_bad_pte+0x1aa/0x250
+[ 89.667234] [<ffffffff811a2c95>] vm_normal_page+0x55/0xa0
+[ 89.703818] [<ffffffff811a3105>] unmap_page_range+0x425/0x8a0
+[ 89.737982] [<ffffffff811a3601>] unmap_single_vma+0x81/0xf0
+[ 89.780385] [<ffffffff81184320>] ? lru_deactivate_fn+0x190/0x190
+[ 89.820130] [<ffffffff811a4131>] unmap_vmas+0x51/0xa0
+[ 89.860168] [<ffffffff811ad12c>] exit_mmap+0xac/0x1a0
+[ 89.890588] [<ffffffff810763c3>] mmput+0x63/0x100
+[ 89.919205] [<ffffffff811eba48>] flush_old_exec+0x3f8/0x8b0
+[ 89.962135] [<ffffffff8123b5bb>] load_elf_binary+0x32b/0x1260
+[ 89.998581] [<ffffffff811a14f2>] ? get_user_pages+0x52/0x60
+
+hv_synic_cleanup() function exists but noone calls it now. Do the following:
+- call hv_synic_cleanup() on each cpu from vmbus_exit();
+- write global disable bit through MSR;
+- use hv_synic_free_cpu() to avoid memory leask and code duplication.
+
+Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
+Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Acked-by: <ohering@suse.de>
+---
+ drivers/hv/hv.c | 9 +++++++--
+ drivers/hv/vmbus_drv.c | 4 ++++
+ 2 files changed, 11 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/hv/hv.c b/drivers/hv/hv.c
+index 50e51a5..39531dc 100644
+--- a/drivers/hv/hv.c
++++ b/drivers/hv/hv.c
+@@ -477,6 +477,7 @@ void hv_synic_cleanup(void *arg)
+ union hv_synic_sint shared_sint;
+ union hv_synic_simp simp;
+ union hv_synic_siefp siefp;
++ union hv_synic_scontrol sctrl;
+ int cpu = smp_processor_id();
+
+ if (!hv_context.synic_initialized)
+@@ -502,6 +503,10 @@ void hv_synic_cleanup(void *arg)
+
+ wrmsrl(HV_X64_MSR_SIEFP, siefp.as_uint64);
+
+- free_page((unsigned long)hv_context.synic_message_page[cpu]);
+- free_page((unsigned long)hv_context.synic_event_page[cpu]);
++ /* Disable the global synic bit */
++ rdmsrl(HV_X64_MSR_SCONTROL, sctrl.as_uint64);
++ sctrl.enable = 0;
++ wrmsrl(HV_X64_MSR_SCONTROL, sctrl.as_uint64);
++
++ hv_synic_free_cpu(cpu);
+ }
+diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
+index 76db97d..d8233d4 100644
+--- a/drivers/hv/vmbus_drv.c
++++ b/drivers/hv/vmbus_drv.c
+@@ -1029,11 +1029,15 @@ cleanup:
+
+ static void __exit vmbus_exit(void)
+ {
++ int cpu;
++
+ vmbus_connection.conn_state = DISCONNECTED;
+ free_irq(irq, hv_acpi_dev);
+ vmbus_free_channels();
+ bus_unregister(&hv_bus);
+ hv_cleanup();
++ for_each_online_cpu(cpu)
++ smp_call_function_single(cpu, hv_synic_cleanup, NULL, 1);
+ acpi_bus_unregister_driver(&vmbus_acpi_driver);
+ hv_cpu_hotplug_quirk(false);
+ vmbus_disconnect();
diff --git a/patches.suse/msft-hv-0748-Drivers-hv-vmbus-Teardown-clockevent-devices-on-modu.patch b/patches.suse/msft-hv-0748-Drivers-hv-vmbus-Teardown-clockevent-devices-on-modu.patch
new file mode 100644
index 0000000000..f0fd58ed0f
--- /dev/null
+++ b/patches.suse/msft-hv-0748-Drivers-hv-vmbus-Teardown-clockevent-devices-on-modu.patch
@@ -0,0 +1,106 @@
+From: Vitaly Kuznetsov <vkuznets@redhat.com>
+Date: Fri, 27 Feb 2015 11:25:57 -0800
+Patch-mainline: v4.1-rc1
+Subject: Drivers: hv: vmbus: Teardown clockevent devices on module unload
+Git-commit: e086748c655ab99bac91b87d1bb59d9cc45867b9
+References: fate#317533
+
+Newly introduced clockevent devices made it impossible to unload hv_vmbus
+module as clockevents_config_and_register() takes additional reverence to
+the module. To make it possible again we do the following:
+- avoid setting dev->owner for clockevent devices;
+- implement hv_synic_clockevents_cleanup() doing clockevents_unbind_device();
+- call it from vmbus_exit().
+
+In theory hv_synic_clockevents_cleanup() can be merged with hv_synic_cleanup(),
+however, we call hv_synic_cleanup() from smp_call_function_single() and this
+doesn't work for clockevents_unbind_device() as it does such call on its own. I
+opted for a separate function.
+
+Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
+Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Acked-by: <ohering@suse.de>
+---
+ drivers/hv/hv.c | 25 ++++++++++++++++++++++++-
+ drivers/hv/hyperv_vmbus.h | 2 ++
+ drivers/hv/vmbus_drv.c | 1 +
+ 3 files changed, 27 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/hv/hv.c b/drivers/hv/hv.c
+index 39531dc..d3943bc 100644
+--- a/drivers/hv/hv.c
++++ b/drivers/hv/hv.c
+@@ -312,7 +312,11 @@ static void hv_init_clockevent_device(struct clock_event_device *dev, int cpu)
+ dev->features = CLOCK_EVT_FEAT_ONESHOT;
+ dev->cpumask = cpumask_of(cpu);
+ dev->rating = 1000;
+- /* dev->owner = THIS_MODULE; */
++ /*
++ * Avoid settint dev->owner = THIS_MODULE deliberately as doing so will
++ * result in clockevents_config_and_register() taking additional
++ * references to the hv_vmbus module making it impossible to unload.
++ */
+
+ dev->set_mode = hv_ce_setmode;
+ dev->set_next_event = hv_ce_set_next_event;
+@@ -470,6 +474,22 @@ void hv_synic_init(void *arg)
+ }
+
+ /*
++ * hv_synic_clockevents_cleanup - Cleanup clockevent devices
++ */
++void hv_synic_clockevents_cleanup(void)
++{
++#if 0
++ int cpu;
++
++ if (!(ms_hyperv.features & HV_X64_MSR_SYNTIMER_AVAILABLE))
++ return;
++
++ for_each_online_cpu(cpu)
++ clockevents_unbind_device(hv_context.clk_evt[cpu], cpu);
++#endif
++}
++
++/*
+ * hv_synic_cleanup - Cleanup routine for hv_synic_init().
+ */
+ void hv_synic_cleanup(void *arg)
+@@ -483,6 +501,11 @@ void hv_synic_cleanup(void *arg)
+ if (!hv_context.synic_initialized)
+ return;
+
++ /* Turn off clockevent device */
++ if (ms_hyperv.features & HV_X64_MSR_SYNTIMER_AVAILABLE)
++ hv_ce_setmode(CLOCK_EVT_MODE_SHUTDOWN,
++ hv_context.clk_evt[cpu]);
++
+ rdmsrl(HV_X64_MSR_SINT0 + VMBUS_MESSAGE_SINT, shared_sint.as_uint64);
+
+ shared_sint.masked = 1;
+diff --git a/drivers/hv/hyperv_vmbus.h b/drivers/hv/hyperv_vmbus.h
+index 6cf2de9..b055e53 100644
+--- a/drivers/hv/hyperv_vmbus.h
++++ b/drivers/hv/hyperv_vmbus.h
+@@ -572,6 +572,8 @@ extern void hv_synic_init(void *irqarg);
+
+ extern void hv_synic_cleanup(void *arg);
+
++extern void hv_synic_clockevents_cleanup(void);
++
+ /*
+ * Host version information.
+ */
+diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
+index d8233d4..6d99aa5 100644
+--- a/drivers/hv/vmbus_drv.c
++++ b/drivers/hv/vmbus_drv.c
+@@ -1032,6 +1032,7 @@ static void __exit vmbus_exit(void)
+ int cpu;
+
+ vmbus_connection.conn_state = DISCONNECTED;
++ hv_synic_clockevents_cleanup();
+ free_irq(irq, hv_acpi_dev);
+ vmbus_free_channels();
+ bus_unregister(&hv_bus);
diff --git a/patches.suse/msft-hv-0749-hv-hv_util-move-vmbus_open-to-a-later-place.patch b/patches.suse/msft-hv-0749-hv-hv_util-move-vmbus_open-to-a-later-place.patch
new file mode 100644
index 0000000000..06676030f1
--- /dev/null
+++ b/patches.suse/msft-hv-0749-hv-hv_util-move-vmbus_open-to-a-later-place.patch
@@ -0,0 +1,53 @@
+From: Dexuan Cui <decui@microsoft.com>
+Date: Fri, 27 Feb 2015 11:25:58 -0800
+Patch-mainline: v4.1-rc1
+Subject: hv: hv_util: move vmbus_open() to a later place
+Git-commit: 1896566372579939eb86414ea3d664f18d5e909c
+References: fate#317533
+
+Before the line vmbus_open() returns, srv->util_cb can be already running
+and the variables, like util_fw_version, are needed by the srv->util_cb.
+
+So we have to make sure the variables are initialized before the vmbus_open().
+
+CC: "K. Y. Srinivasan" <kys@microsoft.com>
+Reviewed-by: Vitaly Kuznetsov <vkuznets@redhat.com>
+Reviewed-by: Jason Wang <jasowang@redhat.com>
+Signed-off-by: Dexuan Cui <decui@microsoft.com>
+Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Acked-by: <ohering@suse.de>
+---
+ drivers/hv/hv_util.c | 11 ++++++-----
+ 1 file changed, 6 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/hv/hv_util.c b/drivers/hv/hv_util.c
+index 3b9c9ef..c5be773 100644
+--- a/drivers/hv/hv_util.c
++++ b/drivers/hv/hv_util.c
+@@ -340,12 +340,8 @@ static int util_probe(struct hv_device *dev,
+
+ set_channel_read_state(dev->channel, false);
+
+- ret = vmbus_open(dev->channel, 4 * PAGE_SIZE, 4 * PAGE_SIZE, NULL, 0,
+- srv->util_cb, dev->channel);
+- if (ret)
+- goto error;
+-
+ hv_set_drvdata(dev, srv);
++
+ /*
+ * Based on the host; initialize the framework and
+ * service version numbers we will negotiate.
+@@ -365,6 +361,11 @@ static int util_probe(struct hv_device *dev,
+ hb_srv_version = HB_VERSION;
+ }
+
++ ret = vmbus_open(dev->channel, 4 * PAGE_SIZE, 4 * PAGE_SIZE, NULL, 0,
++ srv->util_cb, dev->channel);
++ if (ret)
++ goto error;
++
+ return 0;
+
+ error:
diff --git a/patches.suse/msft-hv-0750-hv-vmbus_post_msg-retry-the-hypercall-on-some-transi.patch b/patches.suse/msft-hv-0750-hv-vmbus_post_msg-retry-the-hypercall-on-some-transi.patch
new file mode 100644
index 0000000000..d4211e3ab3
--- /dev/null
+++ b/patches.suse/msft-hv-0750-hv-vmbus_post_msg-retry-the-hypercall-on-some-transi.patch
@@ -0,0 +1,73 @@
+From: Dexuan Cui <decui@microsoft.com>
+Date: Fri, 27 Feb 2015 11:25:59 -0800
+Patch-mainline: v4.1-rc1
+Subject: hv: vmbus_post_msg: retry the hypercall on some transient errors
+Git-commit: 89f9f6796d41e10e224b0cb0027ddd78cb881f65
+References: fate#317533
+
+I got HV_STATUS_INVALID_CONNECTION_ID on Hyper-V 2008 R2 when keeping running
+"rmmod hv_netvsc; modprobe hv_netvsc; rmmod hv_utils; modprobe hv_utils"
+in a Linux guest. Looks the host has some kind of throttling mechanism if
+some kinds of hypercalls are sent too frequently.
+Without the patch, the driver can occasionally fail to load.
+
+Also let's retry HV_STATUS_INSUFFICIENT_MEMORY, though we didn't get it
+before.
+
+Removed 'case -ENOMEM', since the hypervisor doesn't return this.
+
+CC: "K. Y. Srinivasan" <kys@microsoft.com>
+Reviewed-by: Jason Wang <jasowang@redhat.com>
+Signed-off-by: Dexuan Cui <decui@microsoft.com>
+Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Acked-by: <ohering@suse.de>
+---
+ arch/x86/include/asm/hyperv.h | 2 ++
+ drivers/hv/connection.c | 11 +++++++++--
+ 2 files changed, 11 insertions(+), 2 deletions(-)
+
+diff --git a/arch/x86/include/asm/hyperv.h b/arch/x86/include/asm/hyperv.h
+index 90c458e..ce6068d 100644
+--- a/arch/x86/include/asm/hyperv.h
++++ b/arch/x86/include/asm/hyperv.h
+@@ -225,6 +225,8 @@
+ #define HV_STATUS_INVALID_HYPERCALL_CODE 2
+ #define HV_STATUS_INVALID_HYPERCALL_INPUT 3
+ #define HV_STATUS_INVALID_ALIGNMENT 4
++#define HV_STATUS_INSUFFICIENT_MEMORY 11
++#define HV_STATUS_INVALID_CONNECTION_ID 18
+ #define HV_STATUS_INSUFFICIENT_BUFFERS 19
+
+ #endif
+diff --git a/drivers/hv/connection.c b/drivers/hv/connection.c
+index c4acd1c..af2388f 100644
+--- a/drivers/hv/connection.c
++++ b/drivers/hv/connection.c
+@@ -440,9 +440,16 @@ int vmbus_post_msg(void *buffer, size_t buflen)
+ ret = hv_post_message(conn_id, 1, buffer, buflen);
+
+ switch (ret) {
++ case HV_STATUS_INVALID_CONNECTION_ID:
++ /*
++ * We could get this if we send messages too
++ * frequently.
++ */
++ ret = -EAGAIN;
++ break;
++ case HV_STATUS_INSUFFICIENT_MEMORY:
+ case HV_STATUS_INSUFFICIENT_BUFFERS:
+ ret = -ENOMEM;
+- case -ENOMEM:
+ break;
+ case HV_STATUS_SUCCESS:
+ return ret;
+@@ -452,7 +459,7 @@ int vmbus_post_msg(void *buffer, size_t buflen)
+ }
+
+ retries++;
+- msleep(100);
++ msleep(1000);
+ }
+ return ret;
+ }
diff --git a/patches.suse/msft-hv-0751-hv-vmbus_open-reset-the-channel-state-on-ENOMEM.patch b/patches.suse/msft-hv-0751-hv-vmbus_open-reset-the-channel-state-on-ENOMEM.patch
new file mode 100644
index 0000000000..33f172c0f4
--- /dev/null
+++ b/patches.suse/msft-hv-0751-hv-vmbus_open-reset-the-channel-state-on-ENOMEM.patch
@@ -0,0 +1,47 @@
+From: Dexuan Cui <decui@microsoft.com>
+Date: Fri, 27 Feb 2015 11:26:00 -0800
+Patch-mainline: v4.1-rc1
+Subject: hv: vmbus_open(): reset the channel state on ENOMEM
+Git-commit: ac0d12b7cee73b4b4b769ea58c62ec7042c6be13
+References: fate#317533
+
+Without this patch, the state is put to CHANNEL_OPENING_STATE, and when
+the driver is loaded next time, vmbus_open() will fail immediately due to
+newchannel->state != CHANNEL_OPEN_STATE.
+
+CC: "K. Y. Srinivasan" <kys@microsoft.com>
+Signed-off-by: Dexuan Cui <decui@microsoft.com>
+Reviewed-by: Jason Wang <jasowang@redhat.com>
+Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Acked-by: <ohering@suse.de>
+---
+ drivers/hv/channel.c | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c
+index 2978f5e..26dcf26 100644
+--- a/drivers/hv/channel.c
++++ b/drivers/hv/channel.c
+@@ -89,9 +89,10 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size,
+ out = (void *)__get_free_pages(GFP_KERNEL|__GFP_ZERO,
+ get_order(send_ringbuffer_size + recv_ringbuffer_size));
+
+- if (!out)
+- return -ENOMEM;
+-
++ if (!out) {
++ err = -ENOMEM;
++ goto error0;
++ }
+
+ in = (void *)((unsigned long)out + send_ringbuffer_size);
+
+@@ -199,6 +200,7 @@ error0:
+ free_pages((unsigned long)out,
+ get_order(send_ringbuffer_size + recv_ringbuffer_size));
+ kfree(open_info);
++ newchannel->state = CHANNEL_OPEN_STATE;
+ return err;
+ }
+ EXPORT_SYMBOL_GPL(vmbus_open);
diff --git a/patches.suse/msft-hv-0752-hv-channel-match-var-type-to-return-type-of-wait_for.patch b/patches.suse/msft-hv-0752-hv-channel-match-var-type-to-return-type-of-wait_for.patch
new file mode 100644
index 0000000000..06f740acda
--- /dev/null
+++ b/patches.suse/msft-hv-0752-hv-channel-match-var-type-to-return-type-of-wait_for.patch
@@ -0,0 +1,32 @@
+From: Nicholas Mc Guire <der.herr@hofr.at>
+Date: Fri, 27 Feb 2015 11:26:01 -0800
+Patch-mainline: v4.1-rc1
+Subject: hv: channel: match var type to return type of wait_for_completion
+Git-commit: 08a9513f7417d6dff9a1ab0c163900f503ff84eb
+References: fate#317533
+
+return type of wait_for_completion_timeout is unsigned long not int, this
+patch changes the type of t from int to unsigned long.
+
+Signed-off-by: Nicholas Mc Guire <der.herr@hofr.at>
+Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Acked-by: <ohering@suse.de>
+---
+ drivers/hv/channel.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c
+index 26dcf26..f687995 100644
+--- a/drivers/hv/channel.c
++++ b/drivers/hv/channel.c
+@@ -71,7 +71,8 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size,
+ struct vmbus_channel_msginfo *open_info = NULL;
+ void *in, *out;
+ unsigned long flags;
+- int ret, t, err = 0;
++ int ret, err = 0;
++ unsigned long t;
+
+ spin_lock_irqsave(&newchannel->lock, flags);
+ if (newchannel->state == CHANNEL_OPEN_STATE) {
diff --git a/patches.suse/msft-hv-0753-hv-channel_mgmt-match-var-type-to-return-type-of-wai.patch b/patches.suse/msft-hv-0753-hv-channel_mgmt-match-var-type-to-return-type-of-wai.patch
new file mode 100644
index 0000000000..a773e89e6b
--- /dev/null
+++ b/patches.suse/msft-hv-0753-hv-channel_mgmt-match-var-type-to-return-type-of-wai.patch
@@ -0,0 +1,32 @@
+From: Nicholas Mc Guire <der.herr@hofr.at>
+Date: Fri, 27 Feb 2015 11:26:02 -0800
+Patch-mainline: v4.1-rc1
+Subject: hv: channel_mgmt: match var type to return type of wait_for_completion
+Git-commit: 51e5181d20086c0b26e871deffeff3ff47cf5c4b
+References: fate#317533
+
+return type of wait_for_completion_timeout is unsigned long not int, this
+patch changes the type of t from int to unsigned long.
+
+Signed-off-by: Nicholas Mc Guire <der.herr@hofr.at>
+Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Acked-by: <ohering@suse.de>
+---
+ drivers/hv/channel_mgmt.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c
+index 36bacc7..6be93f0 100644
+--- a/drivers/hv/channel_mgmt.c
++++ b/drivers/hv/channel_mgmt.c
+@@ -789,7 +789,8 @@ int vmbus_request_offers(void)
+ {
+ struct vmbus_channel_message_header *msg;
+ struct vmbus_channel_msginfo *msginfo;
+- int ret, t;
++ int ret;
++ unsigned long t;
+
+ msginfo = kmalloc(sizeof(*msginfo) +
+ sizeof(struct vmbus_channel_message_header),
diff --git a/patches.suse/msft-hv-0754-hv-hv_balloon-match-var-type-to-return-type-of-wait_.patch b/patches.suse/msft-hv-0754-hv-hv_balloon-match-var-type-to-return-type-of-wait_.patch
new file mode 100644
index 0000000000..dd414759df
--- /dev/null
+++ b/patches.suse/msft-hv-0754-hv-hv_balloon-match-var-type-to-return-type-of-wait_.patch
@@ -0,0 +1,32 @@
+From: Nicholas Mc Guire <der.herr@hofr.at>
+Date: Fri, 27 Feb 2015 11:26:03 -0800
+Patch-mainline: v4.1-rc1
+Subject: hv: hv_balloon: match var type to return type of wait_for_completion
+Git-commit: b057b3ad16e1c6e21e234cd7f5c61c525da97f17
+References: fate#317533
+
+return type of wait_for_completion_timeout is unsigned long not int, this
+patch changes the type of t from int to unsigned long.
+
+Signed-off-by: Nicholas Mc Guire <der.herr@hofr.at>
+Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Acked-by: <ohering@suse.de>
+---
+ drivers/hv/hv_balloon.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/hv/hv_balloon.c b/drivers/hv/hv_balloon.c
+index ff16938..965c37a 100644
+--- a/drivers/hv/hv_balloon.c
++++ b/drivers/hv/hv_balloon.c
+@@ -1414,7 +1414,8 @@ static void balloon_onchannelcallback(void *context)
+ static int balloon_probe(struct hv_device *dev,
+ const struct hv_vmbus_device_id *dev_id)
+ {
+- int ret, t;
++ int ret;
++ unsigned long t;
+ struct dm_version_request version_req;
+ struct dm_capabilities cap_msg;
+
diff --git a/patches.suse/msft-hv-0755-Drivers-hv-vmbus-Fix-a-bug-in-the-error-path-in-vmbu.patch b/patches.suse/msft-hv-0755-Drivers-hv-vmbus-Fix-a-bug-in-the-error-path-in-vmbu.patch
new file mode 100644
index 0000000000..26312fab8b
--- /dev/null
+++ b/patches.suse/msft-hv-0755-Drivers-hv-vmbus-Fix-a-bug-in-the-error-path-in-vmbu.patch
@@ -0,0 +1,50 @@
+From: "K. Y. Srinivasan" <kys@microsoft.com>
+Date: Fri, 27 Feb 2015 11:26:04 -0800
+Patch-mainline: v4.1-rc1
+Subject: Drivers: hv: vmbus: Fix a bug in the error path in vmbus_open()
+Git-commit: 40384e4bbeb9f2651fe9bffc0062d9f31ef625bf
+References: fate#317533
+
+Correctly rollback state if the failure occurs after we have handed over
+the ownership of the buffer to the host.
+
+Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Acked-by: <ohering@suse.de>
+---
+ drivers/hv/channel.c | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c
+index f687995..bf0cf8f 100644
+--- a/drivers/hv/channel.c
++++ b/drivers/hv/channel.c
+@@ -137,7 +137,7 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size,
+ GFP_KERNEL);
+ if (!open_info) {
+ err = -ENOMEM;
+- goto error0;
++ goto error_gpadl;
+ }
+
+ init_completion(&open_info->waitevent);
+@@ -153,7 +153,7 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size,
+
+ if (userdatalen > MAX_USER_DEFINED_BYTES) {
+ err = -EINVAL;
+- goto error0;
++ goto error_gpadl;
+ }
+
+ if (userdatalen)
+@@ -197,6 +197,9 @@ error1:
+ list_del(&open_info->msglistentry);
+ spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags);
+
++error_gpadl:
++ vmbus_teardown_gpadl(newchannel, newchannel->ringbuffer_gpadlhandle);
++
+ error0:
+ free_pages((unsigned long)out,
+ get_order(send_ringbuffer_size + recv_ringbuffer_size));
diff --git a/patches.suse/msft-hv-0756-Drivers-hv-vmbus-Add-support-for-the-NetworkDirect-G.patch b/patches.suse/msft-hv-0756-Drivers-hv-vmbus-Add-support-for-the-NetworkDirect-G.patch
new file mode 100644
index 0000000000..fba5595d14
--- /dev/null
+++ b/patches.suse/msft-hv-0756-Drivers-hv-vmbus-Add-support-for-the-NetworkDirect-G.patch
@@ -0,0 +1,52 @@
+From: "K. Y. Srinivasan" <kys@microsoft.com>
+Date: Fri, 27 Feb 2015 11:26:05 -0800
+Patch-mainline: v4.1-rc1
+Subject: Drivers: hv: vmbus: Add support for the NetworkDirect GUID
+Git-commit: 04653a009a63d6a91c60a5449ea97e3ed5e1dc29
+References: fate#317533
+
+NetworkDirect is a service that supports guest RDMA.
+Define the GUID for this service.
+
+Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Acked-by: <ohering@suse.de>
+---
+ drivers/hv/channel_mgmt.c | 2 ++
+ include/linux/hyperv.h | 10 ++++++++++
+ 2 files changed, 12 insertions(+)
+
+diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c
+index 6be93f0..0ba6b5c 100644
+--- a/drivers/hv/channel_mgmt.c
++++ b/drivers/hv/channel_mgmt.c
+@@ -413,6 +413,8 @@ static const struct hv_vmbus_device_id hp_devs[] = {
+ { HV_SCSI_GUID, },
+ /* Network */
+ { HV_NIC_GUID, },
++ /* NetworkDirect Guest RDMA */
++ { HV_ND_GUID, },
+ };
+
+
+diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
+index 26a32b7..7d976ac 100644
+--- a/include/linux/hyperv.h
++++ b/include/linux/hyperv.h
+@@ -1110,6 +1110,16 @@ void vmbus_driver_unregister(struct hv_driver *hv_driver);
+ }
+
+ /*
++ * NetworkDirect. This is the guest RDMA service.
++ * {8c2eaf3d-32a7-4b09-ab99-bd1f1c86b501}
++ */
++#define HV_ND_GUID \
++ .guid = { \
++ 0x3d, 0xaf, 0x2e, 0x8c, 0xa7, 0x32, 0x09, 0x4b, \
++ 0xab, 0x99, 0xbd, 0x1f, 0x1c, 0x86, 0xb5, 0x01 \
++ }
++
++/*
+ * Common header for Hyper-V ICs
+ */
+
diff --git a/patches.suse/msft-hv-0757-Drivers-hv-vmbus-Properly-handle-child-device-remove.patch b/patches.suse/msft-hv-0757-Drivers-hv-vmbus-Properly-handle-child-device-remove.patch
new file mode 100644
index 0000000000..a8f74eb0ae
--- /dev/null
+++ b/patches.suse/msft-hv-0757-Drivers-hv-vmbus-Properly-handle-child-device-remove.patch
@@ -0,0 +1,45 @@
+From: "K. Y. Srinivasan" <kys@microsoft.com>
+Date: Sat, 28 Feb 2015 11:18:16 -0800
+Patch-mainline: v4.1-rc1
+Subject: Drivers: hv: vmbus: Properly handle child device remove
+Git-commit: d15a0301c4157884d1a48a5d76b9ac3e36d71242
+References: fate#317533
+
+Handle the case when the device may be removed when the device has no driver
+attached to it.
+
+Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Acked-by: <ohering@suse.de>
+---
+ drivers/hv/vmbus_drv.c | 15 +++++++++------
+ 1 file changed, 9 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
+index 6d99aa5..a12666d 100644
+--- a/drivers/hv/vmbus_drv.c
++++ b/drivers/hv/vmbus_drv.c
+@@ -508,14 +508,17 @@ static int vmbus_probe(struct device *child_device)
+ */
+ static int vmbus_remove(struct device *child_device)
+ {
+- struct hv_driver *drv = drv_to_hv_drv(child_device->driver);
++ struct hv_driver *drv;
+ struct hv_device *dev = device_to_hv_device(child_device);
+
+- if (drv->remove)
+- drv->remove(dev);
+- else
+- pr_err("remove not set for driver %s\n",
+- dev_name(child_device));
++ if (child_device->driver) {
++ drv = drv_to_hv_drv(child_device->driver);
++ if (drv->remove)
++ drv->remove(dev);
++ else
++ pr_err("remove not set for driver %s\n",
++ dev_name(child_device));
++ }
+
+ return 0;
+ }
diff --git a/patches.suse/msft-hv-0758-Drivers-hv-vmbus-Introduce-a-function-to-remove-a-re.patch b/patches.suse/msft-hv-0758-Drivers-hv-vmbus-Introduce-a-function-to-remove-a-re.patch
new file mode 100644
index 0000000000..e0027382dd
--- /dev/null
+++ b/patches.suse/msft-hv-0758-Drivers-hv-vmbus-Introduce-a-function-to-remove-a-re.patch
@@ -0,0 +1,157 @@
+From: "K. Y. Srinivasan" <kys@microsoft.com>
+Date: Sat, 28 Feb 2015 11:18:17 -0800
+Patch-mainline: v4.1-rc1
+Subject: Drivers: hv: vmbus: Introduce a function to remove a rescinded offer
+Git-commit: ed6cfcc5fdf2ebca320b6f74c836e555e18216e1
+References: fate#317533
+
+In response to a rescind message, we need to remove the channel and the
+corresponding device. Cleanup this code path by factoring out the code
+to remove a channel.
+
+Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Acked-by: <ohering@suse.de>
+---
+ drivers/hv/channel.c | 9 +++++++++
+ drivers/hv/channel_mgmt.c | 49 +++++++++++++++++++++++++++++------------------
+ drivers/hv/vmbus_drv.c | 11 ++++++++++-
+ include/linux/hyperv.h | 1 +
+ 4 files changed, 50 insertions(+), 20 deletions(-)
+
+diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c
+index bf0cf8f..9b79aca 100644
+--- a/drivers/hv/channel.c
++++ b/drivers/hv/channel.c
+@@ -501,6 +501,15 @@ static int vmbus_close_internal(struct vmbus_channel *channel)
+ put_cpu();
+ }
+
++ /*
++ * If the channel has been rescinded; process device removal.
++ */
++ if (channel->rescind) {
++ hv_process_channel_removal(channel,
++ channel->offermsg.child_relid);
++ return 0;
++ }
++
+ /* Send a closing message */
+
+ msg = &channel->close_msg.msg;
+diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c
+index 0ba6b5c..b933891 100644
+--- a/drivers/hv/channel_mgmt.c
++++ b/drivers/hv/channel_mgmt.c
+@@ -207,33 +207,21 @@ static void percpu_channel_deq(void *arg)
+ list_del(&channel->percpu_list);
+ }
+
+-/*
+- * vmbus_process_rescind_offer -
+- * Rescind the offer by initiating a device removal
+- */
+-static void vmbus_process_rescind_offer(struct work_struct *work)
++
++void hv_process_channel_removal(struct vmbus_channel *channel, u32 relid)
+ {
+- struct vmbus_channel *channel = container_of(work,
+- struct vmbus_channel,
+- work);
++ struct vmbus_channel_relid_released msg;
+ unsigned long flags;
+ struct vmbus_channel *primary_channel;
+- struct vmbus_channel_relid_released msg;
+- struct device *dev;
+-
+- if (channel->device_obj) {
+- dev = get_device(&channel->device_obj->device);
+- if (dev) {
+- vmbus_device_unregister(channel->device_obj);
+- put_device(dev);
+- }
+- }
+
+ memset(&msg, 0, sizeof(struct vmbus_channel_relid_released));
+- msg.child_relid = channel->offermsg.child_relid;
++ msg.child_relid = relid;
+ msg.header.msgtype = CHANNELMSG_RELID_RELEASED;
+ vmbus_post_msg(&msg, sizeof(struct vmbus_channel_relid_released));
+
++ if (channel == NULL)
++ return;
++
+ if (channel->target_cpu != get_cpu()) {
+ put_cpu();
+ smp_call_function_single(channel->target_cpu,
+@@ -256,6 +244,29 @@ static void vmbus_process_rescind_offer(struct work_struct *work)
+ free_channel(channel);
+ }
+
++/*
++ * vmbus_process_rescind_offer -
++ * Rescind the offer by initiating a device removal
++ */
++static void vmbus_process_rescind_offer(struct work_struct *work)
++{
++ struct vmbus_channel *channel = container_of(work,
++ struct vmbus_channel,
++ work);
++ struct device *dev;
++
++ if (channel->device_obj) {
++ dev = get_device(&channel->device_obj->device);
++ if (dev) {
++ vmbus_device_unregister(channel->device_obj);
++ put_device(dev);
++ }
++ } else {
++ hv_process_channel_removal(channel,
++ channel->offermsg.child_relid);
++ }
++}
++
+ void vmbus_free_channels(void)
+ {
+ struct vmbus_channel *channel;
+diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
+index a12666d..2b7b51d 100644
+--- a/drivers/hv/vmbus_drv.c
++++ b/drivers/hv/vmbus_drv.c
+@@ -510,14 +510,23 @@ static int vmbus_remove(struct device *child_device)
+ {
+ struct hv_driver *drv;
+ struct hv_device *dev = device_to_hv_device(child_device);
++ u32 relid = dev->channel->offermsg.child_relid;
+
+ if (child_device->driver) {
+ drv = drv_to_hv_drv(child_device->driver);
+ if (drv->remove)
+ drv->remove(dev);
+- else
++ else {
++ hv_process_channel_removal(dev->channel, relid);
+ pr_err("remove not set for driver %s\n",
+ dev_name(child_device));
++ }
++ } else {
++ /*
++ * We don't have a driver for this device; deal with the
++ * rescind message by removing the channel.
++ */
++ hv_process_channel_removal(dev->channel, relid);
+ }
+
+ return 0;
+diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
+index 7d976ac..dd92a85 100644
+--- a/include/linux/hyperv.h
++++ b/include/linux/hyperv.h
+@@ -1226,6 +1226,7 @@ void hv_kvp_onchannelcallback(void *);
+ int hv_vss_init(struct hv_util_service *);
+ void hv_vss_deinit(void);
+ void hv_vss_onchannelcallback(void *);
++void hv_process_channel_removal(struct vmbus_channel *channel, u32 relid);
+
+ extern struct resource hyperv_mmio;
+
diff --git a/patches.suse/msft-hv-0759-Drivers-hv-vmbus-Handle-both-rescind-and-offer-messa.patch b/patches.suse/msft-hv-0759-Drivers-hv-vmbus-Handle-both-rescind-and-offer-messa.patch
new file mode 100644
index 0000000000..d0bc62f2f8
--- /dev/null
+++ b/patches.suse/msft-hv-0759-Drivers-hv-vmbus-Handle-both-rescind-and-offer-messa.patch
@@ -0,0 +1,192 @@
+From: "K. Y. Srinivasan" <kys@microsoft.com>
+Date: Sat, 28 Feb 2015 11:18:18 -0800
+Patch-mainline: v4.1-rc1
+Subject: Drivers: hv: vmbus: Handle both rescind and offer messages in the same context
+Git-commit: 2dd37cb81580dce6dfb8c5a7d5c37b904a188ae7
+References: fate#317533
+
+Execute both ressind and offer messages in the same work context. This serializes these
+operations and naturally addresses the various corner cases.
+
+Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Acked-by: <ohering@suse.de>
+---
+ drivers/hv/channel_mgmt.c | 115 +++++++++++++++++++++++++---------------------
+ 1 file changed, 62 insertions(+), 53 deletions(-)
+
+diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c
+index b933891..f8528e1 100644
+--- a/drivers/hv/channel_mgmt.c
++++ b/drivers/hv/channel_mgmt.c
+@@ -134,6 +134,34 @@ fw_error:
+
+ EXPORT_SYMBOL_GPL(vmbus_prep_negotiate_resp);
+
++static void vmbus_process_device_unregister(struct work_struct *work)
++{
++ struct device *dev;
++ struct vmbus_channel *channel = container_of(work,
++ struct vmbus_channel,
++ work);
++
++ dev = get_device(&channel->device_obj->device);
++ if (dev) {
++ vmbus_device_unregister(channel->device_obj);
++ put_device(dev);
++ }
++}
++
++static void vmbus_sc_creation_cb(struct work_struct *work)
++{
++ struct vmbus_channel *newchannel = container_of(work,
++ struct vmbus_channel,
++ work);
++ struct vmbus_channel *primary_channel = newchannel->primary_channel;
++
++ /*
++ * On entry sc_creation_callback has been already verified to
++ * be non-NULL.
++ */
++ primary_channel->sc_creation_callback(newchannel);
++}
++
+ /*
+ * alloc_channel - Allocate and initialize a vmbus channel object
+ */
+@@ -244,29 +272,6 @@ void hv_process_channel_removal(struct vmbus_channel *channel, u32 relid)
+ free_channel(channel);
+ }
+
+-/*
+- * vmbus_process_rescind_offer -
+- * Rescind the offer by initiating a device removal
+- */
+-static void vmbus_process_rescind_offer(struct work_struct *work)
+-{
+- struct vmbus_channel *channel = container_of(work,
+- struct vmbus_channel,
+- work);
+- struct device *dev;
+-
+- if (channel->device_obj) {
+- dev = get_device(&channel->device_obj->device);
+- if (dev) {
+- vmbus_device_unregister(channel->device_obj);
+- put_device(dev);
+- }
+- } else {
+- hv_process_channel_removal(channel,
+- channel->offermsg.child_relid);
+- }
+-}
+-
+ void vmbus_free_channels(void)
+ {
+ struct vmbus_channel *channel;
+@@ -281,11 +286,8 @@ void vmbus_free_channels(void)
+ * vmbus_process_offer - Process the offer by creating a channel/device
+ * associated with this offer
+ */
+-static void vmbus_process_offer(struct work_struct *work)
++static void vmbus_process_offer(struct vmbus_channel *newchannel)
+ {
+- struct vmbus_channel *newchannel = container_of(work,
+- struct vmbus_channel,
+- work);
+ struct vmbus_channel *channel;
+ bool fnew = true;
+ bool enq = false;
+@@ -349,9 +351,19 @@ static void vmbus_process_offer(struct work_struct *work)
+
+ newchannel->state = CHANNEL_OPEN_STATE;
+ if (channel->sc_creation_callback != NULL)
+- channel->sc_creation_callback(newchannel);
+-
+- goto done_init_rescind;
++ /*
++ * We need to invoke the sub-channel creation
++ * callback; invoke this in a seperate work
++ * context since we are currently running on
++ * the global work context in which we handle
++ * messages from the host.
++ */
++ INIT_WORK(&newchannel->work,
++ vmbus_sc_creation_cb);
++ queue_work(newchannel->controlwq,
++ &newchannel->work);
++
++ return;
+ }
+
+ goto err_free_chan;
+@@ -392,15 +404,9 @@ static void vmbus_process_offer(struct work_struct *work)
+ kfree(newchannel->device_obj);
+ goto err_free_chan;
+ }
+-done_init_rescind:
+- spin_lock_irqsave(&newchannel->lock, flags);
+- /* The next possible work is rescind handling */
+- INIT_WORK(&newchannel->work, vmbus_process_rescind_offer);
+- /* Check if rescind offer was already received */
+- if (newchannel->rescind)
+- queue_work(newchannel->controlwq, &newchannel->work);
+- spin_unlock_irqrestore(&newchannel->lock, flags);
++
+ return;
++
+ err_free_chan:
+ free_channel(newchannel);
+ }
+@@ -526,8 +532,7 @@ static void vmbus_onoffer(struct vmbus_channel_message_header *hdr)
+ newchannel->monitor_grp = (u8)offer->monitorid / 32;
+ newchannel->monitor_bit = (u8)offer->monitorid % 32;
+
+- INIT_WORK(&newchannel->work, vmbus_process_offer);
+- queue_work(newchannel->controlwq, &newchannel->work);
++ vmbus_process_offer(newchannel);
+ }
+
+ /*
+@@ -544,24 +549,28 @@ static void vmbus_onoffer_rescind(struct vmbus_channel_message_header *hdr)
+ rescind = (struct vmbus_channel_rescind_offer *)hdr;
+ channel = relid2channel(rescind->child_relid);
+
+- if (channel == NULL)
+- /* Just return here, no channel found */
++ if (channel == NULL) {
++ hv_process_channel_removal(NULL, rescind->child_relid);
+ return;
++ }
+
+ spin_lock_irqsave(&channel->lock, flags);
+ channel->rescind = true;
+- /*
+- * channel->work.func != vmbus_process_rescind_offer means we are still
+- * processing offer request and the rescind offer processing should be
+- * postponed. It will be done at the very end of vmbus_process_offer()
+- * as rescind flag is being checked there.
+- */
+- if (channel->work.func == vmbus_process_rescind_offer)
+- /* work is initialized for vmbus_process_rescind_offer() from
+- * vmbus_process_offer() where the channel got created */
+- queue_work(channel->controlwq, &channel->work);
+-
+ spin_unlock_irqrestore(&channel->lock, flags);
++
++ if (channel->device_obj) {
++ /*
++ * We will have to unregister this device from the
++ * driver core. Do this in the per-channel work context.
++ * Note that we are currently executing on the global
++ * workq for handling messages from the host.
++ */
++ INIT_WORK(&channel->work, vmbus_process_device_unregister);
++ queue_work(channel->controlwq, &channel->work);
++ } else {
++ hv_process_channel_removal(channel,
++ channel->offermsg.child_relid);
++ }
+ }
+
+ /*
diff --git a/patches.suse/msft-hv-0760-Drivers-hv-vmbus-Remove-the-channel-from-the-channel.patch b/patches.suse/msft-hv-0760-Drivers-hv-vmbus-Remove-the-channel-from-the-channel.patch
new file mode 100644
index 0000000000..21b1981395
--- /dev/null
+++ b/patches.suse/msft-hv-0760-Drivers-hv-vmbus-Remove-the-channel-from-the-channel.patch
@@ -0,0 +1,60 @@
+From: "K. Y. Srinivasan" <kys@microsoft.com>
+Date: Sat, 28 Feb 2015 11:18:19 -0800
+Patch-mainline: v4.1-rc1
+Subject: Drivers: hv: vmbus: Remove the channel from the channel list(s) on failure
+Git-commit: 5b1e5b530753e660080d402b81b88684893157d5
+References: fate#317533
+
+Properly rollback state in vmbus_pocess_offer() in the failure paths.
+
+Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Acked-by: <ohering@suse.de>
+---
+ drivers/hv/channel_mgmt.c | 21 ++++++++++++++++-----
+ 1 file changed, 16 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c
+index f8528e1..b1e5a5f 100644
+--- a/drivers/hv/channel_mgmt.c
++++ b/drivers/hv/channel_mgmt.c
+@@ -386,7 +386,7 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel)
+ &newchannel->offermsg.offer.if_instance,
+ newchannel);
+ if (!newchannel->device_obj)
+- goto err_free_chan;
++ goto err_deq_chan;
+
+ /*
+ * Add the new device to the bus. This will kick off device-driver
+@@ -398,15 +398,26 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel)
+ pr_err("unable to add child device object (relid %d)\n",
+ newchannel->offermsg.child_relid);
+
+- spin_lock_irqsave(&vmbus_connection.channel_lock, flags);
+- list_del(&newchannel->listentry);
+- spin_unlock_irqrestore(&vmbus_connection.channel_lock, flags);
+ kfree(newchannel->device_obj);
+- goto err_free_chan;
++ goto err_deq_chan;
+ }
+
+ return;
+
++err_deq_chan:
++ spin_lock_irqsave(&vmbus_connection.channel_lock, flags);
++ list_del(&newchannel->listentry);
++ spin_unlock_irqrestore(&vmbus_connection.channel_lock, flags);
++
++ 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();
++ }
++
+ err_free_chan:
+ free_channel(newchannel);
+ }
diff --git a/patches.suse/msft-hv-0761-Drivers-hv-util-On-device-remove-close-the-channel-a.patch b/patches.suse/msft-hv-0761-Drivers-hv-util-On-device-remove-close-the-channel-a.patch
new file mode 100644
index 0000000000..cd5ac12f94
--- /dev/null
+++ b/patches.suse/msft-hv-0761-Drivers-hv-util-On-device-remove-close-the-channel-a.patch
@@ -0,0 +1,32 @@
+From: "K. Y. Srinivasan" <kys@microsoft.com>
+Date: Sat, 28 Feb 2015 11:18:20 -0800
+Patch-mainline: v4.1-rc1
+Subject: Drivers: hv: util: On device remove, close the channel after de-initializing the service
+Git-commit: 5380b383ba10915e61e3db09341cf8193f0601ad
+References: fate#317533
+
+When the offer is rescinded, vmbus_close() can free up the channel;
+deinitialize the service before closing the channel.
+
+Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Acked-by: <ohering@suse.de>
+---
+ drivers/hv/hv_util.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/hv/hv_util.c b/drivers/hv/hv_util.c
+index c5be773..7994ec2 100644
+--- a/drivers/hv/hv_util.c
++++ b/drivers/hv/hv_util.c
+@@ -380,9 +380,9 @@ static int util_remove(struct hv_device *dev)
+ {
+ struct hv_util_service *srv = hv_get_drvdata(dev);
+
+- vmbus_close(dev->channel);
+ if (srv->util_deinit)
+ srv->util_deinit();
++ vmbus_close(dev->channel);
+ kfree(srv->recv_buffer);
+
+ return 0;
diff --git a/patches.suse/msft-hv-0762-Drivers-hv-vmbus-Get-rid-of-some-unnecessary-message.patch b/patches.suse/msft-hv-0762-Drivers-hv-vmbus-Get-rid-of-some-unnecessary-message.patch
new file mode 100644
index 0000000000..674a027449
--- /dev/null
+++ b/patches.suse/msft-hv-0762-Drivers-hv-vmbus-Get-rid-of-some-unnecessary-message.patch
@@ -0,0 +1,46 @@
+From: "K. Y. Srinivasan" <kys@microsoft.com>
+Date: Sat, 28 Feb 2015 11:18:21 -0800
+Patch-mainline: v4.1-rc1
+Subject: Drivers: hv: vmbus: Get rid of some unnecessary messages
+Git-commit: 37f492ce8148d84261cdb9fe1e925199f47531ae
+References: fate#317533
+
+Currently we log messages when either we are not able to map an ID to a
+channel or when the channel does not have a callback associated
+(in the channel interrupt handling path). These messages don't add
+any value, get rid of them.
+
+Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Acked-by: <ohering@suse.de>
+---
+ drivers/hv/connection.c | 7 +------
+ 1 file changed, 1 insertion(+), 6 deletions(-)
+
+diff --git a/drivers/hv/connection.c b/drivers/hv/connection.c
+index af2388f..583d7d4 100644
+--- a/drivers/hv/connection.c
++++ b/drivers/hv/connection.c
+@@ -318,10 +318,8 @@ static void process_chn_event(u32 relid)
+ */
+ channel = pcpu_relid2channel(relid);
+
+- if (!channel) {
+- pr_err("channel not found for relid - %u\n", relid);
++ if (!channel)
+ return;
+- }
+
+ /*
+ * A channel once created is persistent even when there
+@@ -356,10 +354,7 @@ static void process_chn_event(u32 relid)
+ else
+ bytes_to_read = 0;
+ } while (read_state && (bytes_to_read != 0));
+- } else {
+- pr_err("no channel callback for relid - %u\n", relid);
+ }
+-
+ }
+
+ /*
diff --git a/patches.suse/msft-hv-0763-Drivers-hv-hv_balloon-eliminate-the-trylock-path-in-.patch b/patches.suse/msft-hv-0763-Drivers-hv-hv_balloon-eliminate-the-trylock-path-in-.patch
new file mode 100644
index 0000000000..a78ceb7ca5
--- /dev/null
+++ b/patches.suse/msft-hv-0763-Drivers-hv-hv_balloon-eliminate-the-trylock-path-in-.patch
@@ -0,0 +1,142 @@
+From: Vitaly Kuznetsov <vkuznets@redhat.com>
+Date: Sat, 28 Feb 2015 11:38:58 -0800
+Patch-mainline: v4.1-rc1
+Subject: Drivers: hv: hv_balloon: eliminate the trylock path in acquire/release_region_mutex
+Git-commit: b05d8d9ef5ef21d1b18440430f950304836e1aaa
+References: fate#317533
+
+When many memory regions are being added and automatically onlined the
+following lockup is sometimes observed:
+
+INFO: task udevd:1872 blocked for more than 120 seconds.
+...
+Call Trace:
+ [<ffffffff816ec0bc>] schedule_timeout+0x22c/0x350
+ [<ffffffff816eb98f>] wait_for_common+0x10f/0x160
+ [<ffffffff81067650>] ? default_wake_function+0x0/0x20
+ [<ffffffff816eb9fd>] wait_for_completion+0x1d/0x20
+ [<ffffffff8144cb9c>] hv_memory_notifier+0xdc/0x120
+ [<ffffffff816f298c>] notifier_call_chain+0x4c/0x70
+...
+
+When several memory blocks are going online simultaneously we got several
+hv_memory_notifier() trying to acquire the ha_region_mutex. When this mutex is
+being held by hot_add_req() all these competing acquire_region_mutex() do
+mutex_trylock, fail, and queue themselves into wait_for_completion(..). However
+when we do complete() from release_region_mutex() only one of them wakes up.
+This could be solved by changing complete() -> complete_all() memory onlining
+can be delayed as well, in that case we can still get several
+hv_memory_notifier() runners at the same time trying to grab the mutex.
+Only one of them will succeed and the others will hang for forever as
+complete() is not being called. We don't see this issue often because we have
+5sec onlining timeout in hv_mem_hot_add() and usually all udev events arrive
+in this time frame.
+
+Get rid of the trylock path, waiting on the mutex is supposed to provide the
+required serialization.
+
+Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
+Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Acked-by: <ohering@suse.de>
+---
+ drivers/hv/hv_balloon.c | 35 ++++++-----------------------------
+ 1 file changed, 6 insertions(+), 29 deletions(-)
+
+diff --git a/drivers/hv/hv_balloon.c b/drivers/hv/hv_balloon.c
+index 965c37a..ea3d33c 100644
+--- a/drivers/hv/hv_balloon.c
++++ b/drivers/hv/hv_balloon.c
+@@ -534,7 +534,6 @@ struct hv_dynmem_device {
+ struct task_struct *thread;
+
+ struct mutex ha_region_mutex;
+- struct completion waiter_event;
+
+ /*
+ * A list of hot-add regions.
+@@ -554,38 +553,17 @@ static struct hv_dynmem_device dm_device;
+ static void post_status(struct hv_dynmem_device *dm);
+
+ #ifdef CONFIG_MEMORY_HOTPLUG
+-static void acquire_region_mutex(bool trylock)
+-{
+- if (trylock) {
+- reinit_completion(&dm_device.waiter_event);
+- while (!mutex_trylock(&dm_device.ha_region_mutex))
+- wait_for_completion(&dm_device.waiter_event);
+- } else {
+- mutex_lock(&dm_device.ha_region_mutex);
+- }
+-}
+-
+-static void release_region_mutex(bool trylock)
+-{
+- if (trylock) {
+- mutex_unlock(&dm_device.ha_region_mutex);
+- } else {
+- mutex_unlock(&dm_device.ha_region_mutex);
+- complete(&dm_device.waiter_event);
+- }
+-}
+-
+ static int hv_memory_notifier(struct notifier_block *nb, unsigned long val,
+ void *v)
+ {
+ switch (val) {
+ case MEM_GOING_ONLINE:
+- acquire_region_mutex(true);
++ mutex_lock(&dm_device.ha_region_mutex);
+ break;
+
+ case MEM_ONLINE:
+ case MEM_CANCEL_ONLINE:
+- release_region_mutex(true);
++ mutex_unlock(&dm_device.ha_region_mutex);
+ if (dm_device.ha_waiting) {
+ dm_device.ha_waiting = false;
+ complete(&dm_device.ol_waitevent);
+@@ -646,7 +624,7 @@ static void hv_mem_hot_add(unsigned long start, unsigned long size,
+ init_completion(&dm_device.ol_waitevent);
+ dm_device.ha_waiting = true;
+
+- release_region_mutex(false);
++ mutex_unlock(&dm_device.ha_region_mutex);
+ nid = memory_add_physaddr_to_nid(PFN_PHYS(start_pfn));
+ ret = add_memory(nid, PFN_PHYS((start_pfn)),
+ (HA_CHUNK << PAGE_SHIFT));
+@@ -675,7 +653,7 @@ static void hv_mem_hot_add(unsigned long start, unsigned long size,
+ * have not been "onlined" within the allowed time.
+ */
+ wait_for_completion_timeout(&dm_device.ol_waitevent, 5*HZ);
+- acquire_region_mutex(false);
++ mutex_lock(&dm_device.ha_region_mutex);
+ post_status(&dm_device);
+ }
+
+@@ -886,7 +864,7 @@ static void hot_add_req(struct work_struct *dummy)
+ resp.hdr.size = sizeof(struct dm_hot_add_response);
+
+ #ifdef CONFIG_MEMORY_HOTPLUG
+- acquire_region_mutex(false);
++ mutex_lock(&dm_device.ha_region_mutex);
+ pg_start = dm->ha_wrk.ha_page_range.finfo.start_page;
+ pfn_cnt = dm->ha_wrk.ha_page_range.finfo.page_cnt;
+
+@@ -918,7 +896,7 @@ static void hot_add_req(struct work_struct *dummy)
+ if (do_hot_add)
+ resp.page_count = process_hot_add(pg_start, pfn_cnt,
+ rg_start, rg_sz);
+- release_region_mutex(false);
++ mutex_unlock(&dm_device.ha_region_mutex);
+ #endif
+ /*
+ * The result field of the response structure has the
+@@ -1440,7 +1418,6 @@ static int balloon_probe(struct hv_device *dev,
+ dm_device.next_version = DYNMEM_PROTOCOL_VERSION_WIN7;
+ init_completion(&dm_device.host_event);
+ init_completion(&dm_device.config_event);
+- init_completion(&dm_device.waiter_event);
+ INIT_LIST_HEAD(&dm_device.ha_region_list);
+ mutex_init(&dm_device.ha_region_mutex);
+ INIT_WORK(&dm_device.balloon_wrk.wrk, balloon_up);
diff --git a/patches.suse/msft-hv-0764-Drivers-hv-hv_balloon-report-offline-pages-as-being-.patch b/patches.suse/msft-hv-0764-Drivers-hv-hv_balloon-report-offline-pages-as-being-.patch
new file mode 100644
index 0000000000..a32448b93d
--- /dev/null
+++ b/patches.suse/msft-hv-0764-Drivers-hv-hv_balloon-report-offline-pages-as-being-.patch
@@ -0,0 +1,104 @@
+From: Vitaly Kuznetsov <vkuznets@redhat.com>
+Date: Sat, 28 Feb 2015 11:38:59 -0800
+Patch-mainline: v4.1-rc1
+Subject: Drivers: hv: hv_balloon: report offline pages as being used
+Git-commit: 549fd280b145e2154db5a7d06981d041f8bbf597
+References: fate#317533
+
+When hot-added memory pages are not brought online or when some memory blocks
+are sent offline the subsequent ballooning process kills the guest with OOM
+killer. This happens as we don't report these pages as neither used nor free
+and apparently host algorithm considers them as being unused. Keep track of
+all online/offline operations and report all currently offline pages as being
+used so host won't try to balloon them out.
+
+Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
+Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Acked-by: <ohering@suse.de>
+---
+ drivers/hv/hv_balloon.c | 33 ++++++++++++++++++++++++---------
+ 1 file changed, 24 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/hv/hv_balloon.c b/drivers/hv/hv_balloon.c
+index ea3d33c..53932b3 100644
+--- a/drivers/hv/hv_balloon.c
++++ b/drivers/hv/hv_balloon.c
+@@ -503,6 +503,8 @@ struct hv_dynmem_device {
+ * Number of pages we have currently ballooned out.
+ */
+ unsigned int num_pages_ballooned;
++ unsigned int num_pages_onlined;
++ unsigned int num_pages_added;
+
+ /*
+ * State to manage the ballooning (up) operation.
+@@ -556,12 +558,15 @@ static void post_status(struct hv_dynmem_device *dm);
+ static int hv_memory_notifier(struct notifier_block *nb, unsigned long val,
+ void *v)
+ {
++ struct memory_notify *mem = (struct memory_notify *)v;
++
+ switch (val) {
+ case MEM_GOING_ONLINE:
+ mutex_lock(&dm_device.ha_region_mutex);
+ break;
+
+ case MEM_ONLINE:
++ dm_device.num_pages_onlined += mem->nr_pages;
+ case MEM_CANCEL_ONLINE:
+ mutex_unlock(&dm_device.ha_region_mutex);
+ if (dm_device.ha_waiting) {
+@@ -570,8 +575,12 @@ static int hv_memory_notifier(struct notifier_block *nb, unsigned long val,
+ }
+ break;
+
+- case MEM_GOING_OFFLINE:
+ case MEM_OFFLINE:
++ mutex_lock(&dm_device.ha_region_mutex);
++ dm_device.num_pages_onlined -= mem->nr_pages;
++ mutex_unlock(&dm_device.ha_region_mutex);
++ break;
++ case MEM_GOING_OFFLINE:
+ case MEM_CANCEL_OFFLINE:
+ break;
+ }
+@@ -896,6 +905,8 @@ static void hot_add_req(struct work_struct *dummy)
+ if (do_hot_add)
+ resp.page_count = process_hot_add(pg_start, pfn_cnt,
+ rg_start, rg_sz);
++
++ dm->num_pages_added += resp.page_count;
+ mutex_unlock(&dm_device.ha_region_mutex);
+ #endif
+ /*
+@@ -1009,17 +1020,21 @@ static void post_status(struct hv_dynmem_device *dm)
+ status.hdr.trans_id = atomic_inc_return(&trans_id);
+
+ /*
+- * The host expects the guest to report free memory.
+- * Further, the host expects the pressure information to
+- * include the ballooned out pages.
+- * For a given amount of memory that we are managing, we
+- * need to compute a floor below which we should not balloon.
+- * Compute this and add it to the pressure report.
++ * The host expects the guest to report free and committed memory.
++ * Furthermore, the host expects the pressure information to include
++ * the ballooned out pages. For a given amount of memory that we are
++ * managing we need to compute a floor below which we should not
++ * balloon. Compute this and add it to the pressure report.
++ * We also need to report all offline pages (num_pages_added -
++ * num_pages_onlined) as committed to the host, otherwise it can try
++ * asking us to balloon them out.
+ */
+ status.num_avail = val.freeram;
+ status.num_committed = vm_memory_committed() +
+- dm->num_pages_ballooned +
+- compute_balloon_floor();
++ dm->num_pages_ballooned +
++ (dm->num_pages_added > dm->num_pages_onlined ?
++ dm->num_pages_added - dm->num_pages_onlined : 0) +
++ compute_balloon_floor();
+
+ /*
+ * If our transaction ID is no longer current, just don't
diff --git a/patches.suse/msft-hv-0765-Drivers-hv-hv_balloon-refuse-to-balloon-below-the-fl.patch b/patches.suse/msft-hv-0765-Drivers-hv-hv_balloon-refuse-to-balloon-below-the-fl.patch
new file mode 100644
index 0000000000..51ff1adf3e
--- /dev/null
+++ b/patches.suse/msft-hv-0765-Drivers-hv-hv_balloon-refuse-to-balloon-below-the-fl.patch
@@ -0,0 +1,48 @@
+From: Vitaly Kuznetsov <vkuznets@redhat.com>
+Date: Sat, 28 Feb 2015 11:39:00 -0800
+Patch-mainline: v4.1-rc1
+Subject: Drivers: hv: hv_balloon: refuse to balloon below the floor
+Git-commit: 530d15b907038735d4cb008dc5caae7ce4dfc985
+References: fate#317533
+
+When host asks us to balloon up we need to be sure we're not committing suicide
+by overballooning. Use already existent 'floor' metric as our lowest possible
+value for free ram.
+
+Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
+Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Acked-by: <ohering@suse.de>
+---
+ drivers/hv/hv_balloon.c | 11 +++++++++++
+ 1 file changed, 11 insertions(+)
+
+diff --git a/drivers/hv/hv_balloon.c b/drivers/hv/hv_balloon.c
+index 53932b3..c5bb872 100644
+--- a/drivers/hv/hv_balloon.c
++++ b/drivers/hv/hv_balloon.c
+@@ -1138,6 +1138,8 @@ static void balloon_up(struct work_struct *dummy)
+ bool alloc_error;
+ bool done = false;
+ int i;
++ struct sysinfo val;
++ unsigned long floor;
+
+ /* The host balloons pages in 2M granularity. */
+ WARN_ON_ONCE(num_pages % PAGES_IN_2M != 0);
+@@ -1148,6 +1150,15 @@ static void balloon_up(struct work_struct *dummy)
+ */
+ alloc_unit = 512;
+
++ si_meminfo(&val);
++ floor = compute_balloon_floor();
++
++ /* Refuse to balloon below the floor, keep the 2M granularity. */
++ if (val.freeram - num_pages < floor) {
++ num_pages = val.freeram > floor ? (val.freeram - floor) : 0;
++ num_pages -= num_pages % PAGES_IN_2M;
++ }
++
+ while (!done) {
+ bl_resp = (struct dm_balloon_response *)send_buffer;
+ memset(send_buffer, 0, PAGE_SIZE);
diff --git a/patches.suse/msft-hv-0766-Drivers-hv-vmbus-Add-support-for-VMBus-panic-notifie.patch b/patches.suse/msft-hv-0766-Drivers-hv-vmbus-Add-support-for-VMBus-panic-notifie.patch
new file mode 100644
index 0000000000..24c3bfdccb
--- /dev/null
+++ b/patches.suse/msft-hv-0766-Drivers-hv-vmbus-Add-support-for-VMBus-panic-notifie.patch
@@ -0,0 +1,113 @@
+From: Nick Meier <nmeier@microsoft.com>
+Date: Sat, 28 Feb 2015 11:39:01 -0800
+Patch-mainline: v4.1-rc1
+Subject: Drivers: hv: vmbus: Add support for VMBus panic notifier handler
+Git-commit: 96c1d0581d00f7abe033350edb021a9d947d8d81
+References: fate#317533
+
+Hyper-V allows a guest to notify the Hyper-V host that a panic
+condition occured. This notification can include up to five 64
+bit values. These 64 bit values are written into crash MSRs.
+Once the data has been written into the crash MSRs, the host is
+then notified by writing into a Crash Control MSR. On the Hyper-V
+host, the panic notification data is captured in the Windows Event
+log as a 18590 event.
+
+Crash MSRs are defined in appendix H of the Hypervisor Top Level
+Functional Specification. At the time of this patch, v4.0 is the
+current functional spec. The URL for the v4.0 document is:
+
+http://download.microsoft.com/download/A/B/4/AB43A34E-BDD0-4FA6-BDEF-79EEF16E880B/Hypervisor Top Level Functional Specification v4.0.docx
+
+Signed-off-by: Nick Meier <nmeier@microsoft.com>
+Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Acked-by: <ohering@suse.de>
+---
+ drivers/hv/hyperv_vmbus.h | 11 +++++++++++
+ drivers/hv/vmbus_drv.c | 36 ++++++++++++++++++++++++++++++++++++
+ 2 files changed, 47 insertions(+)
+
+diff --git a/drivers/hv/hyperv_vmbus.h b/drivers/hv/hyperv_vmbus.h
+index b055e53..88af4ec 100644
+--- a/drivers/hv/hyperv_vmbus.h
++++ b/drivers/hv/hyperv_vmbus.h
+@@ -49,6 +49,17 @@ enum hv_cpuid_function {
+ HVCPUID_IMPLEMENTATION_LIMITS = 0x40000005,
+ };
+
++#define HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE 0x400
++
++#define HV_X64_MSR_CRASH_P0 0x40000100
++#define HV_X64_MSR_CRASH_P1 0x40000101
++#define HV_X64_MSR_CRASH_P2 0x40000102
++#define HV_X64_MSR_CRASH_P3 0x40000103
++#define HV_X64_MSR_CRASH_P4 0x40000104
++#define HV_X64_MSR_CRASH_CTL 0x40000105
++
++#define HV_CRASH_CTL_CRASH_NOTIFY 0x8000000000000000
++
+ /* Define version of the synthetic interrupt controller. */
+ #define HV_SYNIC_VERSION (1)
+
+diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
+index 2b7b51d..526fa8b 100644
+--- a/drivers/hv/vmbus_drv.c
++++ b/drivers/hv/vmbus_drv.c
+@@ -37,6 +37,8 @@
+ #include <asm/hyperv.h>
+ #include <asm/hypervisor.h>
+ #include <asm/mshyperv.h>
++#include <linux/notifier.h>
++#include <linux/ptrace.h>
+ #include "hyperv_vmbus.h"
+
+
+@@ -45,6 +47,31 @@ static struct tasklet_struct msg_dpc;
+ static struct completion probe_event;
+ static int irq;
+
++
++int hyperv_panic_event(struct notifier_block *nb,
++ unsigned long event, void *ptr)
++{
++ struct pt_regs *regs;
++
++ regs = task_pt_regs(current);
++
++ wrmsrl(HV_X64_MSR_CRASH_P0, regs->ip);
++ wrmsrl(HV_X64_MSR_CRASH_P1, regs->ax);
++ wrmsrl(HV_X64_MSR_CRASH_P2, regs->bx);
++ wrmsrl(HV_X64_MSR_CRASH_P3, regs->cx);
++ wrmsrl(HV_X64_MSR_CRASH_P4, regs->dx);
++
++ /*
++ * Let Hyper-V know there is crash data available
++ */
++ wrmsrl(HV_X64_MSR_CRASH_CTL, HV_CRASH_CTL_CRASH_NOTIFY);
++ return NOTIFY_DONE;
++}
++
++static struct notifier_block hyperv_panic_block = {
++ .notifier_call = hyperv_panic_event,
++};
++
+ struct resource hyperv_mmio = {
+ .name = "hyperv mmio",
+ .flags = IORESOURCE_MEM,
+@@ -795,6 +822,15 @@ static int vmbus_bus_init(int irq)
+ goto err_alloc;
+
+ hv_cpu_hotplug_quirk(true);
++
++ /*
++ * Only register if the crash MSRs are available
++ */
++ if (ms_hyperv.features & HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE) {
++ atomic_notifier_chain_register(&panic_notifier_list,
++ &hyperv_panic_block);
++ }
++
+ vmbus_request_offers();
+
+ return 0;
diff --git a/patches.suse/msft-hv-0767-Drivers-hv-vmbus-Use-a-round-robin-algorithm-for-pic.patch b/patches.suse/msft-hv-0767-Drivers-hv-vmbus-Use-a-round-robin-algorithm-for-pic.patch
new file mode 100644
index 0000000000..02ae86bf72
--- /dev/null
+++ b/patches.suse/msft-hv-0767-Drivers-hv-vmbus-Use-a-round-robin-algorithm-for-pic.patch
@@ -0,0 +1,101 @@
+From: "K. Y. Srinivasan" <kys@microsoft.com>
+Date: Sat, 28 Feb 2015 11:39:02 -0800
+Patch-mainline: v4.1-rc1
+Subject: Drivers: hv: vmbus: Use a round-robin algorithm for picking the outgoing channel
+Git-commit: a13e8bbe851a96a0e78c2bd599bc34082fa697cd
+References: fate#317533
+
+The current algorithm for picking an outgoing channel was not distributing
+the load well. Implement a simple round-robin scheme to ensure good
+distribution of the outgoing traffic.
+
+Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
+Reviewed-by: Long Li <longli@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Acked-by: <ohering@suse.de>
+---
+ drivers/hv/channel_mgmt.c | 30 +++++++++++++++---------------
+ include/linux/hyperv.h | 3 +++
+ 2 files changed, 18 insertions(+), 15 deletions(-)
+
+diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c
+index b1e5a5f..6117891 100644
+--- a/drivers/hv/channel_mgmt.c
++++ b/drivers/hv/channel_mgmt.c
+@@ -350,6 +350,7 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel)
+ }
+
+ newchannel->state = CHANNEL_OPEN_STATE;
++ channel->num_sc++;
+ if (channel->sc_creation_callback != NULL)
+ /*
+ * We need to invoke the sub-channel creation
+@@ -862,9 +863,8 @@ cleanup:
+
+ /*
+ * Retrieve the (sub) channel on which to send an outgoing request.
+- * When a primary channel has multiple sub-channels, we choose a
+- * channel whose VCPU binding is closest to the VCPU on which
+- * this call is being made.
++ * When a primary channel has multiple sub-channels, we try to
++ * distribute the load equally amongst all available channels.
+ */
+ struct vmbus_channel *vmbus_get_outgoing_channel(struct vmbus_channel *primary)
+ {
+@@ -872,11 +872,19 @@ struct vmbus_channel *vmbus_get_outgoing_channel(struct vmbus_channel *primary)
+ int cur_cpu;
+ struct vmbus_channel *cur_channel;
+ struct vmbus_channel *outgoing_channel = primary;
+- int cpu_distance, new_cpu_distance;
++ int next_channel;
++ int i = 1;
+
+ if (list_empty(&primary->sc_list))
+ return outgoing_channel;
+
++ next_channel = primary->next_oc++;
++
++ if (next_channel > (primary->num_sc)) {
++ primary->next_oc = 0;
++ return outgoing_channel;
++ }
++
+ cur_cpu = hv_context.vp_index[get_cpu()];
+ put_cpu();
+ list_for_each_safe(cur, tmp, &primary->sc_list) {
+@@ -887,18 +895,10 @@ struct vmbus_channel *vmbus_get_outgoing_channel(struct vmbus_channel *primary)
+ if (cur_channel->target_vp == cur_cpu)
+ return cur_channel;
+
+- cpu_distance = ((outgoing_channel->target_vp > cur_cpu) ?
+- (outgoing_channel->target_vp - cur_cpu) :
+- (cur_cpu - outgoing_channel->target_vp));
+-
+- new_cpu_distance = ((cur_channel->target_vp > cur_cpu) ?
+- (cur_channel->target_vp - cur_cpu) :
+- (cur_cpu - cur_channel->target_vp));
+-
+- if (cpu_distance < new_cpu_distance)
+- continue;
++ if (i == next_channel)
++ return cur_channel;
+
+- outgoing_channel = cur_channel;
++ i++;
+ }
+
+ return outgoing_channel;
+diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
+index dd92a85..1ca5824 100644
+--- a/include/linux/hyperv.h
++++ b/include/linux/hyperv.h
+@@ -761,6 +761,9 @@ struct vmbus_channel {
+ * link up channels based on their CPU affinity.
+ */
+ struct list_head percpu_list;
++
++ int num_sc;
++ int next_oc;
+ };
+
+ static inline void set_channel_read_state(struct vmbus_channel *c, bool state)
diff --git a/patches.suse/msft-hv-0768-Drivers-hv-vmbus-Suport-an-API-to-send-pagebuffers-w.patch b/patches.suse/msft-hv-0768-Drivers-hv-vmbus-Suport-an-API-to-send-pagebuffers-w.patch
new file mode 100644
index 0000000000..b2d1d5baa4
--- /dev/null
+++ b/patches.suse/msft-hv-0768-Drivers-hv-vmbus-Suport-an-API-to-send-pagebuffers-w.patch
@@ -0,0 +1,104 @@
+From: "K. Y. Srinivasan" <kys@microsoft.com>
+Date: Sat, 28 Feb 2015 11:39:03 -0800
+Patch-mainline: v4.1-rc1
+Subject: Drivers: hv: vmbus: Suport an API to send pagebuffers with additional control
+Git-commit: 87e93d61708fe2c44875d1ecdb174aad070dbd08
+References: fate#317533
+
+Implement an API for sending pagebuffers that gives more control to the client
+in terms of setting the vmbus flags as well as deciding when to
+notify the host. This will be useful for enabling batch processing.
+
+Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Acked-by: <ohering@suse.de>
+---
+ drivers/hv/channel.c | 33 +++++++++++++++++++++++++++------
+ include/linux/hyperv.h | 9 +++++++++
+ 2 files changed, 36 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c
+index 9b79aca..f060d1f 100644
+--- a/drivers/hv/channel.c
++++ b/drivers/hv/channel.c
+@@ -636,13 +636,18 @@ int vmbus_sendpacket(struct vmbus_channel *channel, void *buffer,
+ EXPORT_SYMBOL(vmbus_sendpacket);
+
+ /*
+- * vmbus_sendpacket_pagebuffer - Send a range of single-page buffer
+- * packets using a GPADL Direct packet type.
++ * vmbus_sendpacket_pagebuffer_ctl - Send a range of single-page buffer
++ * packets using a GPADL Direct packet type. This interface allows you
++ * to control notifying the host. This will be useful for sending
++ * batched data. Also the sender can control the send flags
++ * explicitly.
+ */
+-int vmbus_sendpacket_pagebuffer(struct vmbus_channel *channel,
++int vmbus_sendpacket_pagebuffer_ctl(struct vmbus_channel *channel,
+ struct hv_page_buffer pagebuffers[],
+ u32 pagecount, void *buffer, u32 bufferlen,
+- u64 requestid)
++ u64 requestid,
++ u32 flags,
++ bool kick_q)
+ {
+ int ret;
+ int i;
+@@ -670,7 +675,7 @@ int vmbus_sendpacket_pagebuffer(struct vmbus_channel *channel,
+
+ /* Setup the descriptor */
+ desc.type = VM_PKT_DATA_USING_GPA_DIRECT;
+- desc.flags = VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED;
++ desc.flags = flags;
+ desc.dataoffset8 = descsize >> 3; /* in 8-bytes grandularity */
+ desc.length8 = (u16)(packetlen_aligned >> 3);
+ desc.transactionid = requestid;
+@@ -691,11 +696,27 @@ int vmbus_sendpacket_pagebuffer(struct vmbus_channel *channel,
+
+ ret = hv_ringbuffer_write(&channel->outbound, bufferlist, 3, &signal);
+
+- if (ret == 0 && signal)
++ if ((ret == 0) && kick_q && signal)
+ vmbus_setevent(channel);
+
+ return ret;
+ }
++
++/*
++ * vmbus_sendpacket_pagebuffer - Send a range of single-page buffer
++ * packets using a GPADL Direct packet type.
++ */
++int vmbus_sendpacket_pagebuffer(struct vmbus_channel *channel,
++ struct hv_page_buffer pagebuffers[],
++ u32 pagecount, void *buffer, u32 bufferlen,
++ u64 requestid)
++{
++ u32 flags = VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED;
++ return vmbus_sendpacket_pagebuffer_ctl(channel, pagebuffers, pagecount,
++ buffer, bufferlen, requestid,
++ flags, true);
++
++}
+ EXPORT_SYMBOL_GPL(vmbus_sendpacket_pagebuffer);
+
+ /*
+diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
+index 1ca5824..86e1a7a 100644
+--- a/include/linux/hyperv.h
++++ b/include/linux/hyperv.h
+@@ -874,6 +874,15 @@ extern int vmbus_sendpacket_pagebuffer(struct vmbus_channel *channel,
+ u32 bufferlen,
+ u64 requestid);
+
++extern int vmbus_sendpacket_pagebuffer_ctl(struct vmbus_channel *channel,
++ struct hv_page_buffer pagebuffers[],
++ u32 pagecount,
++ void *buffer,
++ u32 bufferlen,
++ u64 requestid,
++ u32 flags,
++ bool kick_q);
++
+ extern int vmbus_sendpacket_multipagebuffer(struct vmbus_channel *channel,
+ struct hv_multipage_buffer *mpb,
+ void *buffer,
diff --git a/patches.suse/msft-hv-0769-Drivers-hv-vmbus-Suport-an-API-to-send-packet-with-a.patch b/patches.suse/msft-hv-0769-Drivers-hv-vmbus-Suport-an-API-to-send-packet-with-a.patch
new file mode 100644
index 0000000000..49ecc72841
--- /dev/null
+++ b/patches.suse/msft-hv-0769-Drivers-hv-vmbus-Suport-an-API-to-send-packet-with-a.patch
@@ -0,0 +1,104 @@
+From: "K. Y. Srinivasan" <kys@microsoft.com>
+Date: Sat, 28 Feb 2015 11:39:04 -0800
+Patch-mainline: v4.1-rc1
+Subject: Drivers: hv: vmbus: Suport an API to send packet with additional control
+Git-commit: e9395e3f8952110bda60b54ad03ec52c6e9c7dbd
+References: fate#317533
+
+Implement an API that gives additional control on the what VMBUS flags will be
+set as well as if the host needs to be signalled. This API will be
+useful for clients that want to batch up requests to the host.
+
+Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Acked-by: <ohering@suse.de>
+---
+ drivers/hv/channel.c | 43 ++++++++++++++++++++++++++-----------------
+ include/linux/hyperv.h | 8 ++++++++
+ 2 files changed, 34 insertions(+), 17 deletions(-)
+
+diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c
+index f060d1f..da53180 100644
+--- a/drivers/hv/channel.c
++++ b/drivers/hv/channel.c
+@@ -584,23 +584,9 @@ void vmbus_close(struct vmbus_channel *channel)
+ }
+ EXPORT_SYMBOL_GPL(vmbus_close);
+
+-/**
+- * vmbus_sendpacket() - Send the specified buffer on the given channel
+- * @channel: Pointer to vmbus_channel structure.
+- * @buffer: Pointer to the buffer you want to receive the data into.
+- * @bufferlen: Maximum size of what the the buffer will hold
+- * @requestid: Identifier of the request
+- * @type: Type of packet that is being send e.g. negotiate, time
+- * packet etc.
+- *
+- * Sends data in @buffer directly to hyper-v via the vmbus
+- * This will send the data unparsed to hyper-v.
+- *
+- * Mainly used by Hyper-V drivers.
+- */
+-int vmbus_sendpacket(struct vmbus_channel *channel, void *buffer,
++int vmbus_sendpacket_ctl(struct vmbus_channel *channel, void *buffer,
+ u32 bufferlen, u64 requestid,
+- enum vmbus_packet_type type, u32 flags)
++ enum vmbus_packet_type type, u32 flags, bool kick_q)
+ {
+ struct vmpacket_descriptor desc;
+ u32 packetlen = sizeof(struct vmpacket_descriptor) + bufferlen;
+@@ -628,11 +614,34 @@ int vmbus_sendpacket(struct vmbus_channel *channel, void *buffer,
+
+ ret = hv_ringbuffer_write(&channel->outbound, bufferlist, 3, &signal);
+
+- if (ret == 0 && signal)
++ if ((ret == 0) && kick_q && signal)
+ vmbus_setevent(channel);
+
+ return ret;
+ }
++EXPORT_SYMBOL(vmbus_sendpacket_ctl);
++
++/**
++ * vmbus_sendpacket() - Send the specified buffer on the given channel
++ * @channel: Pointer to vmbus_channel structure.
++ * @buffer: Pointer to the buffer you want to receive the data into.
++ * @bufferlen: Maximum size of what the the buffer will hold
++ * @requestid: Identifier of the request
++ * @type: Type of packet that is being send e.g. negotiate, time
++ * packet etc.
++ *
++ * Sends data in @buffer directly to hyper-v via the vmbus
++ * This will send the data unparsed to hyper-v.
++ *
++ * Mainly used by Hyper-V drivers.
++ */
++int vmbus_sendpacket(struct vmbus_channel *channel, void *buffer,
++ u32 bufferlen, u64 requestid,
++ enum vmbus_packet_type type, u32 flags)
++{
++ return vmbus_sendpacket_ctl(channel, buffer, bufferlen, requestid,
++ type, flags, true);
++}
+ EXPORT_SYMBOL(vmbus_sendpacket);
+
+ /*
+diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
+index 86e1a7a..80e444b 100644
+--- a/include/linux/hyperv.h
++++ b/include/linux/hyperv.h
+@@ -867,6 +867,14 @@ extern int vmbus_sendpacket(struct vmbus_channel *channel,
+ enum vmbus_packet_type type,
+ u32 flags);
+
++extern int vmbus_sendpacket_ctl(struct vmbus_channel *channel,
++ void *buffer,
++ u32 bufferLen,
++ u64 requestid,
++ enum vmbus_packet_type type,
++ u32 flags,
++ bool kick_q);
++
+ extern int vmbus_sendpacket_pagebuffer(struct vmbus_channel *channel,
+ struct hv_page_buffer pagebuffers[],
+ u32 pagecount,
diff --git a/patches.suse/msft-hv-0770-mei-bus-can-be-static.patch b/patches.suse/msft-hv-0770-mei-bus-can-be-static.patch
new file mode 100644
index 0000000000..0c174e7d98
--- /dev/null
+++ b/patches.suse/msft-hv-0770-mei-bus-can-be-static.patch
@@ -0,0 +1,32 @@
+From: kbuild test robot <fengguang.wu@intel.com>
+Date: Mon, 2 Mar 2015 11:49:23 +0800
+Patch-mainline: v4.1-rc1
+Subject: mei: bus: () can be static
+Git-commit: ed99d846f1774e14c8705819c12469eb3855b54e
+References: fate#317533
+
+drivers/hv/vmbus_drv.c:51:5: sparse: symbol 'hyperv_panic_event' was not declared. Should it be static?
+drivers/hv/vmbus_drv.c:51:5: sparse: symbol 'hyperv_panic_event' was not declared. Should it be static?
+drivers/hv/vmbus_drv.c:51:5: sparse: symbol 'hyperv_panic_event' was not declared. Should it be static?
+drivers/hv/vmbus_drv.c:51:5: sparse: symbol 'hyperv_panic_event' was not declared. Should it be static?
+
+Signed-off-by: Fengguang Wu <fengguang.wu@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Acked-by: <ohering@suse.de>
+---
+ drivers/hv/vmbus_drv.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
+index 526fa8b..8313e25 100644
+--- a/drivers/hv/vmbus_drv.c
++++ b/drivers/hv/vmbus_drv.c
+@@ -48,7 +48,7 @@ static struct completion probe_event;
+ static int irq;
+
+
+-int hyperv_panic_event(struct notifier_block *nb,
++static int hyperv_panic_event(struct notifier_block *nb,
+ unsigned long event, void *ptr)
+ {
+ struct pt_regs *regs;
diff --git a/patches.suse/msft-hv-0771-hyperv-hyperv_fb-match-wait_for_completion_timeout-r.patch b/patches.suse/msft-hv-0771-hyperv-hyperv_fb-match-wait_for_completion_timeout-r.patch
new file mode 100644
index 0000000000..cc2bb222ef
--- /dev/null
+++ b/patches.suse/msft-hv-0771-hyperv-hyperv_fb-match-wait_for_completion_timeout-r.patch
@@ -0,0 +1,42 @@
+From: Nicholas Mc Guire <der.herr@hofr.at>
+Date: Thu, 29 Jan 2015 11:24:16 +0100
+Patch-mainline: v4.1-rc1
+Subject: hyperv: hyperv_fb: match wait_for_completion_timeout return type
+Git-commit: 7dea97e0379dbb2983a9f009c7cdaeb6bbe4c98e
+References: fate#317533
+
+The return type of wait_for_completion_timeout is unsigned long not
+int. This patch fixes up the declarations only.
+
+Signed-off-by: Nicholas Mc Guire <der.herr@hofr.at>
+Reviewed-by: Vitaly Kuznetsov <vkuznets@redhat.com>
+Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
+Acked-by: <ohering@suse.de>
+---
+ drivers/video/hyperv_fb.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/video/hyperv_fb.c b/drivers/video/hyperv_fb.c
+index 4254336..807ee22 100644
+--- a/drivers/video/hyperv_fb.c
++++ b/drivers/video/hyperv_fb.c
+@@ -415,7 +415,8 @@ static int synthvid_negotiate_ver(struct hv_device *hdev, u32 ver)
+ struct fb_info *info = hv_get_drvdata(hdev);
+ struct hvfb_par *par = info->par;
+ struct synthvid_msg *msg = (struct synthvid_msg *)par->init_buf;
+- int t, ret = 0;
++ int ret = 0;
++ unsigned long t;
+
+ memset(msg, 0, sizeof(struct synthvid_msg));
+ msg->vid_hdr.type = SYNTHVID_VERSION_REQUEST;
+@@ -488,7 +489,8 @@ static int synthvid_send_config(struct hv_device *hdev)
+ struct fb_info *info = hv_get_drvdata(hdev);
+ struct hvfb_par *par = info->par;
+ struct synthvid_msg *msg = (struct synthvid_msg *)par->init_buf;
+- int t, ret = 0;
++ int ret = 0;
++ unsigned long t;
+
+ /* Send VRAM location */
+ memset(msg, 0, sizeof(struct synthvid_msg));
diff --git a/patches.suse/msft-hv-0772-Drivers-hv-vmbus-Perform-device-register-in-the-per-.patch b/patches.suse/msft-hv-0772-Drivers-hv-vmbus-Perform-device-register-in-the-per-.patch
new file mode 100644
index 0000000000..0fed24b283
--- /dev/null
+++ b/patches.suse/msft-hv-0772-Drivers-hv-vmbus-Perform-device-register-in-the-per-.patch
@@ -0,0 +1,281 @@
+From: "K. Y. Srinivasan" <kys@microsoft.com>
+Date: Wed, 18 Mar 2015 12:29:21 -0700
+Patch-mainline: v4.1-rc1
+Subject: Drivers: hv: vmbus: Perform device register in the per-channel work element
+Git-commit: fde25d25dbd997067058f7d4c2ff31600157e6f2
+References: fate#317533
+
+This patch is a continuation of the rescind handling cleanup work. We cannot
+block in the global message handling work context especially if we are blocking
+waiting for the host to wake us up. I would like to thank
+Dexuan Cui <decui@microsoft.com> for observing this problem.
+
+The current char-next branch is broken and this patch fixes
+the bug.
+
+Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Acked-by: <ohering@suse.de>
+---
+ drivers/hv/channel_mgmt.c | 143 ++++++++++++++++++++++++++++++++--------------
+ drivers/hv/connection.c | 6 +-
+ drivers/hv/hyperv_vmbus.h | 2 +-
+ 3 files changed, 107 insertions(+), 44 deletions(-)
+
+diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c
+index 6117891..5f8e47b 100644
+--- a/drivers/hv/channel_mgmt.c
++++ b/drivers/hv/channel_mgmt.c
+@@ -23,6 +23,7 @@
+ #include <linux/kernel.h>
+ #include <linux/sched.h>
+ #include <linux/wait.h>
++#include <linux/delay.h>
+ #include <linux/mm.h>
+ #include <linux/slab.h>
+ #include <linux/list.h>
+@@ -37,6 +38,10 @@ struct vmbus_channel_message_table_entry {
+ void (*message_handler)(struct vmbus_channel_message_header *msg);
+ };
+
++struct vmbus_rescind_work {
++ struct work_struct work;
++ struct vmbus_channel *channel;
++};
+
+ /**
+ * vmbus_prep_negotiate_resp() - Create default response for Hyper-V Negotiate message
+@@ -134,20 +139,6 @@ fw_error:
+
+ EXPORT_SYMBOL_GPL(vmbus_prep_negotiate_resp);
+
+-static void vmbus_process_device_unregister(struct work_struct *work)
+-{
+- struct device *dev;
+- struct vmbus_channel *channel = container_of(work,
+- struct vmbus_channel,
+- work);
+-
+- dev = get_device(&channel->device_obj->device);
+- if (dev) {
+- vmbus_device_unregister(channel->device_obj);
+- put_device(dev);
+- }
+-}
+-
+ static void vmbus_sc_creation_cb(struct work_struct *work)
+ {
+ struct vmbus_channel *newchannel = container_of(work,
+@@ -220,6 +211,40 @@ static void free_channel(struct vmbus_channel *channel)
+ queue_work(vmbus_connection.work_queue, &channel->work);
+ }
+
++static void process_rescind_fn(struct work_struct *work)
++{
++ struct vmbus_rescind_work *rc_work;
++ struct vmbus_channel *channel;
++ struct device *dev;
++
++ rc_work = container_of(work, struct vmbus_rescind_work, work);
++ channel = rc_work->channel;
++
++ /*
++ * We have already acquired a reference on the channel
++ * and so it cannot vanish underneath us.
++ * It is possible (while very unlikely) that we may
++ * get here while the processing of the initial offer
++ * is still not complete. Deal with this situation by
++ * just waiting until the channel is in the correct state.
++ */
++
++ while (channel->work.func != release_channel)
++ msleep(1000);
++
++ if (channel->device_obj) {
++ dev = get_device(&channel->device_obj->device);
++ if (dev) {
++ vmbus_device_unregister(channel->device_obj);
++ put_device(dev);
++ }
++ } else {
++ hv_process_channel_removal(channel,
++ channel->offermsg.child_relid);
++ }
++ kfree(work);
++}
++
+ static void percpu_channel_enq(void *arg)
+ {
+ struct vmbus_channel *channel = arg;
+@@ -282,6 +307,46 @@ void vmbus_free_channels(void)
+ }
+ }
+
++static void vmbus_do_device_register(struct work_struct *work)
++{
++ struct hv_device *device_obj;
++ int ret;
++ unsigned long flags;
++ struct vmbus_channel *newchannel = container_of(work,
++ struct vmbus_channel,
++ work);
++
++ ret = vmbus_device_register(newchannel->device_obj);
++ if (ret != 0) {
++ pr_err("unable to add child device object (relid %d)\n",
++ newchannel->offermsg.child_relid);
++ spin_lock_irqsave(&vmbus_connection.channel_lock, flags);
++ list_del(&newchannel->listentry);
++ device_obj = newchannel->device_obj;
++ newchannel->device_obj = NULL;
++ spin_unlock_irqrestore(&vmbus_connection.channel_lock, flags);
++
++ 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();
++ }
++
++ kfree(device_obj);
++ if (!newchannel->rescind) {
++ free_channel(newchannel);
++ return;
++ }
++ }
++ /*
++ * The next state for this channel is to be freed.
++ */
++ INIT_WORK(&newchannel->work, release_channel);
++}
++
+ /*
+ * vmbus_process_offer - Process the offer by creating a channel/device
+ * associated with this offer
+@@ -291,7 +356,6 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel)
+ struct vmbus_channel *channel;
+ bool fnew = true;
+ bool enq = false;
+- int ret;
+ unsigned long flags;
+
+ /* Make sure this is a new offer */
+@@ -393,16 +457,13 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel)
+ * Add the new device to the bus. This will kick off device-driver
+ * binding which eventually invokes the device driver's AddDevice()
+ * method.
++ * Invoke this call on the per-channel work context.
++ * Until we return from this function, rescind offer message
++ * cannot be processed as we are running on the global message
++ * handling work.
+ */
+- ret = vmbus_device_register(newchannel->device_obj);
+- if (ret != 0) {
+- pr_err("unable to add child device object (relid %d)\n",
+- newchannel->offermsg.child_relid);
+-
+- kfree(newchannel->device_obj);
+- goto err_deq_chan;
+- }
+-
++ INIT_WORK(&newchannel->work, vmbus_do_device_register);
++ queue_work(newchannel->controlwq, &newchannel->work);
+ return;
+
+ err_deq_chan:
+@@ -556,33 +617,31 @@ static void vmbus_onoffer_rescind(struct vmbus_channel_message_header *hdr)
+ {
+ struct vmbus_channel_rescind_offer *rescind;
+ struct vmbus_channel *channel;
+- unsigned long flags;
++ struct vmbus_rescind_work *rc_work;
+
+ rescind = (struct vmbus_channel_rescind_offer *)hdr;
+- channel = relid2channel(rescind->child_relid);
++ channel = relid2channel(rescind->child_relid, true);
+
+ if (channel == NULL) {
+ hv_process_channel_removal(NULL, rescind->child_relid);
+ return;
+ }
+
+- spin_lock_irqsave(&channel->lock, flags);
+- channel->rescind = true;
+- spin_unlock_irqrestore(&channel->lock, flags);
+-
+- if (channel->device_obj) {
+- /*
+- * We will have to unregister this device from the
+- * driver core. Do this in the per-channel work context.
+- * Note that we are currently executing on the global
+- * workq for handling messages from the host.
+- */
+- INIT_WORK(&channel->work, vmbus_process_device_unregister);
+- queue_work(channel->controlwq, &channel->work);
+- } else {
+- hv_process_channel_removal(channel,
+- channel->offermsg.child_relid);
++ /*
++ * We have acquired a reference on the channel and have posted
++ * the rescind state. Perform further cleanup in a work context
++ * that is different from the global work context in which
++ * we process messages from the host (we are currently executing
++ * on that global context.
++ */
++ rc_work = kzalloc(sizeof(struct vmbus_rescind_work), GFP_KERNEL);
++ if (!rc_work) {
++ pr_err("Unable to allocate memory for rescind processing ");
++ return;
+ }
++ rc_work->channel = channel;
++ INIT_WORK(&rc_work->work, process_rescind_fn);
++ schedule_work(&rc_work->work);
+ }
+
+ /*
+diff --git a/drivers/hv/connection.c b/drivers/hv/connection.c
+index 583d7d4..8bcd307 100644
+--- a/drivers/hv/connection.c
++++ b/drivers/hv/connection.c
+@@ -270,7 +270,7 @@ static struct vmbus_channel *pcpu_relid2channel(u32 relid)
+ * relid2channel - Get the channel object given its
+ * child relative id (ie channel id)
+ */
+-struct vmbus_channel *relid2channel(u32 relid)
++struct vmbus_channel *relid2channel(u32 relid, bool rescind)
+ {
+ struct vmbus_channel *channel;
+ struct vmbus_channel *found_channel = NULL;
+@@ -282,6 +282,8 @@ struct vmbus_channel *relid2channel(u32 relid)
+ list_for_each_entry(channel, &vmbus_connection.chn_list, listentry) {
+ if (channel->offermsg.child_relid == relid) {
+ found_channel = channel;
++ if (rescind)
++ found_channel->rescind = true;
+ break;
+ } else if (!list_empty(&channel->sc_list)) {
+ /*
+@@ -292,6 +294,8 @@ struct vmbus_channel *relid2channel(u32 relid)
+ sc_list);
+ if (cur_sc->offermsg.child_relid == relid) {
+ found_channel = cur_sc;
++ if (rescind)
++ found_channel->rescind = true;
+ break;
+ }
+ }
+diff --git a/drivers/hv/hyperv_vmbus.h b/drivers/hv/hyperv_vmbus.h
+index 88af4ec..6339589 100644
+--- a/drivers/hv/hyperv_vmbus.h
++++ b/drivers/hv/hyperv_vmbus.h
+@@ -698,7 +698,7 @@ void vmbus_device_unregister(struct hv_device *device_obj);
+ /* VmbusChildDeviceDestroy( */
+ /* struct hv_device *); */
+
+-struct vmbus_channel *relid2channel(u32 relid);
++struct vmbus_channel *relid2channel(u32 relid, bool rescind);
+
+ void vmbus_free_channels(void);
+
diff --git a/patches.suse/msft-hv-0773-Drivers-hv-hv_balloon-keep-locks-balanced-on-add_mem.patch b/patches.suse/msft-hv-0773-Drivers-hv-hv_balloon-keep-locks-balanced-on-add_mem.patch
new file mode 100644
index 0000000000..8046e3d48b
--- /dev/null
+++ b/patches.suse/msft-hv-0773-Drivers-hv-hv_balloon-keep-locks-balanced-on-add_mem.patch
@@ -0,0 +1,45 @@
+From: Vitaly Kuznetsov <vkuznets@redhat.com>
+Date: Wed, 18 Mar 2015 12:29:22 -0700
+Patch-mainline: v4.1-rc1
+Subject: Drivers: hv: hv_balloon: keep locks balanced on add_memory() failure
+Git-commit: f3f6eb80872becdbce07f7d2670d3f8ae5119752
+References: fate#317533
+
+When add_memory() fails the following BUG is observed:
+[ 743.646107] hv_balloon: hot_add memory failed error is -17
+[ 743.679973]
+[ 743.680930] =====================================
+[ 743.680930] [ BUG: bad unlock balance detected! ]
+[ 743.680930] 3.19.0-rc5_bug1131426+ #552 Not tainted
+[ 743.680930] -------------------------------------
+[ 743.680930] kworker/0:2/255 is trying to release lock (&dm_device.ha_region_mutex) at:
+[ 743.680930] [<ffffffff81aae5fe>] mutex_unlock+0xe/0x10
+[ 743.680930] but there are no more locks to release!
+
+This happens as we don't acquire ha_region_mutex and hot_add_req() expects us
+to as it does unconditional mutex_unlock(). Acquire the lock on the error path.
+
+The current char-next branch is broken and this patch fixes
+the bug.
+
+Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
+Acked-by: Jason Wang <jasowang@redhat.com>
+Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Acked-by: <ohering@suse.de>
+---
+ drivers/hv/hv_balloon.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/hv/hv_balloon.c b/drivers/hv/hv_balloon.c
+index c5bb872..f1f17c5 100644
+--- a/drivers/hv/hv_balloon.c
++++ b/drivers/hv/hv_balloon.c
+@@ -652,6 +652,7 @@ static void hv_mem_hot_add(unsigned long start, unsigned long size,
+ }
+ has->ha_end_pfn -= HA_CHUNK;
+ has->covered_end_pfn -= processed_pfn;
++ mutex_lock(&dm_device.ha_region_mutex);
+ break;
+ }
+
diff --git a/patches.suse/msft-hv-0774-Drivers-hv-hv_balloon-don-t-lose-memory-when-onlinin.patch b/patches.suse/msft-hv-0774-Drivers-hv-hv_balloon-don-t-lose-memory-when-onlinin.patch
new file mode 100644
index 0000000000..a75772b885
--- /dev/null
+++ b/patches.suse/msft-hv-0774-Drivers-hv-hv_balloon-don-t-lose-memory-when-onlinin.patch
@@ -0,0 +1,132 @@
+From: Vitaly Kuznetsov <vkuznets@redhat.com>
+Date: Wed, 18 Mar 2015 12:29:23 -0700
+Patch-mainline: v4.1-rc1
+Subject: Drivers: hv: hv_balloon: don't lose memory when onlining order is not natural
+Git-commit: 5abbbb75d733793b1637441691de95b7665cee85
+References: fate#317533
+
+Memory blocks can be onlined in random order. When this order is not natural
+some memory pages are not onlined because of the redundant check in
+hv_online_page().
+
+Here is a real world scenario:
+1) Host tries to hot-add the following (process_hot_add):
+ pg_start=rg_start=0x48000, pfn_cnt=111616, rg_size=262144
+
+2) This results in adding 4 memory blocks:
+[ 109.057866] init_memory_mapping: [mem 0x48000000-0x4fffffff]
+[ 114.102698] init_memory_mapping: [mem 0x50000000-0x57ffffff]
+[ 119.168039] init_memory_mapping: [mem 0x58000000-0x5fffffff]
+[ 124.233053] init_memory_mapping: [mem 0x60000000-0x67ffffff]
+The last one is incomplete but we have special has->covered_end_pfn counter to
+avoid onlining non-backed frames and hv_bring_pgs_online() function to bring
+them online later on.
+
+3) Now we have 4 offline memory blocks: /sys/devices/system/memory/memory9-12
+$ for f in /sys/devices/system/memory/memory*/state; do echo $f `cat $f`; done | grep -v onlin
+/sys/devices/system/memory/memory10/state offline
+/sys/devices/system/memory/memory11/state offline
+/sys/devices/system/memory/memory12/state offline
+/sys/devices/system/memory/memory9/state offline
+
+4) We bring them online in non-natural order:
+$grep MemTotal /proc/meminfo
+MemTotal: 966348 kB
+$echo online > /sys/devices/system/memory/memory12/state && grep MemTotal /proc/meminfo
+MemTotal: 1019596 kB
+$echo online > /sys/devices/system/memory/memory11/state && grep MemTotal /proc/meminfo
+MemTotal: 1150668 kB
+$echo online > /sys/devices/system/memory/memory9/state && grep MemTotal /proc/meminfo
+MemTotal: 1150668 kB
+
+As you can see memory9 block gives us zero additional memory. We can also
+observe a huge discrepancy between host- and guest-reported memory sizes.
+
+The root cause of the issue is the redundant pg >= covered_start_pfn check (and
+covered_start_pfn advancing) in hv_online_page(). When upper memory block in
+being onlined before the lower one (memory12 and memory11 in the above case) we
+advance the covered_start_pfn pointer and all memory9 pages do not pass the
+check. If the assumption that host always gives us requests in sequential order
+and pg_start always equals rg_start when the first request for the new HA
+region is received (that's the case in my testing) is correct than we can get
+rid of covered_start_pfn and pg >= start_pfn check in hv_online_page() is
+sufficient.
+
+The current char-next branch is broken and this patch fixes
+the bug.
+
+Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
+Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Acked-by: <ohering@suse.de>
+---
+ drivers/hv/hv_balloon.c | 14 ++++----------
+ 1 file changed, 4 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/hv/hv_balloon.c b/drivers/hv/hv_balloon.c
+index f1f17c5..014256a 100644
+--- a/drivers/hv/hv_balloon.c
++++ b/drivers/hv/hv_balloon.c
+@@ -428,14 +428,13 @@ struct dm_info_msg {
+ * currently hot added. We hot add in multiples of 128M
+ * chunks; it is possible that we may not be able to bring
+ * online all the pages in the region. The range
+- * covered_start_pfn : covered_end_pfn defines the pages that can
++ * covered_end_pfn defines the pages that can
+ * be brough online.
+ */
+
+ struct hv_hotadd_state {
+ struct list_head list;
+ unsigned long start_pfn;
+- unsigned long covered_start_pfn;
+ unsigned long covered_end_pfn;
+ unsigned long ha_end_pfn;
+ unsigned long end_pfn;
+@@ -679,8 +678,7 @@ static void hv_online_page(struct page *pg)
+
+ list_for_each(cur, &dm_device.ha_region_list) {
+ has = list_entry(cur, struct hv_hotadd_state, list);
+- cur_start_pgp = (unsigned long)
+- pfn_to_page(has->covered_start_pfn);
++ cur_start_pgp = (unsigned long)pfn_to_page(has->start_pfn);
+ cur_end_pgp = (unsigned long)pfn_to_page(has->covered_end_pfn);
+
+ if (((unsigned long)pg >= cur_start_pgp) &&
+@@ -692,7 +690,6 @@ static void hv_online_page(struct page *pg)
+ __online_page_set_limits(pg);
+ __online_page_increment_counters(pg);
+ __online_page_free(pg);
+- has->covered_start_pfn++;
+ }
+ }
+ }
+@@ -736,10 +733,9 @@ static bool pfn_covered(unsigned long start_pfn, unsigned long pfn_cnt)
+ * is, update it.
+ */
+
+- if (has->covered_end_pfn != start_pfn) {
++ if (has->covered_end_pfn != start_pfn)
+ has->covered_end_pfn = start_pfn;
+- has->covered_start_pfn = start_pfn;
+- }
++
+ return true;
+
+ }
+@@ -784,7 +780,6 @@ static unsigned long handle_pg_range(unsigned long pg_start,
+ pgs_ol = pfn_cnt;
+ hv_bring_pgs_online(start_pfn, pgs_ol);
+ has->covered_end_pfn += pgs_ol;
+- has->covered_start_pfn += pgs_ol;
+ pfn_cnt -= pgs_ol;
+ }
+
+@@ -845,7 +840,6 @@ static unsigned long process_hot_add(unsigned long pg_start,
+ list_add_tail(&ha_region->list, &dm_device.ha_region_list);
+ ha_region->start_pfn = rg_start;
+ ha_region->ha_end_pfn = rg_start;
+- ha_region->covered_start_pfn = pg_start;
+ ha_region->covered_end_pfn = pg_start;
+ ha_region->end_pfn = rg_start + rg_size;
+ }
diff --git a/patches.suse/msft-hv-0775-Drivers-hv-vmbus-Correcting-truncation-error-for-con.patch b/patches.suse/msft-hv-0775-Drivers-hv-vmbus-Correcting-truncation-error-for-con.patch
new file mode 100644
index 0000000000..0f0078502b
--- /dev/null
+++ b/patches.suse/msft-hv-0775-Drivers-hv-vmbus-Correcting-truncation-error-for-con.patch
@@ -0,0 +1,51 @@
+From: Nick Meier <nmeier@microsoft.com>
+Date: Wed, 18 Mar 2015 12:29:24 -0700
+Patch-mainline: v4.1-rc1
+Subject: Drivers: hv: vmbus: Correcting truncation error for constant HV_CRASH_CTL_CRASH_NOTIFY
+Git-commit: 5ef5b6927f14f29cacd78fa1fb861661a5367f13
+References: fate#317533
+
+HV_CRASH_CTL_CRASH_NOTIFY is a 64 bit number. Depending on the usage context,
+the value may be truncated. This patch is in response from the following
+email from Wu Fengguang <fengguang.wu@intel.com>:
+
+ From: Wu Fengguang <fengguang.wu@intel.com>
+ Subject: [char-misc:char-misc-testing 25/45] drivers/hv/vmbus_drv.c:67:9: sparse:
+ constant 0x8000000000000000 is so big it is unsigned long
+
+ tree: git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc.git char-misc-testing
+ head: b3de8e3719e582f3182bb504295e4a8e43c8c96f
+ commit: 96c1d0581d00f7abe033350edb021a9d947d8d81 [25/45] Drivers: hv: vmbus: Add support for VMBus panic notifier handler
+ reproduce:
+ # apt-get install sparse
+ git checkout 96c1d0581d00f7abe033350edb021a9d947d8d81
+ make ARCH=x86_64 allmodconfig
+ make C=1 CF=-D__CHECK_ENDIAN__
+
+ sparse warnings: (new ones prefixed by >>)
+
+ drivers/hv/vmbus_drv.c:67:9: sparse: constant 0x8000000000000000 is so big it is unsigned long
+ ...
+
+Signed-off-by: Nick Meier <nmeier@microsoft.com>
+Reported-by: Wu Fengguang <fengguang.wu@intel.com>
+Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Acked-by: <ohering@suse.de>
+---
+ drivers/hv/hyperv_vmbus.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/hv/hyperv_vmbus.h b/drivers/hv/hyperv_vmbus.h
+index 6339589..c8e27e0 100644
+--- a/drivers/hv/hyperv_vmbus.h
++++ b/drivers/hv/hyperv_vmbus.h
+@@ -58,7 +58,7 @@ enum hv_cpuid_function {
+ #define HV_X64_MSR_CRASH_P4 0x40000104
+ #define HV_X64_MSR_CRASH_CTL 0x40000105
+
+-#define HV_CRASH_CTL_CRASH_NOTIFY 0x8000000000000000
++#define HV_CRASH_CTL_CRASH_NOTIFY (1ULL << 63)
+
+ /* Define version of the synthetic interrupt controller. */
+ #define HV_SYNIC_VERSION (1)
diff --git a/patches.suse/msft-hv-0776-hv-vmbus-missing-curly-braces-in-vmbus_process_offer.patch b/patches.suse/msft-hv-0776-hv-vmbus-missing-curly-braces-in-vmbus_process_offer.patch
new file mode 100644
index 0000000000..372f287b0c
--- /dev/null
+++ b/patches.suse/msft-hv-0776-hv-vmbus-missing-curly-braces-in-vmbus_process_offer.patch
@@ -0,0 +1,39 @@
+From: Dan Carpenter <dan.carpenter@oracle.com>
+Date: Wed, 18 Mar 2015 12:29:25 -0700
+Patch-mainline: v4.1-rc1
+Subject: hv: vmbus: missing curly braces in vmbus_process_offer()
+Git-commit: 177757423fde68a6ce773d2b67b468fbd8367bbc
+References: fate#317533
+
+The indenting makes it clear that there were curly braces intended here.
+
+Fixes: 2dd37cb81580 ('Drivers: hv: vmbus: Handle both rescind and offer messages in the same context')
+Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
+Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Acked-by: <ohering@suse.de>
+---
+ drivers/hv/channel_mgmt.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c
+index 5f8e47b..25dbbaf 100644
+--- a/drivers/hv/channel_mgmt.c
++++ b/drivers/hv/channel_mgmt.c
+@@ -415,7 +415,7 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel)
+
+ newchannel->state = CHANNEL_OPEN_STATE;
+ channel->num_sc++;
+- if (channel->sc_creation_callback != NULL)
++ if (channel->sc_creation_callback != NULL) {
+ /*
+ * We need to invoke the sub-channel creation
+ * callback; invoke this in a seperate work
+@@ -427,6 +427,7 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel)
+ vmbus_sc_creation_cb);
+ queue_work(newchannel->controlwq,
+ &newchannel->work);
++ }
+
+ return;
+ }
diff --git a/patches.suse/msft-hv-0778-Drivers-hv-vmbus-Fix-a-bug-in-rescind-processing-in-.patch b/patches.suse/msft-hv-0778-Drivers-hv-vmbus-Fix-a-bug-in-rescind-processing-in-.patch
new file mode 100644
index 0000000000..92d241a9b5
--- /dev/null
+++ b/patches.suse/msft-hv-0778-Drivers-hv-vmbus-Fix-a-bug-in-rescind-processing-in-.patch
@@ -0,0 +1,56 @@
+From: "K. Y. Srinivasan" <kys@microsoft.com>
+Date: Wed, 18 Mar 2015 12:29:27 -0700
+Patch-mainline: v4.1-rc1
+Subject: Drivers: hv: vmbus: Fix a bug in rescind processing in vmbus_close_internal()
+Git-commit: f2eddbc9f1a466329c68f3b75e89cfacd2792365
+References: fate#317533
+
+When a channel has been rescinded, the close operation is a noop.
+Restructure the code so we deal with the rescind condition after
+we properly cleanup the channel. I would like to thank
+Dexuan Cui <decui@microsoft.com> for observing this problem.
+The current code leaks memory when the channel is rescinded.
+
+The current char-next branch is broken and this patch fixes
+the bug.
+
+Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Acked-by: <ohering@suse.de>
+---
+ drivers/hv/channel.c | 15 ++++++---------
+ 1 file changed, 6 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c
+index da53180..2c8206d 100644
+--- a/drivers/hv/channel.c
++++ b/drivers/hv/channel.c
+@@ -501,15 +501,6 @@ static int vmbus_close_internal(struct vmbus_channel *channel)
+ put_cpu();
+ }
+
+- /*
+- * If the channel has been rescinded; process device removal.
+- */
+- if (channel->rescind) {
+- hv_process_channel_removal(channel,
+- channel->offermsg.child_relid);
+- return 0;
+- }
+-
+ /* Send a closing message */
+
+ msg = &channel->close_msg.msg;
+@@ -549,6 +540,12 @@ static int vmbus_close_internal(struct vmbus_channel *channel)
+ free_pages((unsigned long)channel->ringbuffer_pages,
+ get_order(channel->ringbuffer_pagecount * PAGE_SIZE));
+
++ /*
++ * If the channel has been rescinded; process device removal.
++ */
++ if (channel->rescind)
++ hv_process_channel_removal(channel,
++ channel->offermsg.child_relid);
+ return ret;
+ }
+
diff --git a/patches.suse/msft-hv-0779-hv-hypervvssd-call-endmntent-before-call-setmntent-a.patch b/patches.suse/msft-hv-0779-hv-hypervvssd-call-endmntent-before-call-setmntent-a.patch
new file mode 100644
index 0000000000..49df1b3684
--- /dev/null
+++ b/patches.suse/msft-hv-0779-hv-hypervvssd-call-endmntent-before-call-setmntent-a.patch
@@ -0,0 +1,61 @@
+From: Vaughan Cao <vaughan.cao@oracle.com>
+Date: Wed, 18 Mar 2015 12:29:28 -0700
+Patch-mainline: v4.1-rc1
+Subject: hv: hypervvssd: call endmntent before call setmntent again
+Git-commit: 4ce50e9491c5c92baf8bb7af85eb25398d3f70af
+References: fate#317533
+
+If freeze fails, vss_operate will re-enter itself to thaw. But it forgets
+to call endmntent() before it recalls setmntent() again.
+
+Signed-off-by: Vaughan Cao <vaughan.cao@oracle.com>
+Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Acked-by: <ohering@suse.de>
+---
+ tools/hv/hv_vss_daemon.c | 10 ++++++++--
+ 1 file changed, 8 insertions(+), 2 deletions(-)
+
+diff --git a/tools/hv/hv_vss_daemon.c b/tools/hv/hv_vss_daemon.c
+index 5e63f70..506dd01 100644
+--- a/tools/hv/hv_vss_daemon.c
++++ b/tools/hv/hv_vss_daemon.c
+@@ -81,6 +81,7 @@ static int vss_operate(int operation)
+ char match[] = "/dev/";
+ FILE *mounts;
+ struct mntent *ent;
++ char errdir[1024] = {0};
+ unsigned int cmd;
+ int error = 0, root_seen = 0, save_errno = 0;
+
+@@ -115,6 +116,8 @@ static int vss_operate(int operation)
+ goto err;
+ }
+
++ endmntent(mounts);
++
+ if (root_seen) {
+ error |= vss_do_freeze("/", cmd);
+ if (error && operation == VSS_OP_FREEZE)
+@@ -124,16 +127,19 @@ static int vss_operate(int operation)
+ goto out;
+ err:
+ save_errno = errno;
++ if (ent) {
++ strncpy(errdir, ent->mnt_dir, sizeof(errdir)-1);
++ endmntent(mounts);
++ }
+ vss_operate(VSS_OP_THAW);
+ /* Call syslog after we thaw all filesystems */
+ if (ent)
+ syslog(LOG_ERR, "FREEZE of %s failed; error:%d %s",
+- ent->mnt_dir, save_errno, strerror(save_errno));
++ errdir, save_errno, strerror(save_errno));
+ else
+ syslog(LOG_ERR, "FREEZE of / failed; error:%d %s", save_errno,
+ strerror(save_errno));
+ out:
+- endmntent(mounts);
+ return error;
+ }
+
diff --git a/patches.suse/msft-hv-0780-Drivers-hv-vmbus-Export-the-vmbus_sendpacket_pagebuf.patch b/patches.suse/msft-hv-0780-Drivers-hv-vmbus-Export-the-vmbus_sendpacket_pagebuf.patch
new file mode 100644
index 0000000000..c3e33d45af
--- /dev/null
+++ b/patches.suse/msft-hv-0780-Drivers-hv-vmbus-Export-the-vmbus_sendpacket_pagebuf.patch
@@ -0,0 +1,29 @@
+From: "K. Y. Srinivasan" <kys@microsoft.com>
+Date: Wed, 18 Mar 2015 12:29:29 -0700
+Patch-mainline: v4.1-rc1
+Subject: Drivers: hv: vmbus: Export the vmbus_sendpacket_pagebuffer_ctl()
+Git-commit: b3a19b36ad7450d4c8caeb7d9f623af3da32a578
+References: fate#317533
+
+Export the vmbus_sendpacket_pagebuffer_ctl() interface. This export will be
+used by the netvsc driver.
+
+Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Acked-by: <ohering@suse.de>
+---
+ drivers/hv/channel.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c
+index 2c8206d..fddd3b5 100644
+--- a/drivers/hv/channel.c
++++ b/drivers/hv/channel.c
+@@ -707,6 +707,7 @@ int vmbus_sendpacket_pagebuffer_ctl(struct vmbus_channel *channel,
+
+ return ret;
+ }
++EXPORT_SYMBOL_GPL(vmbus_sendpacket_pagebuffer_ctl);
+
+ /*
+ * vmbus_sendpacket_pagebuffer - Send a range of single-page buffer
diff --git a/patches.suse/msft-hv-0781-Drivers-hv-vmbus-Fix-a-siganlling-host-signalling-is.patch b/patches.suse/msft-hv-0781-Drivers-hv-vmbus-Fix-a-siganlling-host-signalling-is.patch
new file mode 100644
index 0000000000..5825e5d584
--- /dev/null
+++ b/patches.suse/msft-hv-0781-Drivers-hv-vmbus-Fix-a-siganlling-host-signalling-is.patch
@@ -0,0 +1,65 @@
+From: "K. Y. Srinivasan" <kys@microsoft.com>
+Date: Wed, 18 Mar 2015 12:29:30 -0700
+Patch-mainline: v4.1-rc1
+Subject: Drivers: hv: vmbus: Fix a siganlling host signalling issue
+Git-commit: 5f5cc81733baf7b67a039a931dae282e53bf97b9
+References: fate#317533
+
+Handle the case when the write to the ringbuffer fails. In this case,
+unconditionally signal the host. Since we may have deferred signalling
+the host based on the kick_q parameter, signalling the host
+unconditionally in this case deals with the issue.
+
+Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Acked-by: <ohering@suse.de>
+---
+ drivers/hv/channel.c | 28 ++++++++++++++++++++++++++--
+ 1 file changed, 26 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c
+index fddd3b5..54da66d 100644
+--- a/drivers/hv/channel.c
++++ b/drivers/hv/channel.c
+@@ -611,7 +611,19 @@ int vmbus_sendpacket_ctl(struct vmbus_channel *channel, void *buffer,
+
+ ret = hv_ringbuffer_write(&channel->outbound, bufferlist, 3, &signal);
+
+- if ((ret == 0) && kick_q && signal)
++ /*
++ * Signalling the host is conditional on many factors:
++ * 1. The ring state changed from being empty to non-empty.
++ * This is tracked by the variable "signal".
++ * 2. The variable kick_q tracks if more data will be placed
++ * on the ring. We will not signal if more data is
++ * to be placed.
++ *
++ * If we cannot write to the ring-buffer; signal the host
++ * even if we may not have written anything. This is a rare
++ * enough condition that it should not matter.
++ */
++ if (((ret == 0) && kick_q && signal) || (ret))
+ vmbus_setevent(channel);
+
+ return ret;
+@@ -702,7 +714,19 @@ int vmbus_sendpacket_pagebuffer_ctl(struct vmbus_channel *channel,
+
+ ret = hv_ringbuffer_write(&channel->outbound, bufferlist, 3, &signal);
+
+- if ((ret == 0) && kick_q && signal)
++ /*
++ * Signalling the host is conditional on many factors:
++ * 1. The ring state changed from being empty to non-empty.
++ * This is tracked by the variable "signal".
++ * 2. The variable kick_q tracks if more data will be placed
++ * on the ring. We will not signal if more data is
++ * to be placed.
++ *
++ * If we cannot write to the ring-buffer; signal the host
++ * even if we may not have written anything. This is a rare
++ * enough condition that it should not matter.
++ */
++ if (((ret == 0) && kick_q && signal) || (ret))
+ vmbus_setevent(channel);
+
+ return ret;
diff --git a/patches.suse/msft-hv-0782-Drivers-hv-vmbus-Don-t-wait-after-requesting-offers.patch b/patches.suse/msft-hv-0782-Drivers-hv-vmbus-Don-t-wait-after-requesting-offers.patch
new file mode 100644
index 0000000000..96bb1d89e5
--- /dev/null
+++ b/patches.suse/msft-hv-0782-Drivers-hv-vmbus-Don-t-wait-after-requesting-offers.patch
@@ -0,0 +1,54 @@
+From: "K. Y. Srinivasan" <kys@microsoft.com>
+Date: Thu, 19 Mar 2015 08:11:34 -0700
+Patch-mainline: v4.1-rc1
+Subject: Drivers: hv: vmbus: Don't wait after requesting offers
+Git-commit: 73cffdb65e679b98893f484063462c045adcf212
+References: fate#317533
+
+Don't wait after sending request for offers to the host. This wait is
+unnecessary and simply adds 5 seconds to the boot time.
+
+Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Acked-by: <ohering@suse.de>
+---
+ drivers/hv/channel_mgmt.c | 11 -----------
+ 1 file changed, 11 deletions(-)
+
+diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c
+index 25dbbaf..bb39705 100644
+--- a/drivers/hv/channel_mgmt.c
++++ b/drivers/hv/channel_mgmt.c
+@@ -884,7 +884,6 @@ int vmbus_request_offers(void)
+ struct vmbus_channel_message_header *msg;
+ struct vmbus_channel_msginfo *msginfo;
+ int ret;
+- unsigned long t;
+
+ msginfo = kmalloc(sizeof(*msginfo) +
+ sizeof(struct vmbus_channel_message_header),
+@@ -892,8 +891,6 @@ int vmbus_request_offers(void)
+ if (!msginfo)
+ return -ENOMEM;
+
+- init_completion(&msginfo->waitevent);
+-
+ msg = (struct vmbus_channel_message_header *)msginfo->msg;
+
+ msg->msgtype = CHANNELMSG_REQUESTOFFERS;
+@@ -907,14 +904,6 @@ int vmbus_request_offers(void)
+ goto cleanup;
+ }
+
+- t = wait_for_completion_timeout(&msginfo->waitevent, 5*HZ);
+- if (t == 0) {
+- ret = -ETIMEDOUT;
+- goto cleanup;
+- }
+-
+-
+-
+ cleanup:
+ kfree(msginfo);
+
diff --git a/patches.suse/msft-hv-0784-hv_netvsc-remove-vmbus_are_subchannels_present-in-rn.patch b/patches.suse/msft-hv-0784-hv_netvsc-remove-vmbus_are_subchannels_present-in-rn.patch
new file mode 100644
index 0000000000..7a73cdfcc4
--- /dev/null
+++ b/patches.suse/msft-hv-0784-hv_netvsc-remove-vmbus_are_subchannels_present-in-rn.patch
@@ -0,0 +1,31 @@
+From: Haiyang Zhang <haiyangz@microsoft.com>
+Date: Thu, 26 Mar 2015 16:20:58 -0700
+Patch-mainline: v4.1-rc1
+Subject: hv_netvsc: remove vmbus_are_subchannels_present() in rndis_filter_device_add()
+Git-commit: 5ce58c2f13eaa8ca6d7e1041175433bd8cc55756
+References: fate#317533
+
+The vmbus_are_subchannels_present() also involves opening the channels, which
+may be too early at this point. Checking for subchannels is not necessary here.
+So this patch removes it. Subchannels will be opened when offer messages arrive.
+
+Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Acked-by: <ohering@suse.de>
+---
+ drivers/net/hyperv/rndis_filter.c | 2 --
+ 1 file changed, 2 deletions(-)
+
+diff --git a/drivers/net/hyperv/rndis_filter.c b/drivers/net/hyperv/rndis_filter.c
+index a2b185a..fdfab1f 100644
+--- a/drivers/net/hyperv/rndis_filter.c
++++ b/drivers/net/hyperv/rndis_filter.c
+@@ -1141,8 +1141,6 @@ int rndis_filter_device_add(struct hv_device *dev,
+ net_device->num_chn = 1 +
+ init_packet->msg.v5_msg.subchn_comp.num_subchannels;
+
+- vmbus_are_subchannels_present(dev->channel);
+-
+ ret = rndis_filter_set_rss_param(rndis_device, net_device->num_chn);
+
+ out:
diff --git a/patches.suse/msft-hv-0785-hv_netvsc-Cleanup-the-test-for-freeing-skb-when-we-u.patch b/patches.suse/msft-hv-0785-hv_netvsc-Cleanup-the-test-for-freeing-skb-when-we-u.patch
new file mode 100644
index 0000000000..c223372c5a
--- /dev/null
+++ b/patches.suse/msft-hv-0785-hv_netvsc-Cleanup-the-test-for-freeing-skb-when-we-u.patch
@@ -0,0 +1,47 @@
+From: KY Srinivasan <kys@microsoft.com>
+Date: Sun, 29 Mar 2015 21:08:41 -0700
+Patch-mainline: v4.1-rc1
+Subject: hv_netvsc: Cleanup the test for freeing skb when we use sendbuf mechanism
+Git-commit: cbacec76bcd03ff21b37ac331e652b5a8f3ea644
+References: fate#317533
+
+In preparation for embedding the rndis state and other packet state into
+the skb, cleanup the test for freeing the skb.
+
+Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Acked-by: <ohering@suse.de>
+---
+ drivers/net/hyperv/netvsc.c | 1 +
+ drivers/net/hyperv/netvsc_drv.c | 3 +--
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c
+index b81bd37..ecbd813 100644
+--- a/drivers/net/hyperv/netvsc.c
++++ b/drivers/net/hyperv/netvsc.c
+@@ -870,6 +870,7 @@ int netvsc_send(struct hv_device *device,
+ skb = (struct sk_buff *)
+ (unsigned long)packet->send_completion_tid;
+ packet->page_buf_cnt = 0;
++ packet->send_completion_tid = 0;
+ }
+ }
+ packet->send_buf_index = section_index;
+diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
+index 0c99818..75beb89 100644
+--- a/drivers/net/hyperv/netvsc_drv.c
++++ b/drivers/net/hyperv/netvsc_drv.c
+@@ -234,11 +234,10 @@ static void netvsc_xmit_completion(void *context)
+ struct hv_netvsc_packet *packet = (struct hv_netvsc_packet *)context;
+ struct sk_buff *skb = (struct sk_buff *)
+ (unsigned long)packet->send_completion_tid;
+- u32 index = packet->send_buf_index;
+
+ kfree(packet);
+
+- if (skb && (index == NETVSC_INVALID_INDEX))
++ if (skb)
+ dev_kfree_skb_any(skb);
+ }
+
diff --git a/patches.suse/msft-hv-0787-hv-run-non-blocking-message-handlers-in-the-dispatch.patch b/patches.suse/msft-hv-0787-hv-run-non-blocking-message-handlers-in-the-dispatch.patch
new file mode 100644
index 0000000000..7edfbd9fb5
--- /dev/null
+++ b/patches.suse/msft-hv-0787-hv-run-non-blocking-message-handlers-in-the-dispatch.patch
@@ -0,0 +1,166 @@
+From: Dexuan Cui <decui@microsoft.com>
+Date: Fri, 27 Mar 2015 09:10:08 -0700
+Patch-mainline: v4.1-rc1
+Subject: hv: run non-blocking message handlers in the dispatch tasklet
+Git-commit: 652594c7dfd9bf6392e3a727bc69d89a2562d953
+References: fate#317533
+
+A work item in vmbus_connection.work_queue can sleep, waiting for a new
+host message (usually it is some kind of "completion" message). Currently
+the new message will be handled in the same workqueue, but since work items
+in the workqueue is serialized, we actually have no chance to handle
+the new message if the current work item is sleeping -- as as result, the
+current work item will hang forever.
+
+K. Y. has posted the below fix to resolve the issue:
+Drivers: hv: vmbus: Perform device register in the per-channel work element
+
+Actually we can simplify the fix by directly running non-blocking message
+handlers in the dispatch tasklet (inspired by K. Y.).
+
+This patch is the fundamental change. The following 2 patches will simplify
+the message offering and rescind-offering handling a lot.
+
+Signed-off-by: Dexuan Cui <decui@microsoft.com>
+Cc: K. Y. Srinivasan <kys@microsoft.com>
+Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Acked-by: <ohering@suse.de>
+---
+ drivers/hv/channel_mgmt.c | 41 ++++++++++++++++++-----------------------
+ drivers/hv/hyperv_vmbus.h | 17 +++++++++++++++++
+ drivers/hv/vmbus_drv.c | 21 ++++++++++++++++++---
+ 3 files changed, 53 insertions(+), 26 deletions(-)
+
+diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c
+index bb39705..287f07b 100644
+--- a/drivers/hv/channel_mgmt.c
++++ b/drivers/hv/channel_mgmt.c
+@@ -33,11 +33,6 @@
+
+ #include "hyperv_vmbus.h"
+
+-struct vmbus_channel_message_table_entry {
+- enum vmbus_channel_message_type message_type;
+- void (*message_handler)(struct vmbus_channel_message_header *msg);
+-};
+-
+ struct vmbus_rescind_work {
+ struct work_struct work;
+ struct vmbus_channel *channel;
+@@ -827,25 +822,25 @@ static void vmbus_onversion_response(
+ }
+
+ /* Channel message dispatch table */
+-static struct vmbus_channel_message_table_entry
++struct vmbus_channel_message_table_entry
+ channel_message_table[CHANNELMSG_COUNT] = {
+- {CHANNELMSG_INVALID, NULL},
+- {CHANNELMSG_OFFERCHANNEL, vmbus_onoffer},
+- {CHANNELMSG_RESCIND_CHANNELOFFER, vmbus_onoffer_rescind},
+- {CHANNELMSG_REQUESTOFFERS, NULL},
+- {CHANNELMSG_ALLOFFERS_DELIVERED, vmbus_onoffers_delivered},
+- {CHANNELMSG_OPENCHANNEL, NULL},
+- {CHANNELMSG_OPENCHANNEL_RESULT, vmbus_onopen_result},
+- {CHANNELMSG_CLOSECHANNEL, NULL},
+- {CHANNELMSG_GPADL_HEADER, NULL},
+- {CHANNELMSG_GPADL_BODY, NULL},
+- {CHANNELMSG_GPADL_CREATED, vmbus_ongpadl_created},
+- {CHANNELMSG_GPADL_TEARDOWN, NULL},
+- {CHANNELMSG_GPADL_TORNDOWN, vmbus_ongpadl_torndown},
+- {CHANNELMSG_RELID_RELEASED, NULL},
+- {CHANNELMSG_INITIATE_CONTACT, NULL},
+- {CHANNELMSG_VERSION_RESPONSE, vmbus_onversion_response},
+- {CHANNELMSG_UNLOAD, NULL},
++ {CHANNELMSG_INVALID, 0, NULL},
++ {CHANNELMSG_OFFERCHANNEL, 0, vmbus_onoffer},
++ {CHANNELMSG_RESCIND_CHANNELOFFER, 0, vmbus_onoffer_rescind},
++ {CHANNELMSG_REQUESTOFFERS, 0, NULL},
++ {CHANNELMSG_ALLOFFERS_DELIVERED, 1, vmbus_onoffers_delivered},
++ {CHANNELMSG_OPENCHANNEL, 0, NULL},
++ {CHANNELMSG_OPENCHANNEL_RESULT, 1, vmbus_onopen_result},
++ {CHANNELMSG_CLOSECHANNEL, 0, NULL},
++ {CHANNELMSG_GPADL_HEADER, 0, NULL},
++ {CHANNELMSG_GPADL_BODY, 0, NULL},
++ {CHANNELMSG_GPADL_CREATED, 1, vmbus_ongpadl_created},
++ {CHANNELMSG_GPADL_TEARDOWN, 0, NULL},
++ {CHANNELMSG_GPADL_TORNDOWN, 1, vmbus_ongpadl_torndown},
++ {CHANNELMSG_RELID_RELEASED, 0, NULL},
++ {CHANNELMSG_INITIATE_CONTACT, 0, NULL},
++ {CHANNELMSG_VERSION_RESPONSE, 1, vmbus_onversion_response},
++ {CHANNELMSG_UNLOAD, 0, NULL},
+ };
+
+ /*
+diff --git a/drivers/hv/hyperv_vmbus.h b/drivers/hv/hyperv_vmbus.h
+index c8e27e0..f40a5a9 100644
+--- a/drivers/hv/hyperv_vmbus.h
++++ b/drivers/hv/hyperv_vmbus.h
+@@ -685,6 +685,23 @@ struct vmbus_msginfo {
+
+ extern struct vmbus_connection vmbus_connection;
+
++enum vmbus_message_handler_type {
++ /* The related handler can sleep. */
++ VMHT_BLOCKING = 0,
++
++ /* The related handler must NOT sleep. */
++ VMHT_NON_BLOCKING = 1,
++};
++
++struct vmbus_channel_message_table_entry {
++ enum vmbus_channel_message_type message_type;
++ enum vmbus_message_handler_type handler_type;
++ void (*message_handler)(struct vmbus_channel_message_header *msg);
++};
++
++extern struct vmbus_channel_message_table_entry
++ channel_message_table[CHANNELMSG_COUNT];
++
+ /* General vmbus interface */
+
+ struct hv_device *vmbus_device_create(const uuid_le *type,
+diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
+index 8313e25..c85235e 100644
+--- a/drivers/hv/vmbus_drv.c
++++ b/drivers/hv/vmbus_drv.c
+@@ -657,21 +657,36 @@ static void vmbus_on_msg_dpc(unsigned long data)
+ void *page_addr = hv_context.synic_message_page[cpu];
+ struct hv_message *msg = (struct hv_message *)page_addr +
+ VMBUS_MESSAGE_SINT;
++ struct vmbus_channel_message_header *hdr;
++ struct vmbus_channel_message_table_entry *entry;
+ struct onmessage_work_context *ctx;
+
+ while (1) {
+- if (msg->header.message_type == HVMSG_NONE) {
++ if (msg->header.message_type == HVMSG_NONE)
+ /* no msg */
+ break;
+- } else {
++
++ hdr = (struct vmbus_channel_message_header *)msg->u.payload;
++
++ if (hdr->msgtype >= CHANNELMSG_COUNT) {
++ WARN_ONCE(1, "unknown msgtype=%d\n", hdr->msgtype);
++ goto msg_handled;
++ }
++
++ entry = &channel_message_table[hdr->msgtype];
++ if (entry->handler_type == VMHT_BLOCKING) {
+ ctx = kmalloc(sizeof(*ctx), GFP_ATOMIC);
+ if (ctx == NULL)
+ continue;
++
+ INIT_WORK(&ctx->work, vmbus_onmessage_work);
+ memcpy(&ctx->msg, msg, sizeof(*msg));
++
+ queue_work(vmbus_connection.work_queue, &ctx->work);
+- }
++ } else
++ entry->message_handler(hdr);
+
++msg_handled:
+ msg->header.message_type = HVMSG_NONE;
+
+ /*
diff --git a/patches.suse/msft-hv-0788-hv-don-t-schedule-new-works-in-vmbus_onoffer-vmbus_o.patch b/patches.suse/msft-hv-0788-hv-don-t-schedule-new-works-in-vmbus_onoffer-vmbus_o.patch
new file mode 100644
index 0000000000..49b5d8fe88
--- /dev/null
+++ b/patches.suse/msft-hv-0788-hv-don-t-schedule-new-works-in-vmbus_onoffer-vmbus_o.patch
@@ -0,0 +1,295 @@
+From: Dexuan Cui <decui@microsoft.com>
+Date: Fri, 27 Mar 2015 09:10:09 -0700
+Patch-mainline: v4.1-rc1
+Subject: hv: don't schedule new works in vmbus_onoffer()/vmbus_onoffer_rescind()
+Git-commit: d43e2fe7da320310834467a3fd87a10adb25a221
+References: fate#317533
+
+Since the 2 fucntions can safely run in vmbus_connection.work_queue without
+hang, we don't need to schedule new work items into the per-channel workqueue.
+
+Actally we can even remove the per-channel workqueue now -- we'll do it
+in the next patch.
+
+Signed-off-by: Dexuan Cui <decui@microsoft.com>
+Cc: K. Y. Srinivasan <kys@microsoft.com>
+Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Acked-by: <ohering@suse.de>
+---
+ drivers/hv/channel_mgmt.c | 157 +++++++++-------------------------------------
+ drivers/hv/connection.c | 6 +-
+ drivers/hv/hyperv_vmbus.h | 2 +-
+ 3 files changed, 30 insertions(+), 135 deletions(-)
+
+diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c
+index 287f07b..d69864d 100644
+--- a/drivers/hv/channel_mgmt.c
++++ b/drivers/hv/channel_mgmt.c
+@@ -23,7 +23,6 @@
+ #include <linux/kernel.h>
+ #include <linux/sched.h>
+ #include <linux/wait.h>
+-#include <linux/delay.h>
+ #include <linux/mm.h>
+ #include <linux/slab.h>
+ #include <linux/list.h>
+@@ -33,11 +32,6 @@
+
+ #include "hyperv_vmbus.h"
+
+-struct vmbus_rescind_work {
+- struct work_struct work;
+- struct vmbus_channel *channel;
+-};
+-
+ /**
+ * vmbus_prep_negotiate_resp() - Create default response for Hyper-V Negotiate message
+ * @icmsghdrp: Pointer to msg header structure
+@@ -134,20 +128,6 @@ fw_error:
+
+ EXPORT_SYMBOL_GPL(vmbus_prep_negotiate_resp);
+
+-static void vmbus_sc_creation_cb(struct work_struct *work)
+-{
+- struct vmbus_channel *newchannel = container_of(work,
+- struct vmbus_channel,
+- work);
+- struct vmbus_channel *primary_channel = newchannel->primary_channel;
+-
+- /*
+- * On entry sc_creation_callback has been already verified to
+- * be non-NULL.
+- */
+- primary_channel->sc_creation_callback(newchannel);
+-}
+-
+ /*
+ * alloc_channel - Allocate and initialize a vmbus channel object
+ */
+@@ -206,40 +186,6 @@ static void free_channel(struct vmbus_channel *channel)
+ queue_work(vmbus_connection.work_queue, &channel->work);
+ }
+
+-static void process_rescind_fn(struct work_struct *work)
+-{
+- struct vmbus_rescind_work *rc_work;
+- struct vmbus_channel *channel;
+- struct device *dev;
+-
+- rc_work = container_of(work, struct vmbus_rescind_work, work);
+- channel = rc_work->channel;
+-
+- /*
+- * We have already acquired a reference on the channel
+- * and so it cannot vanish underneath us.
+- * It is possible (while very unlikely) that we may
+- * get here while the processing of the initial offer
+- * is still not complete. Deal with this situation by
+- * just waiting until the channel is in the correct state.
+- */
+-
+- while (channel->work.func != release_channel)
+- msleep(1000);
+-
+- if (channel->device_obj) {
+- dev = get_device(&channel->device_obj->device);
+- if (dev) {
+- vmbus_device_unregister(channel->device_obj);
+- put_device(dev);
+- }
+- } else {
+- hv_process_channel_removal(channel,
+- channel->offermsg.child_relid);
+- }
+- kfree(work);
+-}
+-
+ static void percpu_channel_enq(void *arg)
+ {
+ struct vmbus_channel *channel = arg;
+@@ -302,46 +248,6 @@ void vmbus_free_channels(void)
+ }
+ }
+
+-static void vmbus_do_device_register(struct work_struct *work)
+-{
+- struct hv_device *device_obj;
+- int ret;
+- unsigned long flags;
+- struct vmbus_channel *newchannel = container_of(work,
+- struct vmbus_channel,
+- work);
+-
+- ret = vmbus_device_register(newchannel->device_obj);
+- if (ret != 0) {
+- pr_err("unable to add child device object (relid %d)\n",
+- newchannel->offermsg.child_relid);
+- spin_lock_irqsave(&vmbus_connection.channel_lock, flags);
+- list_del(&newchannel->listentry);
+- device_obj = newchannel->device_obj;
+- newchannel->device_obj = NULL;
+- spin_unlock_irqrestore(&vmbus_connection.channel_lock, flags);
+-
+- 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();
+- }
+-
+- kfree(device_obj);
+- if (!newchannel->rescind) {
+- free_channel(newchannel);
+- return;
+- }
+- }
+- /*
+- * The next state for this channel is to be freed.
+- */
+- INIT_WORK(&newchannel->work, release_channel);
+-}
+-
+ /*
+ * vmbus_process_offer - Process the offer by creating a channel/device
+ * associated with this offer
+@@ -410,19 +316,8 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel)
+
+ newchannel->state = CHANNEL_OPEN_STATE;
+ channel->num_sc++;
+- if (channel->sc_creation_callback != NULL) {
+- /*
+- * We need to invoke the sub-channel creation
+- * callback; invoke this in a seperate work
+- * context since we are currently running on
+- * the global work context in which we handle
+- * messages from the host.
+- */
+- INIT_WORK(&newchannel->work,
+- vmbus_sc_creation_cb);
+- queue_work(newchannel->controlwq,
+- &newchannel->work);
+- }
++ if (channel->sc_creation_callback != NULL)
++ channel->sc_creation_callback(newchannel);
+
+ return;
+ }
+@@ -453,13 +348,13 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel)
+ * Add the new device to the bus. This will kick off device-driver
+ * binding which eventually invokes the device driver's AddDevice()
+ * method.
+- * Invoke this call on the per-channel work context.
+- * Until we return from this function, rescind offer message
+- * cannot be processed as we are running on the global message
+- * handling work.
+ */
+- INIT_WORK(&newchannel->work, vmbus_do_device_register);
+- queue_work(newchannel->controlwq, &newchannel->work);
++ if (vmbus_device_register(newchannel->device_obj) != 0) {
++ pr_err("unable to add child device object (relid %d)\n",
++ newchannel->offermsg.child_relid);
++ kfree(newchannel->device_obj);
++ goto err_deq_chan;
++ }
+ return;
+
+ err_deq_chan:
+@@ -613,31 +508,35 @@ static void vmbus_onoffer_rescind(struct vmbus_channel_message_header *hdr)
+ {
+ struct vmbus_channel_rescind_offer *rescind;
+ struct vmbus_channel *channel;
+- struct vmbus_rescind_work *rc_work;
++ unsigned long flags;
++ struct device *dev;
+
+ rescind = (struct vmbus_channel_rescind_offer *)hdr;
+- channel = relid2channel(rescind->child_relid, true);
++ channel = relid2channel(rescind->child_relid);
+
+ if (channel == NULL) {
+ hv_process_channel_removal(NULL, rescind->child_relid);
+ return;
+ }
+
+- /*
+- * We have acquired a reference on the channel and have posted
+- * the rescind state. Perform further cleanup in a work context
+- * that is different from the global work context in which
+- * we process messages from the host (we are currently executing
+- * on that global context.
+- */
+- rc_work = kzalloc(sizeof(struct vmbus_rescind_work), GFP_KERNEL);
+- if (!rc_work) {
+- pr_err("Unable to allocate memory for rescind processing ");
+- return;
++ spin_lock_irqsave(&channel->lock, flags);
++ channel->rescind = true;
++ spin_unlock_irqrestore(&channel->lock, flags);
++
++ if (channel->device_obj) {
++ /*
++ * We will have to unregister this device from the
++ * driver core.
++ */
++ dev = get_device(&channel->device_obj->device);
++ if (dev) {
++ vmbus_device_unregister(channel->device_obj);
++ put_device(dev);
++ }
++ } else {
++ hv_process_channel_removal(channel,
++ channel->offermsg.child_relid);
+ }
+- rc_work->channel = channel;
+- INIT_WORK(&rc_work->work, process_rescind_fn);
+- schedule_work(&rc_work->work);
+ }
+
+ /*
+diff --git a/drivers/hv/connection.c b/drivers/hv/connection.c
+index 8bcd307..583d7d4 100644
+--- a/drivers/hv/connection.c
++++ b/drivers/hv/connection.c
+@@ -270,7 +270,7 @@ static struct vmbus_channel *pcpu_relid2channel(u32 relid)
+ * relid2channel - Get the channel object given its
+ * child relative id (ie channel id)
+ */
+-struct vmbus_channel *relid2channel(u32 relid, bool rescind)
++struct vmbus_channel *relid2channel(u32 relid)
+ {
+ struct vmbus_channel *channel;
+ struct vmbus_channel *found_channel = NULL;
+@@ -282,8 +282,6 @@ struct vmbus_channel *relid2channel(u32 relid, bool rescind)
+ list_for_each_entry(channel, &vmbus_connection.chn_list, listentry) {
+ if (channel->offermsg.child_relid == relid) {
+ found_channel = channel;
+- if (rescind)
+- found_channel->rescind = true;
+ break;
+ } else if (!list_empty(&channel->sc_list)) {
+ /*
+@@ -294,8 +292,6 @@ struct vmbus_channel *relid2channel(u32 relid, bool rescind)
+ sc_list);
+ if (cur_sc->offermsg.child_relid == relid) {
+ found_channel = cur_sc;
+- if (rescind)
+- found_channel->rescind = true;
+ break;
+ }
+ }
+diff --git a/drivers/hv/hyperv_vmbus.h b/drivers/hv/hyperv_vmbus.h
+index f40a5a9..887287a 100644
+--- a/drivers/hv/hyperv_vmbus.h
++++ b/drivers/hv/hyperv_vmbus.h
+@@ -715,7 +715,7 @@ void vmbus_device_unregister(struct hv_device *device_obj);
+ /* VmbusChildDeviceDestroy( */
+ /* struct hv_device *); */
+
+-struct vmbus_channel *relid2channel(u32 relid, bool rescind);
++struct vmbus_channel *relid2channel(u32 relid);
+
+ void vmbus_free_channels(void);
+
diff --git a/patches.suse/msft-hv-0789-hv-remove-the-per-channel-workqueue.patch b/patches.suse/msft-hv-0789-hv-remove-the-per-channel-workqueue.patch
new file mode 100644
index 0000000000..8a85b42485
--- /dev/null
+++ b/patches.suse/msft-hv-0789-hv-remove-the-per-channel-workqueue.patch
@@ -0,0 +1,90 @@
+From: Dexuan Cui <decui@microsoft.com>
+Date: Fri, 27 Mar 2015 09:10:10 -0700
+Patch-mainline: v4.1-rc1
+Subject: hv: remove the per-channel workqueue
+Git-commit: aadc3780f31865edc84c587ab718a33a8eeeb09d
+References: fate#317533
+
+It's not necessary any longer, since we can safely run the blocking
+message handlers in vmbus_connection.work_queue now.
+
+Signed-off-by: Dexuan Cui <decui@microsoft.com>
+Cc: K. Y. Srinivasan <kys@microsoft.com>
+Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Acked-by: <ohering@suse.de>
+---
+ drivers/hv/channel_mgmt.c | 30 +-----------------------------
+ include/linux/hyperv.h | 3 ---
+ 2 files changed, 1 insertion(+), 32 deletions(-)
+
+diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c
+index d69864d..0eeb1b3 100644
+--- a/drivers/hv/channel_mgmt.c
++++ b/drivers/hv/channel_mgmt.c
+@@ -147,43 +147,15 @@ static struct vmbus_channel *alloc_channel(void)
+ INIT_LIST_HEAD(&channel->sc_list);
+ INIT_LIST_HEAD(&channel->percpu_list);
+
+- channel->controlwq = alloc_workqueue("hv_vmbus_ctl/%d", WQ_MEM_RECLAIM,
+- 1, channel->id);
+- if (!channel->controlwq) {
+- kfree(channel);
+- return NULL;
+- }
+-
+ return channel;
+ }
+
+ /*
+- * release_hannel - Release the vmbus channel object itself
+- */
+-static void release_channel(struct work_struct *work)
+-{
+- struct vmbus_channel *channel = container_of(work,
+- struct vmbus_channel,
+- work);
+-
+- destroy_workqueue(channel->controlwq);
+-
+- kfree(channel);
+-}
+-
+-/*
+ * free_channel - Release the resources used by the vmbus channel object
+ */
+ static void free_channel(struct vmbus_channel *channel)
+ {
+-
+- /*
+- * We have to release the channel's workqueue/thread in the vmbus's
+- * workqueue/thread context
+- * ie we can't destroy ourselves.
+- */
+- INIT_WORK(&channel->work, release_channel);
+- queue_work(vmbus_connection.work_queue, &channel->work);
++ kfree(channel);
+ }
+
+ static void percpu_channel_enq(void *arg)
+diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
+index 80e444b..902c37a 100644
+--- a/include/linux/hyperv.h
++++ b/include/linux/hyperv.h
+@@ -653,8 +653,6 @@ struct vmbus_channel {
+
+ struct hv_device *device_obj;
+
+- struct work_struct work;
+-
+ enum vmbus_channel_state state;
+
+ struct vmbus_channel_offer_channel offermsg;
+@@ -675,7 +673,6 @@ struct vmbus_channel {
+ struct hv_ring_buffer_info outbound; /* send to parent */
+ struct hv_ring_buffer_info inbound; /* receive from parent */
+ spinlock_t inbound_lock;
+- struct workqueue_struct *controlwq;
+
+ struct vmbus_close_msg close_msg;
+
diff --git a/patches.suse/msft-hv-0790-Drivers-hv-hv_balloon-do-not-online-pages-in-offline.patch b/patches.suse/msft-hv-0790-Drivers-hv-hv_balloon-do-not-online-pages-in-offline.patch
new file mode 100644
index 0000000000..a91339657f
--- /dev/null
+++ b/patches.suse/msft-hv-0790-Drivers-hv-hv_balloon-do-not-online-pages-in-offline.patch
@@ -0,0 +1,51 @@
+From: Vitaly Kuznetsov <vkuznets@redhat.com>
+Date: Fri, 27 Mar 2015 09:10:11 -0700
+Patch-mainline: v4.1-rc1
+Subject: Drivers: hv: hv_balloon: do not online pages in offline blocks
+Git-commit: d6cbd2c3a3db437708520c66f285c69ef028ac1f
+References: fate#317533
+
+Currently we add memory in 128Mb blocks but the request from host can be
+aligned differently. In such case we add a partially backed block and
+when this block goes online we skip onlining pages which are not backed
+(hv_online_page() callback serves this purpose). When we receive next
+request for the same host add region we online pages which were not backed
+before with hv_bring_pgs_online(). However, we don't check if the the block
+in question was onlined and online this tail unconditionally. This is bad as
+we avoid all online_pages() logic: these pages are not accounted, we don't
+send notifications (and hv_balloon is not the only receiver of them),...
+And, first of all, nobody asked as to online these pages. Solve the issue by
+checking if the last previously backed page was onlined and onlining the tail
+only in case it was.
+
+Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
+Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Acked-by: <ohering@suse.de>
+---
+ drivers/hv/hv_balloon.c | 12 +++++++++++-
+ 1 file changed, 11 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/hv/hv_balloon.c b/drivers/hv/hv_balloon.c
+index 014256a..99afef9 100644
+--- a/drivers/hv/hv_balloon.c
++++ b/drivers/hv/hv_balloon.c
+@@ -778,7 +778,17 @@ static unsigned long handle_pg_range(unsigned long pg_start,
+ pgs_ol = has->ha_end_pfn - start_pfn;
+ if (pgs_ol > pfn_cnt)
+ pgs_ol = pfn_cnt;
+- hv_bring_pgs_online(start_pfn, pgs_ol);
++
++ /*
++ * Check if the corresponding memory block is already
++ * online by checking its last previously backed page.
++ * In case it is we need to bring rest (which was not
++ * backed previously) online too.
++ */
++ if (start_pfn > has->start_pfn &&
++ !PageReserved(pfn_to_page(start_pfn - 1)))
++ hv_bring_pgs_online(start_pfn, pgs_ol);
++
+ has->covered_end_pfn += pgs_ol;
+ pfn_cnt -= pgs_ol;
+ }
diff --git a/patches.suse/msft-hv-0791-Drivers-hv-hv_balloon-eliminate-jumps-in-piecewiese-.patch b/patches.suse/msft-hv-0791-Drivers-hv-hv_balloon-eliminate-jumps-in-piecewiese-.patch
new file mode 100644
index 0000000000..a81567e713
--- /dev/null
+++ b/patches.suse/msft-hv-0791-Drivers-hv-hv_balloon-eliminate-jumps-in-piecewiese-.patch
@@ -0,0 +1,57 @@
+From: Vitaly Kuznetsov <vkuznets@redhat.com>
+Date: Fri, 27 Mar 2015 09:10:12 -0700
+Patch-mainline: v4.1-rc1
+Subject: Drivers: hv: hv_balloon: eliminate jumps in piecewiese linear floor function
+Git-commit: 7fb0e1a65075a871c58cbcf8c877d1f9ae5cd83c
+References: fate#317533
+
+Commit 79208c57da53 ("Drivers: hv: hv_balloon: Make adjustments in computing
+the floor") was inacurate as it introduced a jump in our piecewiese linear
+'floor' function:
+
+At 2048MB we have:
+Left limit:
+104 + 2048/8 = 360
+Right limit:
+256 + 2048/16 = 384 (so the right value is 232)
+
+We now have to make an adjustment at 8192 boundary:
+232 + 8192/16 = 744
+512 + 8192/32 = 768 (so the right value is 488)
+
+Suggested-by: Laszlo Ersek <lersek@redhat.com>
+Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
+Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Acked-by: <ohering@suse.de>
+---
+ drivers/hv/hv_balloon.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/hv/hv_balloon.c b/drivers/hv/hv_balloon.c
+index 99afef9..4f5323c 100644
+--- a/drivers/hv/hv_balloon.c
++++ b/drivers/hv/hv_balloon.c
+@@ -976,8 +976,8 @@ static unsigned long compute_balloon_floor(void)
+ * 128 72 (1/2)
+ * 512 168 (1/4)
+ * 2048 360 (1/8)
+- * 8192 768 (1/16)
+- * 32768 1536 (1/32)
++ * 8192 744 (1/16)
++ * 32768 1512 (1/32)
+ */
+ if (totalram_pages < MB2PAGES(128))
+ min_pages = MB2PAGES(8) + (totalram_pages >> 1);
+@@ -986,9 +986,9 @@ static unsigned long compute_balloon_floor(void)
+ else if (totalram_pages < MB2PAGES(2048))
+ min_pages = MB2PAGES(104) + (totalram_pages >> 3);
+ else if (totalram_pages < MB2PAGES(8192))
+- min_pages = MB2PAGES(256) + (totalram_pages >> 4);
++ min_pages = MB2PAGES(232) + (totalram_pages >> 4);
+ else
+- min_pages = MB2PAGES(512) + (totalram_pages >> 5);
++ min_pages = MB2PAGES(488) + (totalram_pages >> 5);
+ #undef MB2PAGES
+ return min_pages;
+ }
diff --git a/patches.suse/msft-hv-0792-Drivers-hv-hv_balloon-survive-ballooning-request-wit.patch b/patches.suse/msft-hv-0792-Drivers-hv-hv_balloon-survive-ballooning-request-wit.patch
new file mode 100644
index 0000000000..2d9cf584af
--- /dev/null
+++ b/patches.suse/msft-hv-0792-Drivers-hv-hv_balloon-survive-ballooning-request-wit.patch
@@ -0,0 +1,123 @@
+From: Vitaly Kuznetsov <vkuznets@redhat.com>
+Date: Fri, 27 Mar 2015 09:10:13 -0700
+Patch-mainline: v4.1-rc1
+Subject: Drivers: hv: hv_balloon: survive ballooning request with num_pages=0
+Git-commit: 0a1a86ac046091d7228c9f3a283dea5be96275dd
+References: fate#317533
+
+... and simplify alloc_balloon_pages() interface by removing redundant
+alloc_error from it.
+
+If we happen to enter balloon_up() with balloon_wrk.num_pages = 0 we will enter
+infinite 'while (!done)' loop as alloc_balloon_pages() will be always returning
+0 and not setting alloc_error. We will also be sending a meaningless message to
+the host on every iteration.
+
+The 'alloc_unit == 1 && alloc_error -> num_ballooned == 0' change and
+alloc_error elimination requires a special comment. We do alloc_balloon_pages()
+with 2 different alloc_unit values and there are 4 different
+alloc_balloon_pages() results, let's check them all.
+
+alloc_unit = 512:
+1) num_ballooned = 0, alloc_error = 0: we do 'alloc_unit=1' and retry pre- and
+ post-patch.
+2) num_ballooned > 0, alloc_error = 0: we check 'num_ballooned == num_pages'
+ and act accordingly, pre- and post-patch.
+3) num_ballooned > 0, alloc_error > 0: we report this chunk and remain within
+ the loop, no changes here.
+4) num_ballooned = 0, alloc_error > 0: we do 'alloc_unit=1' and retry pre- and
+ post-patch.
+
+alloc_unit = 1:
+1) num_ballooned = 0, alloc_error = 0: this can happen in two cases: when we
+ passed 'num_pages=0' to alloc_balloon_pages() or when there was no space in
+ bl_resp to place a single response. The second option is not possible as
+ bl_resp is of PAGE_SIZE size and single response 'union dm_mem_page_range' is
+ 8 bytes, but the first one is (in theory, I think that Hyper-V host never
+ places such requests). Pre-patch code loops forever, post-patch code sends
+ a reply with more_pages = 0 and finishes.
+2) num_ballooned > 0, alloc_error = 0: we ran out of space in bl_resp, we
+ report partial success and remain within the loop, no changes pre- and
+ post-patch.
+3) num_ballooned > 0, alloc_error > 0: pre-patch code finishes, post-patch code
+ does one more try and if there is no progress (we finish with
+ 'num_ballooned = 0') we finish. So we try a bit harder with this patch.
+4) num_ballooned = 0, alloc_error > 0: both pre- and post-patch code enter
+ 'more_pages = 0' branch and finish.
+
+So this patch has two real effects:
+1) We reply with an empty response to 'num_pages=0' request.
+2) We try a bit harder on alloc_unit=1 allocations (and reply with an empty
+ tail reply in case we fail).
+
+An empty reply should be supported by host as we were able to send it even with
+pre-patch code when we were not able to allocate a single page.
+
+Suggested-by: Laszlo Ersek <lersek@redhat.com>
+Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
+Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Acked-by: <ohering@suse.de>
+---
+ drivers/hv/hv_balloon.c | 19 ++++++-------------
+ 1 file changed, 6 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/hv/hv_balloon.c b/drivers/hv/hv_balloon.c
+index 4f5323c..74312c8 100644
+--- a/drivers/hv/hv_balloon.c
++++ b/drivers/hv/hv_balloon.c
+@@ -1081,9 +1081,9 @@ static void free_balloon_pages(struct hv_dynmem_device *dm,
+
+
+
+-static int alloc_balloon_pages(struct hv_dynmem_device *dm, int num_pages,
+- struct dm_balloon_response *bl_resp, int alloc_unit,
+- bool *alloc_error)
++static int alloc_balloon_pages(struct hv_dynmem_device *dm, int num_pages,
++ struct dm_balloon_response *bl_resp,
++ int alloc_unit)
+ {
+ int i = 0;
+ struct page *pg;
+@@ -1104,11 +1104,8 @@ static int alloc_balloon_pages(struct hv_dynmem_device *dm, int num_pages,
+ __GFP_NOMEMALLOC | __GFP_NOWARN,
+ get_order(alloc_unit << PAGE_SHIFT));
+
+- if (!pg) {
+- *alloc_error = true;
++ if (!pg)
+ return i * alloc_unit;
+- }
+-
+
+ dm->num_pages_ballooned += alloc_unit;
+
+@@ -1140,7 +1137,6 @@ static void balloon_up(struct work_struct *dummy)
+ struct dm_balloon_response *bl_resp;
+ int alloc_unit;
+ int ret;
+- bool alloc_error;
+ bool done = false;
+ int i;
+ struct sysinfo val;
+@@ -1173,18 +1169,15 @@ static void balloon_up(struct work_struct *dummy)
+
+
+ num_pages -= num_ballooned;
+- alloc_error = false;
+ num_ballooned = alloc_balloon_pages(&dm_device, num_pages,
+- bl_resp, alloc_unit,
+- &alloc_error);
++ bl_resp, alloc_unit);
+
+ if (alloc_unit != 1 && num_ballooned == 0) {
+ alloc_unit = 1;
+ continue;
+ }
+
+- if ((alloc_unit == 1 && alloc_error) ||
+- (num_ballooned == num_pages)) {
++ if (num_ballooned == 0 || num_ballooned == num_pages) {
+ bl_resp->more_pages = 0;
+ done = true;
+ dm_device.state = DM_INITIALIZED;
diff --git a/patches.suse/msft-hv-0793-hv_vmbus-Add-gradually-increased-delay-for-retries-i.patch b/patches.suse/msft-hv-0793-hv_vmbus-Add-gradually-increased-delay-for-retries-i.patch
new file mode 100644
index 0000000000..1d01da2027
--- /dev/null
+++ b/patches.suse/msft-hv-0793-hv_vmbus-Add-gradually-increased-delay-for-retries-i.patch
@@ -0,0 +1,54 @@
+From: Haiyang Zhang <haiyangz@microsoft.com>
+Date: Fri, 27 Mar 2015 09:10:14 -0700
+Patch-mainline: v4.1-rc1
+Subject: hv_vmbus: Add gradually increased delay for retries in vmbus_post_msg()
+Git-commit: e1c0d82dab4a4605d3bd1968436f030dfed4a829
+References: fate#317533
+
+Most of the retries can be done within a millisecond successfully, so we
+sleep 1ms before the first retry, then gradually increase the retry
+interval to 2^n with max value of 2048ms. Doing so, we will have shorter
+overall delay time, because most of the cases succeed within 1-2 attempts.
+
+Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
+Reviewed-by: K. Y. Srinivasan <kys@microsoft.com>
+Reviewed-by: Dexuan Cui <decui@microsoft.com>
+Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Acked-by: <ohering@suse.de>
+---
+ drivers/hv/connection.c | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/hv/connection.c b/drivers/hv/connection.c
+index 583d7d4..b27220a 100644
+--- a/drivers/hv/connection.c
++++ b/drivers/hv/connection.c
+@@ -422,6 +422,7 @@ int vmbus_post_msg(void *buffer, size_t buflen)
+ union hv_connection_id conn_id;
+ int ret = 0;
+ int retries = 0;
++ u32 msec = 1;
+
+ conn_id.asu32 = 0;
+ conn_id.u.id = VMBUS_MESSAGE_CONNECTION_ID;
+@@ -431,7 +432,7 @@ int vmbus_post_msg(void *buffer, size_t buflen)
+ * insufficient resources. Retry the operation a couple of
+ * times before giving up.
+ */
+- while (retries < 10) {
++ while (retries < 20) {
+ ret = hv_post_message(conn_id, 1, buffer, buflen);
+
+ switch (ret) {
+@@ -454,7 +455,9 @@ int vmbus_post_msg(void *buffer, size_t buflen)
+ }
+
+ retries++;
+- msleep(1000);
++ msleep(msec);
++ if (msec < 2048)
++ msec *= 2;
+ }
+ return ret;
+ }
diff --git a/patches.suse/msft-hv-0794-Drivers-hv-hv_balloon-correctly-handle-val.freeram-n.patch b/patches.suse/msft-hv-0794-Drivers-hv-hv_balloon-correctly-handle-val.freeram-n.patch
new file mode 100644
index 0000000000..715b4b0122
--- /dev/null
+++ b/patches.suse/msft-hv-0794-Drivers-hv-hv_balloon-correctly-handle-val.freeram-n.patch
@@ -0,0 +1,39 @@
+From: Vitaly Kuznetsov <vkuznets@redhat.com>
+Date: Tue, 31 Mar 2015 11:16:40 -0700
+Patch-mainline: v4.1-rc1
+Subject: Drivers: hv: hv_balloon: correctly handle val.freeram<num_pages case
+Git-commit: ba0c444153889a9b672974d85a4a57a8eeb49fe3
+References: fate#317533
+
+'Drivers: hv: hv_balloon: refuse to balloon below the floor' fix does not
+correctly handle the case when val.freeram < num_pages as val.freeram is
+__kernel_ulong_t and the 'val.freeram - num_pages' value will be a huge
+positive value instead of being negative.
+
+Usually host doesn't ask us to balloon more than val.freeram but in case
+he have a memory hog started after we post the last pressure report we
+can get into troubles.
+
+Suggested-by: Laszlo Ersek <lersek@redhat.com>
+Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
+Reviewed-by: Laszlo Ersek <lersek@redhat.com>
+Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Acked-by: <ohering@suse.de>
+---
+ drivers/hv/hv_balloon.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/hv/hv_balloon.c b/drivers/hv/hv_balloon.c
+index 74312c8..4052ad8 100644
+--- a/drivers/hv/hv_balloon.c
++++ b/drivers/hv/hv_balloon.c
+@@ -1155,7 +1155,7 @@ static void balloon_up(struct work_struct *dummy)
+ floor = compute_balloon_floor();
+
+ /* Refuse to balloon below the floor, keep the 2M granularity. */
+- if (val.freeram - num_pages < floor) {
++ if (val.freeram < num_pages || val.freeram - num_pages < floor) {
+ num_pages = val.freeram > floor ? (val.freeram - floor) : 0;
+ num_pages -= num_pages % PAGES_IN_2M;
+ }
diff --git a/patches.suse/msft-hv-0795-Drivers-hv-hv_balloon-correctly-handle-num_pages-INT.patch b/patches.suse/msft-hv-0795-Drivers-hv-hv_balloon-correctly-handle-num_pages-INT.patch
new file mode 100644
index 0000000000..36b4b6ff83
--- /dev/null
+++ b/patches.suse/msft-hv-0795-Drivers-hv-hv_balloon-correctly-handle-num_pages-INT.patch
@@ -0,0 +1,58 @@
+From: Vitaly Kuznetsov <vkuznets@redhat.com>
+Date: Tue, 31 Mar 2015 11:16:41 -0700
+Patch-mainline: v4.1-rc1
+Subject: Drivers: hv: hv_balloon: correctly handle num_pages>INT_MAX case
+Git-commit: 797f88c987b02a8de8d4fac94ec2877b92ec35a2
+References: fate#317533
+
+balloon_wrk.num_pages is __u32 and it comes from host in struct dm_balloon
+where it is also __u32. We, however, use 'int' in balloon_up() and in case
+we happen to receive num_pages>INT_MAX request we'll end up allocating zero
+pages as 'num_pages < alloc_unit' check in alloc_balloon_pages() will pass.
+Change num_pages type to unsigned int.
+
+In real life ballooning request come with num_pages in [512, 32768] range so
+this is more a future-proof/cleanup.
+
+Reported-by: Laszlo Ersek <lersek@redhat.com>
+Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
+Reviewed-by: Laszlo Ersek <lersek@redhat.com>
+Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Acked-by: <ohering@suse.de>
+---
+ drivers/hv/hv_balloon.c | 13 +++++++------
+ 1 file changed, 7 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/hv/hv_balloon.c b/drivers/hv/hv_balloon.c
+index 4052ad8..cb5b7dc 100644
+--- a/drivers/hv/hv_balloon.c
++++ b/drivers/hv/hv_balloon.c
+@@ -1081,11 +1081,12 @@ static void free_balloon_pages(struct hv_dynmem_device *dm,
+
+
+
+-static int alloc_balloon_pages(struct hv_dynmem_device *dm, int num_pages,
+- struct dm_balloon_response *bl_resp,
+- int alloc_unit)
++static unsigned int alloc_balloon_pages(struct hv_dynmem_device *dm,
++ unsigned int num_pages,
++ struct dm_balloon_response *bl_resp,
++ int alloc_unit)
+ {
+- int i = 0;
++ unsigned int i = 0;
+ struct page *pg;
+
+ if (num_pages < alloc_unit)
+@@ -1132,8 +1133,8 @@ static int alloc_balloon_pages(struct hv_dynmem_device *dm, int num_pages,
+
+ static void balloon_up(struct work_struct *dummy)
+ {
+- int num_pages = dm_device.balloon_wrk.num_pages;
+- int num_ballooned = 0;
++ unsigned int num_pages = dm_device.balloon_wrk.num_pages;
++ unsigned int num_ballooned = 0;
+ struct dm_balloon_response *bl_resp;
+ int alloc_unit;
+ int ret;
diff --git a/patches.suse/suse-hv-module-unload.patch b/patches.suse/suse-hv-module-unload.patch
new file mode 100644
index 0000000000..a43cd0efab
--- /dev/null
+++ b/patches.suse/suse-hv-module-unload.patch
@@ -0,0 +1,52 @@
+Subject: hv: no rmmod for hv_vmbus and hv_utils
+From: <ohering@suse.de>
+Patch-mainline: Never
+
+The base kernel lacks support for proper rmmod/insmod.
+
+---
+ drivers/hv/hv_util.c | 3 ++-
+ drivers/hv/vmbus_drv.c | 3 ++-
+ 2 files changed, 4 insertions(+), 2 deletions(-)
+
+--- a/drivers/hv/hv_util.c
++++ b/drivers/hv/hv_util.c
+@@ -433,15 +433,16 @@ static int __init init_hyperv_utils(void
+ return vmbus_driver_register(&util_drv);
+ }
+
++#if 0
+ static void exit_hyperv_utils(void)
+ {
+ pr_info("De-Registered HyperV Utility Driver\n");
+
+ vmbus_driver_unregister(&util_drv);
+ }
++#endif
+
+ module_init(init_hyperv_utils);
+-module_exit(exit_hyperv_utils);
+
+ MODULE_DESCRIPTION("Hyper-V Utilities");
+ MODULE_LICENSE("GPL");
+--- a/drivers/hv/vmbus_drv.c
++++ b/drivers/hv/vmbus_drv.c
+@@ -962,6 +962,7 @@ cleanup:
+ return ret;
+ }
+
++#if 0
+ static void __exit vmbus_exit(void)
+ {
+ int cpu;
+@@ -978,9 +979,9 @@ static void __exit vmbus_exit(void)
+ hv_cpu_hotplug_quirk(false);
+ vmbus_disconnect();
+ }
++#endif
+
+
+ MODULE_LICENSE("GPL");
+
+ subsys_initcall(hv_acpi_init);
+-module_exit(vmbus_exit);
diff --git a/series.conf b/series.conf
index a56ca91993..46e1392a30 100644
--- a/series.conf
+++ b/series.conf
@@ -21828,6 +21828,58 @@
patches.suse/msft-hv-0739-hyperv-match-wait_for_completion_timeout-return-type.patch
patches.suse/msft-hv-0740-hyperv-Fix-the-error-processing-in-netvsc_send.patch
patches.suse/msft-hv-0741-hyperv-fix-sparse-warnings.patch
+ patches.suse/msft-hv-0742-hyperv-Implement-netvsc_get_channels-ethool-op.patch
+ patches.suse/msft-hv-0743-Drivers-hv-vmbus-prevent-cpu-offlining-on-newer-hype.patch
+ patches.suse/msft-hv-0744-Drivers-hv-vmbus-rename-channel-work-queues.patch
+ patches.suse/msft-hv-0745-Drivers-hv-vmbus-avoid-double-kfree-for-device_obj.patch
+ patches.suse/msft-hv-0746-Drivers-hv-vmbus-teardown-hv_vmbus_con-workqueue-and.patch
+ patches.suse/msft-hv-0747-drivers-hv-vmbus-Teardown-synthetic-interrupt-contro.patch
+ patches.suse/msft-hv-0748-Drivers-hv-vmbus-Teardown-clockevent-devices-on-modu.patch
+ patches.suse/msft-hv-0749-hv-hv_util-move-vmbus_open-to-a-later-place.patch
+ patches.suse/msft-hv-0750-hv-vmbus_post_msg-retry-the-hypercall-on-some-transi.patch
+ patches.suse/msft-hv-0751-hv-vmbus_open-reset-the-channel-state-on-ENOMEM.patch
+ patches.suse/msft-hv-0752-hv-channel-match-var-type-to-return-type-of-wait_for.patch
+ patches.suse/msft-hv-0753-hv-channel_mgmt-match-var-type-to-return-type-of-wai.patch
+ patches.suse/msft-hv-0754-hv-hv_balloon-match-var-type-to-return-type-of-wait_.patch
+ patches.suse/msft-hv-0755-Drivers-hv-vmbus-Fix-a-bug-in-the-error-path-in-vmbu.patch
+ patches.suse/msft-hv-0756-Drivers-hv-vmbus-Add-support-for-the-NetworkDirect-G.patch
+ patches.suse/msft-hv-0757-Drivers-hv-vmbus-Properly-handle-child-device-remove.patch
+ patches.suse/msft-hv-0758-Drivers-hv-vmbus-Introduce-a-function-to-remove-a-re.patch
+ patches.suse/msft-hv-0759-Drivers-hv-vmbus-Handle-both-rescind-and-offer-messa.patch
+ patches.suse/msft-hv-0760-Drivers-hv-vmbus-Remove-the-channel-from-the-channel.patch
+ patches.suse/msft-hv-0761-Drivers-hv-util-On-device-remove-close-the-channel-a.patch
+ patches.suse/msft-hv-0762-Drivers-hv-vmbus-Get-rid-of-some-unnecessary-message.patch
+ patches.suse/msft-hv-0763-Drivers-hv-hv_balloon-eliminate-the-trylock-path-in-.patch
+ patches.suse/msft-hv-0764-Drivers-hv-hv_balloon-report-offline-pages-as-being-.patch
+ patches.suse/msft-hv-0765-Drivers-hv-hv_balloon-refuse-to-balloon-below-the-fl.patch
+ patches.suse/msft-hv-0766-Drivers-hv-vmbus-Add-support-for-VMBus-panic-notifie.patch
+ patches.suse/msft-hv-0767-Drivers-hv-vmbus-Use-a-round-robin-algorithm-for-pic.patch
+ patches.suse/msft-hv-0768-Drivers-hv-vmbus-Suport-an-API-to-send-pagebuffers-w.patch
+ patches.suse/msft-hv-0769-Drivers-hv-vmbus-Suport-an-API-to-send-packet-with-a.patch
+ patches.suse/msft-hv-0770-mei-bus-can-be-static.patch
+ patches.suse/msft-hv-0771-hyperv-hyperv_fb-match-wait_for_completion_timeout-r.patch
+ patches.suse/msft-hv-0772-Drivers-hv-vmbus-Perform-device-register-in-the-per-.patch
+ patches.suse/msft-hv-0773-Drivers-hv-hv_balloon-keep-locks-balanced-on-add_mem.patch
+ patches.suse/msft-hv-0774-Drivers-hv-hv_balloon-don-t-lose-memory-when-onlinin.patch
+ patches.suse/msft-hv-0775-Drivers-hv-vmbus-Correcting-truncation-error-for-con.patch
+ patches.suse/msft-hv-0776-hv-vmbus-missing-curly-braces-in-vmbus_process_offer.patch
+ patches.suse/msft-hv-0778-Drivers-hv-vmbus-Fix-a-bug-in-rescind-processing-in-.patch
+ patches.suse/msft-hv-0779-hv-hypervvssd-call-endmntent-before-call-setmntent-a.patch
+ patches.suse/msft-hv-0780-Drivers-hv-vmbus-Export-the-vmbus_sendpacket_pagebuf.patch
+ patches.suse/msft-hv-0781-Drivers-hv-vmbus-Fix-a-siganlling-host-signalling-is.patch
+ patches.suse/msft-hv-0782-Drivers-hv-vmbus-Don-t-wait-after-requesting-offers.patch
+ patches.suse/msft-hv-0784-hv_netvsc-remove-vmbus_are_subchannels_present-in-rn.patch
+ patches.suse/msft-hv-0785-hv_netvsc-Cleanup-the-test-for-freeing-skb-when-we-u.patch
+ patches.suse/msft-hv-0787-hv-run-non-blocking-message-handlers-in-the-dispatch.patch
+ patches.suse/msft-hv-0788-hv-don-t-schedule-new-works-in-vmbus_onoffer-vmbus_o.patch
+ patches.suse/msft-hv-0789-hv-remove-the-per-channel-workqueue.patch
+ patches.suse/msft-hv-0790-Drivers-hv-hv_balloon-do-not-online-pages-in-offline.patch
+ patches.suse/msft-hv-0791-Drivers-hv-hv_balloon-eliminate-jumps-in-piecewiese-.patch
+ patches.suse/msft-hv-0792-Drivers-hv-hv_balloon-survive-ballooning-request-wit.patch
+ patches.suse/msft-hv-0793-hv_vmbus-Add-gradually-increased-delay-for-retries-i.patch
+ patches.suse/msft-hv-0794-Drivers-hv-hv_balloon-correctly-handle-val.freeram-n.patch
+ patches.suse/msft-hv-0795-Drivers-hv-hv_balloon-correctly-handle-num_pages-INT.patch
+
patches.suse/msft-hv-0801-scsi-storvsc-Increase-the-ring-buffer-size.patch
patches.suse/msft-hv-0802-scsi-storvsc-Size-the-queue-depth-based-on-the-ringb.patch
patches.suse/msft-hv-0803-scsi-storvsc-Always-send-on-the-selected-outgoing-ch.patch
@@ -21847,6 +21899,7 @@
patches.suse/suse-hv-bind-hv_blkkvsc-to-hv_storvsc.patch
patches.suse/suse-hv-bind-hv_mouse-to-hid-hyperv.patch
patches.suse/suse-hv-HV_DRV_VERSION.patch
+ patches.suse/suse-hv-module-unload.patch
########################################################