Home Home > GIT Browse > SLE12-SP4
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJiri Kosina <jkosina@suse.cz>2017-10-20 13:22:03 +0200
committerJiri Kosina <jkosina@suse.cz>2017-10-20 13:22:03 +0200
commit845773a994638565570c3c346dfdcfed50716171 (patch)
tree7c3de9afa3395fc3199e045181d01fdb44031b93
parentce8476f4750d3a30e72b5ee537288a2404e7a6c1 (diff)
parent6f087bf06b3d0bddf1475b2a2c59fb82564e4640 (diff)
Merge remote-tracking branch 'origin/users/ohering/SLE15/for-next' into SLE15rpm-4.12.14-2
-rw-r--r--patches.suse/msft-hv-1376-tools-hv-ignore-a-NIC-if-it-has-been-configured.patch67
-rw-r--r--patches.suse/msft-hv-1378-vmbus-simplify-hv_ringbuffer_read.patch190
-rw-r--r--patches.suse/msft-hv-1379-vmbus-drop-unused-ring_buffer_info-elements.patch30
-rw-r--r--patches.suse/msft-hv-1380-vmbus-refactor-hv_signal_on_read.patch141
-rw-r--r--patches.suse/msft-hv-1381-vmbus-eliminate-duplicate-cached-index.patch101
-rw-r--r--patches.suse/msft-hv-1382-vmbus-more-host-signalling-avoidance.patch65
-rw-r--r--patches.suse/msft-hv-1383-vmbus-add-prefetch-to-ring-buffer-iterator.patch39
-rw-r--r--patches.suse/msft-hv-1384-x86-hyper-v-include-hyperv-only-when-CONFIG_HYPERV-i.patch50
-rw-r--r--patches.suse/msft-hv-1385-x86-hyper-v-stash-the-max-number-of-virtual-logical-.patch71
-rw-r--r--patches.suse/msft-hv-1394-Revert-x86-hyper-v-include-hyperv-only-when-CONFIG_H.patch54
-rw-r--r--patches.suse/msft-hv-1410-netvsc-Initialize-64-bit-stats-seqcount.patch35
-rw-r--r--patches.suse/msft-hv-1413-netvsc-remove-bonding-setup-script.patch278
-rw-r--r--patches.suse/msft-hv-1414-PCI-hv-Do-not-sleep-in-compose_msi_msg.patch57
-rw-r--r--patches.suse/msft-hv-1415-netvsc-fix-race-on-sub-channel-creation.patch121
-rw-r--r--patches.suse/msft-hv-1418-x86-hyper-v-Include-hyperv-only-when-CONFIG_HYPERV-i.patch61
-rw-r--r--patches.suse/msft-hv-1419-x86-hyper-v-Make-hv_do_hypercall-inline.patch202
-rw-r--r--patches.suse/msft-hv-1420-x86-hyper-v-Introduce-fast-hypercall-implementation.patch75
-rw-r--r--patches.suse/msft-hv-1421-hyper-v-Use-fast-hypercall-for-HVCALL_SIGNAL_EVENT.patch103
-rw-r--r--patches.suse/msft-hv-1422-x86-hyper-v-Implement-rep-hypercalls.patch99
-rw-r--r--patches.suse/msft-hv-1423-hyper-v-Globalize-vp_index.patch366
-rw-r--r--patches.suse/msft-hv-1424-x86-hyper-v-Use-hypercall-for-remote-TLB-flush.patch278
-rw-r--r--patches.suse/msft-hv-1425-netvsc-delay-setup-of-VF-device.patch95
-rw-r--r--patches.suse/msft-hv-1426-netvsc-don-t-signal-host-twice-if-empty.patch31
-rw-r--r--patches.suse/msft-hv-1427-netvsc-propagate-MAC-address-change-to-VF-slave.patch72
-rw-r--r--patches.suse/msft-hv-1428-netvsc-check-error-return-when-restoring-channels-an.patch54
-rw-r--r--patches.suse/msft-hv-1429-netvsc-no-need-to-allocate-send-receive-on-numa-node.patch58
-rw-r--r--patches.suse/msft-hv-1430-netvsc-whitespace-cleanup.patch65
-rw-r--r--patches.suse/msft-hv-1431-netvsc-remove-unnecessary-cast-of-void-pointer.patch43
-rw-r--r--patches.suse/msft-hv-1432-netvsc-remove-unnecessary-check-for-NULL-hdr.patch34
-rw-r--r--patches.suse/msft-hv-1433-netvsc-allow-controlling-send-recv-buffer-size.patch412
-rw-r--r--patches.suse/msft-hv-1434-netvsc-keep-track-of-some-non-fatal-overload-conditi.patch104
-rw-r--r--patches.suse/msft-hv-1435-Tools-hv-vss-Skip-freezing-filesystems-backed-by-loo.patch63
-rw-r--r--patches.suse/msft-hv-1436-Drivers-hv-balloon-Correctly-update-onlined-page-cou.patch45
-rw-r--r--patches.suse/msft-hv-1437-Drivers-hv-balloon-Show-the-max-dynamic-memory-assig.patch33
-rw-r--r--patches.suse/msft-hv-1438-Drivers-hv-balloon-Initialize-last_post_time-on-star.patch36
-rw-r--r--patches.suse/msft-hv-1439-Drivers-hv-kvp-Use-MAX_ADAPTER_ID_SIZE-for-translati.patch35
-rw-r--r--patches.suse/msft-hv-1440-Tools-hv-fix-snprintf-warning-in-kvp_daemon.patch30
-rw-r--r--patches.suse/msft-hv-1441-Tools-hv-update-buffer-handling-in-hv_fcopy_daemon.patch100
-rw-r--r--patches.suse/msft-hv-1442-Drivers-hv-vmbus-Fix-rescind-handling-issues.patch161
-rw-r--r--patches.suse/msft-hv-1443-vmbus-remove-unused-vmbus_sendpacket_multipagebuffer.patch99
-rw-r--r--patches.suse/msft-hv-1444-vmbus-remove-unused-vmubs_sendpacket_pagebuffer_ctl.patch116
-rw-r--r--patches.suse/msft-hv-1445-vmbus-remove-unused-vmbus_sendpacket_ctl.patch114
-rw-r--r--patches.suse/msft-hv-1446-hv_netvsc-Clean-up-unused-parameter-from-netvsc_get_.patch37
-rw-r--r--patches.suse/msft-hv-1447-hv_netvsc-Clean-up-unused-parameter-from-netvsc_get_.patch38
-rw-r--r--patches.suse/msft-hv-1448-hv_netvsc-Add-ethtool-handler-to-set-and-get-UDP-has.patch187
-rw-r--r--patches.suse/msft-hv-1449-hv_netvsc-Fix-rndis_filter_close-error-during-netvsc.patch48
-rw-r--r--patches.suse/msft-hv-1452-scsi-storvsc-fix-memory-leak-on-ring-buffer-busy.patch37
-rw-r--r--patches.suse/msft-hv-1453-x86-hyper-v-Support-extended-CPU-ranges-for-TLB-flus.patch236
-rw-r--r--patches.suse/msft-hv-1454-tracing-hyper-v-Trace-hyperv_mmu_flush_tlb_others.patch121
-rw-r--r--patches.suse/msft-hv-1455-netvsc-cleanup-datapath-switch.patch84
-rw-r--r--patches.suse/msft-hv-1456-netvsc-allow-driver-to-be-removed-even-if-VF-is-pres.patch77
-rw-r--r--patches.suse/msft-hv-1457-hv_netvsc-Clean-up-an-unused-parameter-in-rndis_filt.patch65
-rw-r--r--patches.suse/msft-hv-1458-hv_netvsc-Simplify-num_chn-checking-in-rndis_filter_.patch40
-rw-r--r--patches.suse/msft-hv-1459-hv_netvsc-Simplify-the-limit-check-in-netvsc_set_cha.patch39
-rw-r--r--patches.suse/msft-hv-1460-hv_netvsc-Fix-the-channel-limit-in-netvsc_set_rxfh.patch29
-rw-r--r--patches.suse/msft-hv-1461-hv_netvsc-fix-deadlock-on-hotplug.patch291
-rw-r--r--patches.suse/msft-hv-1462-hv_netvsc-avoid-unnecessary-wakeups-on-subchannel-cr.patch31
-rw-r--r--patches.suse/msft-hv-1464-x86-hyper-v-Remove-duplicated-HV_X64_EX_PROCESSOR_MA.patch46
-rw-r--r--patches.suse/msft-hv-1465-netvsc-increase-default-receive-buffer-size.patch32
-rw-r--r--patches.suse/msft-hv-1466-hv_netvsc-fix-send-buffer-failure-on-MTU-change.patch122
-rw-r--r--patches.suse/msft-hv-1467-vmbus-don-t-acquire-the-mutex-in-vmbus_hvsock_device.patch45
-rw-r--r--patches.suse/msft-hv-1468-Drivers-hv-fcopy-restore-correct-transfer-length.patch52
-rw-r--r--patches.suse/msft-hv-1470-Drivers-hv-vmbus-Fix-bugs-in-rescind-handling.patch196
-rw-r--r--patches.suse/msft-hv-1471-x86-hyperv-Clear-vCPU-banks-between-calls-to-avoid-f.patch101
-rw-r--r--patches.suse/msft-hv-1472-x86-hyperv-Don-t-use-percpu-areas-for-pcpu_flush-pcp.patch115
-rw-r--r--patches.suse/msft-hv-1473-x86-hyperv-Fix-hypercalls-with-extended-CPU-ranges-f.patch66
-rw-r--r--patches.suse/suse-hv-guest-os-id.patch2
-rw-r--r--series.conf66
68 files changed, 6485 insertions, 1 deletions
diff --git a/patches.suse/msft-hv-1376-tools-hv-ignore-a-NIC-if-it-has-been-configured.patch b/patches.suse/msft-hv-1376-tools-hv-ignore-a-NIC-if-it-has-been-configured.patch
new file mode 100644
index 0000000000..0945a42360
--- /dev/null
+++ b/patches.suse/msft-hv-1376-tools-hv-ignore-a-NIC-if-it-has-been-configured.patch
@@ -0,0 +1,67 @@
+From: "sixiao@microsoft.com" <sixiao@microsoft.com>
+Date: Fri, 14 Jul 2017 10:47:20 -0700
+Patch-mainline: v4.14-rc1
+Subject: tools: hv: ignore a NIC if it has been configured
+Git-commit: 1c3a044c6013b7fcf4738129a1141c9c1994bb86
+References: fate#323887
+
+Let bondvf.sh ignore this NIC if it has been configured, to prevent
+user configuration from being overwritten unexpectly.
+
+Signed-off-by: Simon Xiao <sixiao@microsoft.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Acked-by: Olaf Hering <ohering@suse.de>
+---
+ tools/hv/bondvf.sh | 27 +++++++++++++++++++++++++--
+ 1 file changed, 25 insertions(+), 2 deletions(-)
+
+diff --git a/tools/hv/bondvf.sh b/tools/hv/bondvf.sh
+--- a/tools/hv/bondvf.sh
++++ b/tools/hv/bondvf.sh
+@@ -211,6 +211,30 @@ function create_bond {
+
+ echo $'\nBond name:' $bondname
+
++ if [ $distro == ubuntu ]
++ then
++ local mainfn=$cfgdir/interfaces
++ local s="^[ \t]*(auto|iface|mapping|allow-.*)[ \t]+${bondname}"
++
++ grep -E "$s" $mainfn
++ if [ $? -eq 0 ]
++ then
++ echo "WARNING: ${bondname} has been configured already"
++ return
++ fi
++ elif [ $distro == redhat ] || [ $distro == suse ]
++ then
++ local fn=$cfgdir/ifcfg-$bondname
++ if [ -f $fn ]
++ then
++ echo "WARNING: ${bondname} has been configured already"
++ return
++ fi
++ else
++ echo "Unsupported Distro: ${distro}"
++ return
++ fi
++
+ echo configuring $primary
+ create_eth_cfg_pri_$distro $primary $bondname
+
+@@ -219,8 +243,6 @@ function create_bond {
+
+ echo creating: $bondname with primary slave: $primary
+ create_bond_cfg_$distro $bondname $primary $secondary
+-
+- let bondcnt=bondcnt+1
+ }
+
+ for (( i=0; i < $eth_cnt-1; i++ ))
+@@ -228,5 +250,6 @@ do
+ if [ -n "${list_match[$i]}" ]
+ then
+ create_bond ${list_eth[$i]} ${list_match[$i]}
++ let bondcnt=bondcnt+1
+ fi
+ done
diff --git a/patches.suse/msft-hv-1378-vmbus-simplify-hv_ringbuffer_read.patch b/patches.suse/msft-hv-1378-vmbus-simplify-hv_ringbuffer_read.patch
new file mode 100644
index 0000000000..9b6ede9e92
--- /dev/null
+++ b/patches.suse/msft-hv-1378-vmbus-simplify-hv_ringbuffer_read.patch
@@ -0,0 +1,190 @@
+From: Stephen Hemminger <stephen@networkplumber.org>
+Date: Sun, 25 Jun 2017 12:30:24 -0700
+Patch-mainline: v4.14-rc1
+Subject: vmbus: simplify hv_ringbuffer_read
+Git-commit: 4226ff69a3dff78bead7d9a270423cd21f8d40b8
+References: fate#323887
+
+With new iterator functions (and the double mapping) the ring buffer
+read function can be greatly simplified.
+
+Signed-off-by: Stephen Hemminger <sthemmin@microsoft.com>
+Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Acked-by: Olaf Hering <ohering@suse.de>
+---
+ drivers/hv/ring_buffer.c | 118 +++++++----------------------------------------
+ 1 file changed, 17 insertions(+), 101 deletions(-)
+
+diff --git a/drivers/hv/ring_buffer.c b/drivers/hv/ring_buffer.c
+--- a/drivers/hv/ring_buffer.c
++++ b/drivers/hv/ring_buffer.c
+@@ -94,30 +94,6 @@ hv_set_next_write_location(struct hv_ring_buffer_info *ring_info,
+ ring_info->ring_buffer->write_index = next_write_location;
+ }
+
+-/* Get the next read location for the specified ring buffer. */
+-static inline u32
+-hv_get_next_read_location(const struct hv_ring_buffer_info *ring_info)
+-{
+- return ring_info->ring_buffer->read_index;
+-}
+-
+-/*
+- * Get the next read location + offset for the specified ring buffer.
+- * This allows the caller to skip.
+- */
+-static inline u32
+-hv_get_next_readlocation_withoffset(const struct hv_ring_buffer_info *ring_info,
+- u32 offset)
+-{
+- u32 next = ring_info->ring_buffer->read_index;
+-
+- next += offset;
+- if (next >= ring_info->ring_datasize)
+- next -= ring_info->ring_datasize;
+-
+- return next;
+-}
+-
+ /* Set the next read location for the specified ring buffer. */
+ static inline void
+ hv_set_next_read_location(struct hv_ring_buffer_info *ring_info,
+@@ -141,29 +117,6 @@ hv_get_ring_bufferindices(struct hv_ring_buffer_info *ring_info)
+ return (u64)ring_info->ring_buffer->write_index << 32;
+ }
+
+-/*
+- * Helper routine to copy to source from ring buffer.
+- * Assume there is enough room. Handles wrap-around in src case only!!
+- */
+-static u32 hv_copyfrom_ringbuffer(
+- const struct hv_ring_buffer_info *ring_info,
+- void *dest,
+- u32 destlen,
+- u32 start_read_offset)
+-{
+- void *ring_buffer = hv_get_ring_buffer(ring_info);
+- u32 ring_buffer_size = hv_get_ring_buffersize(ring_info);
+-
+- memcpy(dest, ring_buffer + start_read_offset, destlen);
+-
+- start_read_offset += destlen;
+- if (start_read_offset >= ring_buffer_size)
+- start_read_offset -= ring_buffer_size;
+-
+- return start_read_offset;
+-}
+-
+-
+ /*
+ * Helper routine to copy from source to ring buffer.
+ * Assume there is enough room. Handles wrap-around in dest case only!!
+@@ -334,33 +287,22 @@ int hv_ringbuffer_write(struct vmbus_channel *channel,
+ return 0;
+ }
+
+-static inline void
+-init_cached_read_index(struct hv_ring_buffer_info *rbi)
+-{
+- rbi->cached_read_index = rbi->ring_buffer->read_index;
+-}
+-
+ int hv_ringbuffer_read(struct vmbus_channel *channel,
+ void *buffer, u32 buflen, u32 *buffer_actual_len,
+ u64 *requestid, bool raw)
+ {
+- u32 bytes_avail_toread;
+- u32 next_read_location;
+- u64 prev_indices = 0;
+- struct vmpacket_descriptor desc;
+- u32 offset;
+- u32 packetlen;
+- struct hv_ring_buffer_info *inring_info = &channel->inbound;
+-
+- if (buflen <= 0)
++ struct vmpacket_descriptor *desc;
++ u32 packetlen, offset;
++
++ if (unlikely(buflen == 0))
+ return -EINVAL;
+
+ *buffer_actual_len = 0;
+ *requestid = 0;
+
+- bytes_avail_toread = hv_get_bytes_to_read(inring_info);
+ /* Make sure there is something to read */
+- if (bytes_avail_toread < sizeof(desc)) {
++ desc = hv_pkt_iter_first(channel);
++ if (desc == NULL) {
+ /*
+ * No error is set when there is even no header, drivers are
+ * supposed to analyze buffer_actual_len.
+@@ -368,48 +310,22 @@ int hv_ringbuffer_read(struct vmbus_channel *channel,
+ return 0;
+ }
+
+- init_cached_read_index(inring_info);
+-
+- next_read_location = hv_get_next_read_location(inring_info);
+- next_read_location = hv_copyfrom_ringbuffer(inring_info, &desc,
+- sizeof(desc),
+- next_read_location);
+-
+- offset = raw ? 0 : (desc.offset8 << 3);
+- packetlen = (desc.len8 << 3) - offset;
++ offset = raw ? 0 : (desc->offset8 << 3);
++ packetlen = (desc->len8 << 3) - offset;
+ *buffer_actual_len = packetlen;
+- *requestid = desc.trans_id;
+-
+- if (bytes_avail_toread < packetlen + offset)
+- return -EAGAIN;
++ *requestid = desc->trans_id;
+
+- if (packetlen > buflen)
++ if (unlikely(packetlen > buflen))
+ return -ENOBUFS;
+
+- next_read_location =
+- hv_get_next_readlocation_withoffset(inring_info, offset);
++ /* since ring is double mapped, only one copy is necessary */
++ memcpy(buffer, (const char *)desc + offset, packetlen);
+
+- next_read_location = hv_copyfrom_ringbuffer(inring_info,
+- buffer,
+- packetlen,
+- next_read_location);
++ /* Advance ring index to next packet descriptor */
++ __hv_pkt_iter_next(channel, desc);
+
+- next_read_location = hv_copyfrom_ringbuffer(inring_info,
+- &prev_indices,
+- sizeof(u64),
+- next_read_location);
+-
+- /*
+- * Make sure all reads are done before we update the read index since
+- * the writer may start writing to the read area once the read index
+- * is updated.
+- */
+- virt_mb();
+-
+- /* Update the read index */
+- hv_set_next_read_location(inring_info, next_read_location);
+-
+- hv_signal_on_read(channel);
++ /* Notify host of update */
++ hv_pkt_iter_close(channel);
+
+ return 0;
+ }
+@@ -442,7 +358,7 @@ struct vmpacket_descriptor *hv_pkt_iter_first(struct vmbus_channel *channel)
+ struct hv_ring_buffer_info *rbi = &channel->inbound;
+
+ /* set state for later hv_signal_on_read() */
+- init_cached_read_index(rbi);
++ rbi->cached_read_index = rbi->ring_buffer->read_index;
+
+ if (hv_pkt_iter_avail(rbi) < sizeof(struct vmpacket_descriptor))
+ return NULL;
diff --git a/patches.suse/msft-hv-1379-vmbus-drop-unused-ring_buffer_info-elements.patch b/patches.suse/msft-hv-1379-vmbus-drop-unused-ring_buffer_info-elements.patch
new file mode 100644
index 0000000000..79a504d3b7
--- /dev/null
+++ b/patches.suse/msft-hv-1379-vmbus-drop-unused-ring_buffer_info-elements.patch
@@ -0,0 +1,30 @@
+From: Stephen Hemminger <stephen@networkplumber.org>
+Date: Sun, 25 Jun 2017 12:30:25 -0700
+Patch-mainline: v4.14-rc1
+Subject: vmbus: drop unused ring_buffer_info elements
+Git-commit: 95c40f41cfaf34e1c07812e93aa4b3263f9953f3
+References: fate#323887
+
+The elements ring_data_start_offset and priv_write_index
+are not used.
+
+Signed-off-by: Stephen Hemminger <sthemmin@microsoft.com>
+Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Acked-by: Olaf Hering <ohering@suse.de>
+---
+ include/linux/hyperv.h | 2 --
+ 1 file changed, 2 deletions(-)
+
+diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
+--- a/include/linux/hyperv.h
++++ b/include/linux/hyperv.h
+@@ -124,8 +124,6 @@ struct hv_ring_buffer_info {
+ spinlock_t ring_lock;
+
+ u32 ring_datasize; /* < ring_size */
+- u32 ring_data_startoffset;
+- u32 priv_write_index;
+ u32 priv_read_index;
+ u32 cached_read_index;
+ };
diff --git a/patches.suse/msft-hv-1380-vmbus-refactor-hv_signal_on_read.patch b/patches.suse/msft-hv-1380-vmbus-refactor-hv_signal_on_read.patch
new file mode 100644
index 0000000000..abdab63619
--- /dev/null
+++ b/patches.suse/msft-hv-1380-vmbus-refactor-hv_signal_on_read.patch
@@ -0,0 +1,141 @@
+From: Stephen Hemminger <stephen@networkplumber.org>
+Date: Sun, 25 Jun 2017 12:30:26 -0700
+Patch-mainline: v4.14-rc1
+Subject: vmbus: refactor hv_signal_on_read
+Git-commit: 8dd45f2ab005a1f3301296059b23b03ec3dbf79b
+References: fate#323887
+
+The function hv_signal_on_read was defined in hyperv.h and
+only used in one place in ring_buffer code. Clearer to just
+move it inline there.
+
+Signed-off-by: Stephen Hemminger <sthemmin@microsoft.com>
+Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Acked-by: Olaf Hering <ohering@suse.de>
+---
+ drivers/hv/ring_buffer.c | 32 +++++++++++++++++++++++++++++--
+ include/linux/hyperv.h | 49 ------------------------------------------------
+ 2 files changed, 30 insertions(+), 51 deletions(-)
+
+diff --git a/drivers/hv/ring_buffer.c b/drivers/hv/ring_buffer.c
+--- a/drivers/hv/ring_buffer.c
++++ b/drivers/hv/ring_buffer.c
+@@ -29,6 +29,7 @@
+ #include <linux/uio.h>
+ #include <linux/vmalloc.h>
+ #include <linux/slab.h>
++#include <linux/prefetch.h>
+
+ #include "hyperv_vmbus.h"
+
+@@ -357,7 +358,7 @@ struct vmpacket_descriptor *hv_pkt_iter_first(struct vmbus_channel *channel)
+ {
+ struct hv_ring_buffer_info *rbi = &channel->inbound;
+
+- /* set state for later hv_signal_on_read() */
++ /* set state for later hv_pkt_iter_close */
+ rbi->cached_read_index = rbi->ring_buffer->read_index;
+
+ if (hv_pkt_iter_avail(rbi) < sizeof(struct vmpacket_descriptor))
+@@ -400,6 +401,8 @@ EXPORT_SYMBOL_GPL(__hv_pkt_iter_next);
+ void hv_pkt_iter_close(struct vmbus_channel *channel)
+ {
+ struct hv_ring_buffer_info *rbi = &channel->inbound;
++ u32 cur_write_sz, cached_write_sz;
++ u32 pending_sz;
+
+ /*
+ * Make sure all reads are done before we update the read index since
+@@ -409,6 +412,31 @@ void hv_pkt_iter_close(struct vmbus_channel *channel)
+ virt_rmb();
+ rbi->ring_buffer->read_index = rbi->priv_read_index;
+
+- hv_signal_on_read(channel);
++ /*
++ * Issue a full memory barrier before making the signaling decision.
++ * Here is the reason for having this barrier:
++ * If the reading of the pend_sz (in this function)
++ * were to be reordered and read before we commit the new read
++ * index (in the calling function) we could
++ * have a problem. If the host were to set the pending_sz after we
++ * have sampled pending_sz and go to sleep before we commit the
++ * read index, we could miss sending the interrupt. Issue a full
++ * memory barrier to address this.
++ */
++ virt_mb();
++
++ pending_sz = READ_ONCE(rbi->ring_buffer->pending_send_sz);
++ /* If the other end is not blocked on write don't bother. */
++ if (pending_sz == 0)
++ return;
++
++ cur_write_sz = hv_get_bytes_to_write(rbi);
++
++ if (cur_write_sz < pending_sz)
++ return;
++
++ cached_write_sz = hv_get_cached_bytes_to_write(rbi);
++ if (cached_write_sz < pending_sz)
++ vmbus_setevent(channel);
+ }
+ EXPORT_SYMBOL_GPL(hv_pkt_iter_close);
+diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
+--- a/include/linux/hyperv.h
++++ b/include/linux/hyperv.h
+@@ -1471,55 +1471,6 @@ hv_get_ring_buffer(const struct hv_ring_buffer_info *ring_info)
+ return ring_info->ring_buffer->buffer;
+ }
+
+-/*
+- * To optimize the flow management on the send-side,
+- * when the sender is blocked because of lack of
+- * sufficient space in the ring buffer, potential the
+- * consumer of the ring buffer can signal the producer.
+- * This is controlled by the following parameters:
+- *
+- * 1. pending_send_sz: This is the size in bytes that the
+- * producer is trying to send.
+- * 2. The feature bit feat_pending_send_sz set to indicate if
+- * the consumer of the ring will signal when the ring
+- * state transitions from being full to a state where
+- * there is room for the producer to send the pending packet.
+- */
+-
+-static inline void hv_signal_on_read(struct vmbus_channel *channel)
+-{
+- u32 cur_write_sz, cached_write_sz;
+- u32 pending_sz;
+- struct hv_ring_buffer_info *rbi = &channel->inbound;
+-
+- /*
+- * Issue a full memory barrier before making the signaling decision.
+- * Here is the reason for having this barrier:
+- * If the reading of the pend_sz (in this function)
+- * were to be reordered and read before we commit the new read
+- * index (in the calling function) we could
+- * have a problem. If the host were to set the pending_sz after we
+- * have sampled pending_sz and go to sleep before we commit the
+- * read index, we could miss sending the interrupt. Issue a full
+- * memory barrier to address this.
+- */
+- virt_mb();
+-
+- pending_sz = READ_ONCE(rbi->ring_buffer->pending_send_sz);
+- /* If the other end is not blocked on write don't bother. */
+- if (pending_sz == 0)
+- return;
+-
+- cur_write_sz = hv_get_bytes_to_write(rbi);
+-
+- if (cur_write_sz < pending_sz)
+- return;
+-
+- cached_write_sz = hv_get_cached_bytes_to_write(rbi);
+- if (cached_write_sz < pending_sz)
+- vmbus_setevent(channel);
+-}
+-
+ /*
+ * Mask off host interrupt callback notifications
+ */
diff --git a/patches.suse/msft-hv-1381-vmbus-eliminate-duplicate-cached-index.patch b/patches.suse/msft-hv-1381-vmbus-eliminate-duplicate-cached-index.patch
new file mode 100644
index 0000000000..50f560deeb
--- /dev/null
+++ b/patches.suse/msft-hv-1381-vmbus-eliminate-duplicate-cached-index.patch
@@ -0,0 +1,101 @@
+From: Stephen Hemminger <stephen@networkplumber.org>
+Date: Sun, 25 Jun 2017 12:30:27 -0700
+Patch-mainline: v4.14-rc1
+Subject: vmbus: eliminate duplicate cached index
+Git-commit: 05d00bc94ac27d220d8a78e365d7fa3a26dcca17
+References: fate#323887
+
+Don't need cached read index anymore now that packet iterator
+is used. The iterator has the original read index until the
+visible read_index is updated.
+
+Signed-off-by: Stephen Hemminger <sthemmin@microsoft.com>
+Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Acked-by: Olaf Hering <ohering@suse.de>
+---
+ drivers/hv/ring_buffer.c | 17 ++++-------------
+ include/linux/hyperv.h | 14 --------------
+ 2 files changed, 4 insertions(+), 27 deletions(-)
+
+diff --git a/drivers/hv/ring_buffer.c b/drivers/hv/ring_buffer.c
+--- a/drivers/hv/ring_buffer.c
++++ b/drivers/hv/ring_buffer.c
+@@ -358,9 +358,6 @@ struct vmpacket_descriptor *hv_pkt_iter_first(struct vmbus_channel *channel)
+ {
+ struct hv_ring_buffer_info *rbi = &channel->inbound;
+
+- /* set state for later hv_pkt_iter_close */
+- rbi->cached_read_index = rbi->ring_buffer->read_index;
+-
+ if (hv_pkt_iter_avail(rbi) < sizeof(struct vmpacket_descriptor))
+ return NULL;
+
+@@ -388,10 +385,7 @@ __hv_pkt_iter_next(struct vmbus_channel *channel,
+ rbi->priv_read_index -= dsize;
+
+ /* more data? */
+- if (hv_pkt_iter_avail(rbi) < sizeof(struct vmpacket_descriptor))
+- return NULL;
+- else
+- return hv_get_ring_buffer(rbi) + rbi->priv_read_index;
++ return hv_pkt_iter_first(channel);
+ }
+ EXPORT_SYMBOL_GPL(__hv_pkt_iter_next);
+
+@@ -401,7 +395,7 @@ EXPORT_SYMBOL_GPL(__hv_pkt_iter_next);
+ void hv_pkt_iter_close(struct vmbus_channel *channel)
+ {
+ struct hv_ring_buffer_info *rbi = &channel->inbound;
+- u32 cur_write_sz, cached_write_sz;
++ u32 orig_write_sz = hv_get_bytes_to_write(rbi);
+ u32 pending_sz;
+
+ /*
+@@ -430,13 +424,10 @@ void hv_pkt_iter_close(struct vmbus_channel *channel)
+ if (pending_sz == 0)
+ return;
+
+- cur_write_sz = hv_get_bytes_to_write(rbi);
+-
+- if (cur_write_sz < pending_sz)
++ if (hv_get_bytes_to_write(rbi) < pending_sz)
+ return;
+
+- cached_write_sz = hv_get_cached_bytes_to_write(rbi);
+- if (cached_write_sz < pending_sz)
++ if (orig_write_sz < pending_sz)
+ vmbus_setevent(channel);
+ }
+ EXPORT_SYMBOL_GPL(hv_pkt_iter_close);
+diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
+--- a/include/linux/hyperv.h
++++ b/include/linux/hyperv.h
+@@ -125,7 +125,6 @@ struct hv_ring_buffer_info {
+
+ u32 ring_datasize; /* < ring_size */
+ u32 priv_read_index;
+- u32 cached_read_index;
+ };
+
+ /*
+@@ -178,19 +177,6 @@ static inline u32 hv_get_bytes_to_write(const struct hv_ring_buffer_info *rbi)
+ return write;
+ }
+
+-static inline u32 hv_get_cached_bytes_to_write(
+- const struct hv_ring_buffer_info *rbi)
+-{
+- u32 read_loc, write_loc, dsize, write;
+-
+- dsize = rbi->ring_datasize;
+- read_loc = rbi->cached_read_index;
+- write_loc = rbi->ring_buffer->write_index;
+-
+- write = write_loc >= read_loc ? dsize - (write_loc - read_loc) :
+- read_loc - write_loc;
+- return write;
+-}
+ /*
+ * VMBUS version is 32 bit entity broken up into
+ * two 16 bit quantities: major_number. minor_number.
diff --git a/patches.suse/msft-hv-1382-vmbus-more-host-signalling-avoidance.patch b/patches.suse/msft-hv-1382-vmbus-more-host-signalling-avoidance.patch
new file mode 100644
index 0000000000..9b797badd8
--- /dev/null
+++ b/patches.suse/msft-hv-1382-vmbus-more-host-signalling-avoidance.patch
@@ -0,0 +1,65 @@
+From: Stephen Hemminger <stephen@networkplumber.org>
+Date: Sun, 25 Jun 2017 12:30:28 -0700
+Patch-mainline: v4.14-rc1
+Subject: vmbus: more host signalling avoidance
+Git-commit: 03bad714a1619c0074eb44d6f217c505fe27030f
+References: fate#323887
+
+Don't signal host if it has disabled interrupts for that
+ring buffer. Check the feature bit to see if host supports
+pending send size flag.
+
+Signed-off-by: Stephen Hemminger <sthemmin@microsoft.com>
+Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Acked-by: Olaf Hering <ohering@suse.de>
+---
+ drivers/hv/ring_buffer.c | 27 +++++++++++++++++++--------
+ 1 file changed, 19 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/hv/ring_buffer.c b/drivers/hv/ring_buffer.c
+--- a/drivers/hv/ring_buffer.c
++++ b/drivers/hv/ring_buffer.c
+@@ -396,7 +396,6 @@ void hv_pkt_iter_close(struct vmbus_channel *channel)
+ {
+ struct hv_ring_buffer_info *rbi = &channel->inbound;
+ u32 orig_write_sz = hv_get_bytes_to_write(rbi);
+- u32 pending_sz;
+
+ /*
+ * Make sure all reads are done before we update the read index since
+@@ -419,15 +418,27 @@ void hv_pkt_iter_close(struct vmbus_channel *channel)
+ */
+ virt_mb();
+
+- pending_sz = READ_ONCE(rbi->ring_buffer->pending_send_sz);
+- /* If the other end is not blocked on write don't bother. */
+- if (pending_sz == 0)
++ /* If host has disabled notifications then skip */
++ if (rbi->ring_buffer->interrupt_mask)
+ return;
+
+- if (hv_get_bytes_to_write(rbi) < pending_sz)
+- return;
++ if (rbi->ring_buffer->feature_bits.feat_pending_send_sz) {
++ u32 pending_sz = READ_ONCE(rbi->ring_buffer->pending_send_sz);
+
+- if (orig_write_sz < pending_sz)
+- vmbus_setevent(channel);
++ /*
++ * If there was space before we began iteration,
++ * then host was not blocked. Also handles case where
++ * pending_sz is zero then host has nothing pending
++ * and does not need to be signaled.
++ */
++ if (orig_write_sz > pending_sz)
++ return;
++
++ /* If pending write will not fit, don't give false hope. */
++ if (hv_get_bytes_to_write(rbi) < pending_sz)
++ return;
++ }
++
++ vmbus_setevent(channel);
+ }
+ EXPORT_SYMBOL_GPL(hv_pkt_iter_close);
diff --git a/patches.suse/msft-hv-1383-vmbus-add-prefetch-to-ring-buffer-iterator.patch b/patches.suse/msft-hv-1383-vmbus-add-prefetch-to-ring-buffer-iterator.patch
new file mode 100644
index 0000000000..9424cf1cd7
--- /dev/null
+++ b/patches.suse/msft-hv-1383-vmbus-add-prefetch-to-ring-buffer-iterator.patch
@@ -0,0 +1,39 @@
+From: Stephen Hemminger <stephen@networkplumber.org>
+Date: Sun, 25 Jun 2017 12:30:29 -0700
+Patch-mainline: v4.14-rc1
+Subject: vmbus: add prefetch to ring buffer iterator
+Git-commit: 15e1674de747d58c5a6154ba6e85bc61e5009b08
+References: fate#323887
+
+When iterating over incoming ring elements from the host, prefetch
+the next descriptor so that it is cache hot.
+
+Signed-off-by: Stephen Hemminger <sthemmin@microsoft.com>
+Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Acked-by: Olaf Hering <ohering@suse.de>
+---
+ drivers/hv/ring_buffer.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/hv/ring_buffer.c b/drivers/hv/ring_buffer.c
+--- a/drivers/hv/ring_buffer.c
++++ b/drivers/hv/ring_buffer.c
+@@ -357,11 +357,16 @@ static u32 hv_pkt_iter_avail(const struct hv_ring_buffer_info *rbi)
+ struct vmpacket_descriptor *hv_pkt_iter_first(struct vmbus_channel *channel)
+ {
+ struct hv_ring_buffer_info *rbi = &channel->inbound;
++ struct vmpacket_descriptor *desc;
+
+ if (hv_pkt_iter_avail(rbi) < sizeof(struct vmpacket_descriptor))
+ return NULL;
+
+- return hv_get_ring_buffer(rbi) + rbi->priv_read_index;
++ desc = hv_get_ring_buffer(rbi) + rbi->priv_read_index;
++ if (desc)
++ prefetch((char *)desc + (desc->len8 << 3));
++
++ return desc;
+ }
+ EXPORT_SYMBOL_GPL(hv_pkt_iter_first);
+
diff --git a/patches.suse/msft-hv-1384-x86-hyper-v-include-hyperv-only-when-CONFIG_HYPERV-i.patch b/patches.suse/msft-hv-1384-x86-hyper-v-include-hyperv-only-when-CONFIG_HYPERV-i.patch
new file mode 100644
index 0000000000..86f2c0349d
--- /dev/null
+++ b/patches.suse/msft-hv-1384-x86-hyper-v-include-hyperv-only-when-CONFIG_HYPERV-i.patch
@@ -0,0 +1,50 @@
+From: Vitaly Kuznetsov <vkuznets@redhat.com>
+Date: Sun, 25 Jun 2017 10:06:40 -0700
+Patch-mainline: v4.14-rc1
+Subject: x86/hyper-v: include hyperv/ only when CONFIG_HYPERV is set
+Git-commit: 2e252fbf777d3b1250b63a5bf45e2ac1932687d3
+References: fate#323887
+
+Code is arch/x86/hyperv/ is only needed when CONFIG_HYPERV is set, the
+'basic' support and detection lives in arch/x86/kernel/cpu/mshyperv.c
+which is included when CONFIG_HYPERVISOR_GUEST is set.
+
+Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
+Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Acked-by: Olaf Hering <ohering@suse.de>
+---
+ arch/x86/Kbuild | 2 +-
+ arch/x86/include/asm/mshyperv.h | 7 ++++++-
+ 2 files changed, 7 insertions(+), 2 deletions(-)
+
+diff --git a/arch/x86/Kbuild b/arch/x86/Kbuild
+--- a/arch/x86/Kbuild
++++ b/arch/x86/Kbuild
+@@ -8,7 +8,7 @@ obj-$(CONFIG_KVM) += kvm/
+ obj-$(CONFIG_XEN) += xen/
+
+ # Hyper-V paravirtualization support
+-obj-$(CONFIG_HYPERVISOR_GUEST) += hyperv/
++obj-$(subst m,y,$(CONFIG_HYPERV)) += hyperv/
+
+ # lguest paravirtualization support
+ obj-$(CONFIG_LGUEST_GUEST) += lguest/
+diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h
+--- a/arch/x86/include/asm/mshyperv.h
++++ b/arch/x86/include/asm/mshyperv.h
+@@ -173,7 +173,12 @@ void hyperv_init(void);
+ void hyperv_report_panic(struct pt_regs *regs);
+ bool hv_is_hypercall_page_setup(void);
+ void hyperv_cleanup(void);
+-#endif
++#else /* CONFIG_HYPERV */
++static inline void hyperv_init(void) {}
++static inline bool hv_is_hypercall_page_setup(void) { return false; }
++static inline hyperv_cleanup(void) {}
++#endif /* CONFIG_HYPERV */
++
+ #ifdef CONFIG_HYPERV_TSCPAGE
+ struct ms_hyperv_tsc_page *hv_get_tsc_page(void);
+ static inline u64 hv_read_tsc_page(const struct ms_hyperv_tsc_page *tsc_pg)
diff --git a/patches.suse/msft-hv-1385-x86-hyper-v-stash-the-max-number-of-virtual-logical-.patch b/patches.suse/msft-hv-1385-x86-hyper-v-stash-the-max-number-of-virtual-logical-.patch
new file mode 100644
index 0000000000..c0f8dc685b
--- /dev/null
+++ b/patches.suse/msft-hv-1385-x86-hyper-v-stash-the-max-number-of-virtual-logical-.patch
@@ -0,0 +1,71 @@
+From: Vitaly Kuznetsov <vkuznets@redhat.com>
+Date: Sun, 25 Jun 2017 10:06:41 -0700
+Patch-mainline: v4.14-rc1
+Subject: x86/hyper-v: stash the max number of virtual/logical processor
+Git-commit: dd018597a074bcd1e5307d3b8e7863e05287bddf
+References: fate#323887
+
+Max virtual processor will be needed for 'extended' hypercalls supporting
+more than 64 vCPUs. While on it, unify on 'Hyper-V' in mshyperv.c as we
+currently have a mix, report acquired misc features as well.
+
+Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
+Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Acked-by: Olaf Hering <ohering@suse.de>
+---
+ arch/x86/include/asm/mshyperv.h | 2 ++
+ arch/x86/kernel/cpu/mshyperv.c | 12 +++++++++---
+ 2 files changed, 11 insertions(+), 3 deletions(-)
+
+diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h
+--- a/arch/x86/include/asm/mshyperv.h
++++ b/arch/x86/include/asm/mshyperv.h
+@@ -28,6 +28,8 @@ struct ms_hyperv_info {
+ u32 features;
+ u32 misc_features;
+ u32 hints;
++ u32 max_vp_index;
++ u32 max_lp_index;
+ };
+
+ extern struct ms_hyperv_info ms_hyperv;
+diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c
+--- a/arch/x86/kernel/cpu/mshyperv.c
++++ b/arch/x86/kernel/cpu/mshyperv.c
+@@ -184,9 +184,15 @@ static void __init ms_hyperv_init_platform(void)
+ ms_hyperv.misc_features = cpuid_edx(HYPERV_CPUID_FEATURES);
+ ms_hyperv.hints = cpuid_eax(HYPERV_CPUID_ENLIGHTMENT_INFO);
+
+- pr_info("HyperV: features 0x%x, hints 0x%x\n",
++ pr_info("Hyper-V: features 0x%x, hints 0x%x\n",
+ ms_hyperv.features, ms_hyperv.hints);
+
++ ms_hyperv.max_vp_index = cpuid_eax(HVCPUID_IMPLEMENTATION_LIMITS);
++ ms_hyperv.max_lp_index = cpuid_ebx(HVCPUID_IMPLEMENTATION_LIMITS);
++
++ pr_debug("Hyper-V: max %u virtual processors, %u logical processors\n",
++ ms_hyperv.max_vp_index, ms_hyperv.max_lp_index);
++
+ /*
+ * Extract host information.
+ */
+@@ -219,7 +225,7 @@ static void __init ms_hyperv_init_platform(void)
+ rdmsrl(HV_X64_MSR_APIC_FREQUENCY, hv_lapic_frequency);
+ hv_lapic_frequency = div_u64(hv_lapic_frequency, HZ);
+ lapic_timer_frequency = hv_lapic_frequency;
+- pr_info("HyperV: LAPIC Timer Frequency: %#x\n",
++ pr_info("Hyper-V: LAPIC Timer Frequency: %#x\n",
+ lapic_timer_frequency);
+ }
+
+@@ -253,7 +259,7 @@ static void __init ms_hyperv_init_platform(void)
+ }
+
+ const __refconst struct hypervisor_x86 x86_hyper_ms_hyperv = {
+- .name = "Microsoft HyperV",
++ .name = "Microsoft Hyper-V",
+ .detect = ms_hyperv_platform,
+ .init_platform = ms_hyperv_init_platform,
+ };
diff --git a/patches.suse/msft-hv-1394-Revert-x86-hyper-v-include-hyperv-only-when-CONFIG_H.patch b/patches.suse/msft-hv-1394-Revert-x86-hyper-v-include-hyperv-only-when-CONFIG_H.patch
new file mode 100644
index 0000000000..a5f5824b7a
--- /dev/null
+++ b/patches.suse/msft-hv-1394-Revert-x86-hyper-v-include-hyperv-only-when-CONFIG_H.patch
@@ -0,0 +1,54 @@
+From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Date: Thu, 20 Jul 2017 11:12:33 +0200
+Patch-mainline: v4.14-rc1
+Subject: Revert "x86/hyper-v: include hyperv/ only when CONFIG_HYPERV is set"
+Git-commit: 91c17449fe04adfb12ff9523f62e9cd0d658a88d
+References: fate#323887
+
+This reverts commit 2e252fbf777d3b1250b63a5bf45e2ac1932687d3 as it is
+obviously not correct.
+
+And it should have gone in through the x86 tree :(
+
+Reported-by: Colin King <colin.king@canonical.com>
+Reported-by: Ingo Molnar <mingo@kernel.org>
+Reported-by: Stephen Rothwell <sfr@canb.auug.org.au>
+Cc: Vitaly Kuznetsov <vkuznets@redhat.com>
+Cc: Andy Shevchenko <andy.shevchenko@gmail.com>
+Cc: K. Y. Srinivasan <kys@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Acked-by: Olaf Hering <ohering@suse.de>
+---
+ arch/x86/Kbuild | 2 +-
+ arch/x86/include/asm/mshyperv.h | 7 +------
+ 2 files changed, 2 insertions(+), 7 deletions(-)
+
+diff --git a/arch/x86/Kbuild b/arch/x86/Kbuild
+--- a/arch/x86/Kbuild
++++ b/arch/x86/Kbuild
+@@ -8,7 +8,7 @@ obj-$(CONFIG_KVM) += kvm/
+ obj-$(CONFIG_XEN) += xen/
+
+ # Hyper-V paravirtualization support
+-obj-$(subst m,y,$(CONFIG_HYPERV)) += hyperv/
++obj-$(CONFIG_HYPERVISOR_GUEST) += hyperv/
+
+ # lguest paravirtualization support
+ obj-$(CONFIG_LGUEST_GUEST) += lguest/
+diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h
+--- a/arch/x86/include/asm/mshyperv.h
++++ b/arch/x86/include/asm/mshyperv.h
+@@ -175,12 +175,7 @@ void hyperv_init(void);
+ void hyperv_report_panic(struct pt_regs *regs);
+ bool hv_is_hypercall_page_setup(void);
+ void hyperv_cleanup(void);
+-#else /* CONFIG_HYPERV */
+-static inline void hyperv_init(void) {}
+-static inline bool hv_is_hypercall_page_setup(void) { return false; }
+-static inline hyperv_cleanup(void) {}
+-#endif /* CONFIG_HYPERV */
+-
++#endif
+ #ifdef CONFIG_HYPERV_TSCPAGE
+ struct ms_hyperv_tsc_page *hv_get_tsc_page(void);
+ static inline u64 hv_read_tsc_page(const struct ms_hyperv_tsc_page *tsc_pg)
diff --git a/patches.suse/msft-hv-1410-netvsc-Initialize-64-bit-stats-seqcount.patch b/patches.suse/msft-hv-1410-netvsc-Initialize-64-bit-stats-seqcount.patch
new file mode 100644
index 0000000000..b3aee35b0f
--- /dev/null
+++ b/patches.suse/msft-hv-1410-netvsc-Initialize-64-bit-stats-seqcount.patch
@@ -0,0 +1,35 @@
+From: Florian Fainelli <f.fainelli@gmail.com>
+Date: Tue, 1 Aug 2017 12:11:12 -0700
+Patch-mainline: v4.13-rc5
+Subject: netvsc: Initialize 64-bit stats seqcount
+Git-commit: 4a0dee1ffe0e8f4101e704a325e97f8997b0abcc
+References: fate#323887
+
+On 32-bit hosts and with CONFIG_DEBUG_LOCK_ALLOC we should be seeing a
+lockdep splat indicating this seqcount is not correctly initialized, fix
+that. In commit 6c80f3fc2398 ("netvsc: report per-channel stats in
+ethtool statistics") netdev_alloc_pcpu_stats() was removed in favor of
+open-coding the 64-bits statistics, except that u64_stats_init() was
+missed.
+
+Fixes: 6c80f3fc2398 ("netvsc: report per-channel stats in ethtool statistics")
+Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
+Signed-off-by: Stephen Hemminger <sthemmin@microsoft.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Acked-by: Olaf Hering <ohering@suse.de>
+---
+ drivers/net/hyperv/netvsc.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c
+--- a/drivers/net/hyperv/netvsc.c
++++ b/drivers/net/hyperv/netvsc.c
+@@ -1302,6 +1302,8 @@ int netvsc_device_add(struct hv_device *device,
+
+ nvchan->channel = device->channel;
+ nvchan->net_device = net_device;
++ u64_stats_init(&nvchan->tx_stats.syncp);
++ u64_stats_init(&nvchan->rx_stats.syncp);
+ }
+
+ /* Enable NAPI handler before init callbacks */
diff --git a/patches.suse/msft-hv-1413-netvsc-remove-bonding-setup-script.patch b/patches.suse/msft-hv-1413-netvsc-remove-bonding-setup-script.patch
new file mode 100644
index 0000000000..43b0b1d0ce
--- /dev/null
+++ b/patches.suse/msft-hv-1413-netvsc-remove-bonding-setup-script.patch
@@ -0,0 +1,278 @@
+From: stephen hemminger <stephen@networkplumber.org>
+Date: Tue, 1 Aug 2017 19:58:55 -0700
+Patch-mainline: v4.14-rc1
+Subject: netvsc: remove bonding setup script
+Git-commit: 12aa7469d101e139b3728e540884bc7d72dca70a
+References: fate#323887
+
+No longer needed, now all managed by transparent VF logic.
+
+Signed-off-by: Stephen Hemminger <sthemmin@microsoft.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Acked-by: Olaf Hering <ohering@suse.de>
+---
+ tools/hv/bondvf.sh | 255 -----------------------------------------------------
+ 1 file changed, 255 deletions(-)
+ delete mode 100755 tools/hv/bondvf.sh
+
+diff --git a/tools/hv/bondvf.sh b/tools/hv/bondvf.sh
+deleted file mode 100755
+index 80f102860cf8..000000000000
+--- a/tools/hv/bondvf.sh
++++ /dev/null
+@@ -1,255 +0,0 @@
+-#!/bin/bash
+-
+-# This example script creates bonding network devices based on synthetic NIC
+-# (the virtual network adapter usually provided by Hyper-V) and the matching
+-# VF NIC (SRIOV virtual function). So the synthetic NIC and VF NIC can
+-# function as one network device, and fail over to the synthetic NIC if VF is
+-# down.
+-#
+-# Usage:
+-# - After configured vSwitch and vNIC with SRIOV, start Linux virtual
+-# machine (VM)
+-# - Run this scripts on the VM. It will create configuration files in
+-# distro specific directory.
+-# - Reboot the VM, so that the bonding config are enabled.
+-#
+-# The config files are DHCP by default. You may edit them if you need to change
+-# to Static IP or change other settings.
+-#
+-
+-sysdir=/sys/class/net
+-netvsc_cls={f8615163-df3e-46c5-913f-f2d2f965ed0e}
+-bondcnt=0
+-
+-# Detect Distro
+-if [ -f /etc/redhat-release ];
+-then
+- cfgdir=/etc/sysconfig/network-scripts
+- distro=redhat
+-elif grep -q 'Ubuntu' /etc/issue
+-then
+- cfgdir=/etc/network
+- distro=ubuntu
+-elif grep -q 'SUSE' /etc/issue
+-then
+- cfgdir=/etc/sysconfig/network
+- distro=suse
+-else
+- echo "Unsupported Distro"
+- exit 1
+-fi
+-
+-echo Detected Distro: $distro, or compatible
+-
+-# Get a list of ethernet names
+-list_eth=(`cd $sysdir && ls -d */ | cut -d/ -f1 | grep -v bond`)
+-eth_cnt=${#list_eth[@]}
+-
+-echo List of net devices:
+-
+-# Get the MAC addresses
+-for (( i=0; i < $eth_cnt; i++ ))
+-do
+- list_mac[$i]=`cat $sysdir/${list_eth[$i]}/address`
+- echo ${list_eth[$i]}, ${list_mac[$i]}
+-done
+-
+-# Find NIC with matching MAC
+-for (( i=0; i < $eth_cnt-1; i++ ))
+-do
+- for (( j=i+1; j < $eth_cnt; j++ ))
+- do
+- if [ "${list_mac[$i]}" = "${list_mac[$j]}" ]
+- then
+- list_match[$i]=${list_eth[$j]}
+- break
+- fi
+- done
+-done
+-
+-function create_eth_cfg_redhat {
+- local fn=$cfgdir/ifcfg-$1
+-
+- rm -f $fn
+- echo DEVICE=$1 >>$fn
+- echo TYPE=Ethernet >>$fn
+- echo BOOTPROTO=none >>$fn
+- echo UUID=`uuidgen` >>$fn
+- echo ONBOOT=yes >>$fn
+- echo PEERDNS=yes >>$fn
+- echo IPV6INIT=yes >>$fn
+- echo MASTER=$2 >>$fn
+- echo SLAVE=yes >>$fn
+-}
+-
+-function create_eth_cfg_pri_redhat {
+- create_eth_cfg_redhat $1 $2
+-}
+-
+-function create_bond_cfg_redhat {
+- local fn=$cfgdir/ifcfg-$1
+-
+- rm -f $fn
+- echo DEVICE=$1 >>$fn
+- echo TYPE=Bond >>$fn
+- echo BOOTPROTO=dhcp >>$fn
+- echo UUID=`uuidgen` >>$fn
+- echo ONBOOT=yes >>$fn
+- echo PEERDNS=yes >>$fn
+- echo IPV6INIT=yes >>$fn
+- echo BONDING_MASTER=yes >>$fn
+- echo BONDING_OPTS=\"mode=active-backup miimon=100 primary=$2\" >>$fn
+-}
+-
+-function del_eth_cfg_ubuntu {
+- local mainfn=$cfgdir/interfaces
+- local fnlist=( $mainfn )
+-
+- local dirlist=(`awk '/^[ \t]*source/{print $2}' $mainfn`)
+-
+- local i
+- for i in "${dirlist[@]}"
+- do
+- fnlist+=(`ls $i 2>/dev/null`)
+- done
+-
+- local tmpfl=$(mktemp)
+-
+- local nic_start='^[ \t]*(auto|iface|mapping|allow-.*)[ \t]+'$1
+- local nic_end='^[ \t]*(auto|iface|mapping|allow-.*|source)'
+-
+- local fn
+- for fn in "${fnlist[@]}"
+- do
+- awk "/$nic_end/{x=0} x{next} /$nic_start/{x=1;next} 1" \
+- $fn >$tmpfl
+-
+- cp $tmpfl $fn
+- done
+-
+- rm $tmpfl
+-}
+-
+-function create_eth_cfg_ubuntu {
+- local fn=$cfgdir/interfaces
+-
+- del_eth_cfg_ubuntu $1
+- echo $'\n'auto $1 >>$fn
+- echo iface $1 inet manual >>$fn
+- echo bond-master $2 >>$fn
+-}
+-
+-function create_eth_cfg_pri_ubuntu {
+- local fn=$cfgdir/interfaces
+-
+- del_eth_cfg_ubuntu $1
+- echo $'\n'allow-hotplug $1 >>$fn
+- echo iface $1 inet manual >>$fn
+- echo bond-master $2 >>$fn
+- echo bond-primary $1 >>$fn
+-}
+-
+-function create_bond_cfg_ubuntu {
+- local fn=$cfgdir/interfaces
+-
+- del_eth_cfg_ubuntu $1
+-
+- echo $'\n'auto $1 >>$fn
+- echo iface $1 inet dhcp >>$fn
+- echo bond-mode active-backup >>$fn
+- echo bond-miimon 100 >>$fn
+- echo bond-slaves none >>$fn
+-}
+-
+-function create_eth_cfg_suse {
+- local fn=$cfgdir/ifcfg-$1
+-
+- rm -f $fn
+- echo BOOTPROTO=none >>$fn
+- echo STARTMODE=auto >>$fn
+-}
+-
+-function create_eth_cfg_pri_suse {
+- local fn=$cfgdir/ifcfg-$1
+-
+- rm -f $fn
+- echo BOOTPROTO=none >>$fn
+- echo STARTMODE=hotplug >>$fn
+-}
+-
+-function create_bond_cfg_suse {
+- local fn=$cfgdir/ifcfg-$1
+-
+- rm -f $fn
+- echo BOOTPROTO=dhcp >>$fn
+- echo STARTMODE=auto >>$fn
+- echo BONDING_MASTER=yes >>$fn
+- echo BONDING_SLAVE_0=$2 >>$fn
+- echo BONDING_SLAVE_1=$3 >>$fn
+- echo BONDING_MODULE_OPTS=\'mode=active-backup miimon=100 primary=$2\' >>$fn
+-}
+-
+-function create_bond {
+- local bondname=bond$bondcnt
+- local primary
+- local secondary
+-
+- local class_id1=`cat $sysdir/$1/device/class_id 2>/dev/null`
+- local class_id2=`cat $sysdir/$2/device/class_id 2>/dev/null`
+-
+- if [ "$class_id1" = "$netvsc_cls" ]
+- then
+- primary=$2
+- secondary=$1
+- elif [ "$class_id2" = "$netvsc_cls" ]
+- then
+- primary=$1
+- secondary=$2
+- else
+- return 0
+- fi
+-
+- echo $'\nBond name:' $bondname
+-
+- if [ $distro == ubuntu ]
+- then
+- local mainfn=$cfgdir/interfaces
+- local s="^[ \t]*(auto|iface|mapping|allow-.*)[ \t]+${bondname}"
+-
+- grep -E "$s" $mainfn
+- if [ $? -eq 0 ]
+- then
+- echo "WARNING: ${bondname} has been configured already"
+- return
+- fi
+- elif [ $distro == redhat ] || [ $distro == suse ]
+- then
+- local fn=$cfgdir/ifcfg-$bondname
+- if [ -f $fn ]
+- then
+- echo "WARNING: ${bondname} has been configured already"
+- return
+- fi
+- else
+- echo "Unsupported Distro: ${distro}"
+- return
+- fi
+-
+- echo configuring $primary
+- create_eth_cfg_pri_$distro $primary $bondname
+-
+- echo configuring $secondary
+- create_eth_cfg_$distro $secondary $bondname
+-
+- echo creating: $bondname with primary slave: $primary
+- create_bond_cfg_$distro $bondname $primary $secondary
+-}
+-
+-for (( i=0; i < $eth_cnt-1; i++ ))
+-do
+- if [ -n "${list_match[$i]}" ]
+- then
+- create_bond ${list_eth[$i]} ${list_match[$i]}
+- let bondcnt=bondcnt+1
+- fi
+-done
diff --git a/patches.suse/msft-hv-1414-PCI-hv-Do-not-sleep-in-compose_msi_msg.patch b/patches.suse/msft-hv-1414-PCI-hv-Do-not-sleep-in-compose_msi_msg.patch
new file mode 100644
index 0000000000..345267c8ec
--- /dev/null
+++ b/patches.suse/msft-hv-1414-PCI-hv-Do-not-sleep-in-compose_msi_msg.patch
@@ -0,0 +1,57 @@
+From: Stephen Hemminger <stephen@networkplumber.org>
+Date: Mon, 31 Jul 2017 16:48:29 -0700
+Patch-mainline: v4.14-rc1
+Subject: PCI: hv: Do not sleep in compose_msi_msg()
+Git-commit: 80bfeeb9dd6b54ac108c884c792f0fc7d4912bee
+References: fate#323887
+
+The setup of MSI with Hyper-V host was sleeping with locks held. This
+error is reported when doing SR-IOV hotplug with kernel built with lockdep:
+
+ BUG: sleeping function called from invalid context at kernel/sched/completion.c:93
+ in_atomic(): 1, irqs_disabled(): 1, pid: 1405, name: ip
+ 3 locks held by ip/1405:
+ #0: (rtnl_mutex){+.+.+.}, at: [<ffffffff976b10bb>] rtnetlink_rcv+0x1b/0x40
+ #1: (&desc->request_mutex){+.+...}, at: [<ffffffff970ddd33>] __setup_irq+0xb3/0x720
+ #2: (&irq_desc_lock_class){-.-...}, at: [<ffffffff970ddd65>] __setup_irq+0xe5/0x720
+ irq event stamp: 3476
+ hardirqs last enabled at (3475): [<ffffffff971b3005>] get_page_from_freelist+0x225/0xc90
+ hardirqs last disabled at (3476): [<ffffffff978024e7>] _raw_spin_lock_irqsave+0x27/0x90
+ softirqs last enabled at (2446): [<ffffffffc05ef0b0>] ixgbevf_configure+0x380/0x7c0 [ixgbevf]
+ softirqs last disabled at (2444): [<ffffffffc05ef08d>] ixgbevf_configure+0x35d/0x7c0 [ixgbevf]
+
+The workaround is to poll for host response instead of blocking on
+completion.
+
+Signed-off-by: Stephen Hemminger <sthemmin@microsoft.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Acked-by: Olaf Hering <ohering@suse.de>
+---
+ drivers/pci/host/pci-hyperv.c | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/pci/host/pci-hyperv.c b/drivers/pci/host/pci-hyperv.c
+--- a/drivers/pci/host/pci-hyperv.c
++++ b/drivers/pci/host/pci-hyperv.c
+@@ -50,6 +50,7 @@
+ #include <linux/kernel.h>
+ #include <linux/module.h>
+ #include <linux/pci.h>
++#include <linux/delay.h>
+ #include <linux/semaphore.h>
+ #include <linux/irqdomain.h>
+ #include <asm/irqdomain.h>
+@@ -1159,7 +1160,12 @@ static void hv_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
+ goto free_int_desc;
+ }
+
+- wait_for_completion(&comp.comp_pkt.host_event);
++ /*
++ * Since this function is called with IRQ locks held, can't
++ * do normal wait for completion; instead poll.
++ */
++ while (!try_wait_for_completion(&comp.comp_pkt.host_event))
++ udelay(100);
+
+ if (comp.comp_pkt.completion_status < 0) {
+ dev_err(&hbus->hdev->device,
diff --git a/patches.suse/msft-hv-1415-netvsc-fix-race-on-sub-channel-creation.patch b/patches.suse/msft-hv-1415-netvsc-fix-race-on-sub-channel-creation.patch
new file mode 100644
index 0000000000..ed74253cfa
--- /dev/null
+++ b/patches.suse/msft-hv-1415-netvsc-fix-race-on-sub-channel-creation.patch
@@ -0,0 +1,121 @@
+From: stephen hemminger <stephen@networkplumber.org>
+Date: Thu, 3 Aug 2017 17:13:54 -0700
+Patch-mainline: v4.13-rc5
+Subject: netvsc: fix race on sub channel creation
+Git-commit: 732e49850c5e15231e11a0a464748bcbade5e3c2
+References: fate#323887
+
+The existing sub channel code did not wait for all the sub-channels
+to completely initialize. This could lead to race causing crash
+in napi_netif_del() from bad list. The existing code would send
+an init message, then wait only for the initial response that
+the init message was received. It thought it was waiting for
+sub channels but really the init response did the wakeup.
+
+The new code keeps track of the number of open channels and
+waits until that many are open.
+
+Other issues here were:
+ * host might return less sub-channels than was requested.
+ * the new init status is not valid until after init was completed.
+
+Fixes: b3e6b82a0099 ("hv_netvsc: Wait for sub-channels to be processed during probe")
+Signed-off-by: Stephen Hemminger <sthemmin@microsoft.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Acked-by: Olaf Hering <ohering@suse.de>
+---
+ drivers/net/hyperv/hyperv_net.h | 3 ++-
+ drivers/net/hyperv/netvsc.c | 1 +
+ drivers/net/hyperv/rndis_filter.c | 14 ++++++++------
+ 3 files changed, 11 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h
+--- a/drivers/net/hyperv/hyperv_net.h
++++ b/drivers/net/hyperv/hyperv_net.h
+@@ -765,7 +765,8 @@ struct netvsc_device {
+ u32 max_chn;
+ u32 num_chn;
+
+- refcount_t sc_offered;
++ atomic_t open_chn;
++ wait_queue_head_t subchan_open;
+
+ struct rndis_device *extension;
+
+diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c
+--- a/drivers/net/hyperv/netvsc.c
++++ b/drivers/net/hyperv/netvsc.c
+@@ -78,6 +78,7 @@ static struct netvsc_device *alloc_net_device(void)
+ net_device->max_pkt = RNDIS_MAX_PKT_DEFAULT;
+ net_device->pkt_align = RNDIS_PKT_ALIGN_DEFAULT;
+ init_completion(&net_device->channel_init_wait);
++ init_waitqueue_head(&net_device->subchan_open);
+
+ return net_device;
+ }
+diff --git a/drivers/net/hyperv/rndis_filter.c b/drivers/net/hyperv/rndis_filter.c
+--- a/drivers/net/hyperv/rndis_filter.c
++++ b/drivers/net/hyperv/rndis_filter.c
+@@ -1048,8 +1048,8 @@ static void netvsc_sc_open(struct vmbus_channel *new_sc)
+ else
+ netif_napi_del(&nvchan->napi);
+
+- if (refcount_dec_and_test(&nvscdev->sc_offered))
+- complete(&nvscdev->channel_init_wait);
++ atomic_inc(&nvscdev->open_chn);
++ wake_up(&nvscdev->subchan_open);
+ }
+
+ struct netvsc_device *rndis_filter_device_add(struct hv_device *dev,
+@@ -1090,8 +1090,6 @@ int rndis_filter_device_add(struct hv_device *dev,
+ net_device->max_chn = 1;
+ net_device->num_chn = 1;
+
+- refcount_set(&net_device->sc_offered, 0);
+-
+ net_device->extension = rndis_device;
+ rndis_device->ndev = net;
+
+@@ -1221,20 +1219,20 @@ int rndis_filter_device_add(struct hv_device *dev,
+ rndis_device->ind_table[i] = ethtool_rxfh_indir_default(i,
+ net_device->num_chn);
+
++ atomic_set(&net_device->open_chn, 1);
+ num_rss_qs = net_device->num_chn - 1;
+ if (num_rss_qs == 0)
+ return net_device;
+
+ for (i = 1; i < net_device->num_chn; i++) {
+ ret = netvsc_alloc_recv_comp_ring(net_device, i);
+ if (ret) {
+ while (--i != 0)
+ vfree(net_device->chan_table[i].mrc.slots);
+ goto out;
+ }
+ }
+
+- refcount_set(&net_device->sc_offered, num_rss_qs);
+ vmbus_set_sc_create_callback(dev->channel, netvsc_sc_open);
+
+ init_packet = &net_device->channel_init_pkt;
+@@ -1242,15 +1240,19 @@ int rndis_filter_device_add(struct hv_device *dev,
+ if (ret)
+ goto out;
+
++ wait_for_completion(&net_device->channel_init_wait);
+ if (init_packet->msg.v5_msg.subchn_comp.status != NVSP_STAT_SUCCESS) {
+ ret = -ENODEV;
+ goto out;
+ }
+- wait_for_completion(&net_device->channel_init_wait);
+
+ net_device->num_chn = 1 +
+ init_packet->msg.v5_msg.subchn_comp.num_subchannels;
+
++ /* wait for all sub channels to open */
++ wait_event(net_device->subchan_open,
++ atomic_read(&net_device->open_chn) == net_device->num_chn);
++
+ /* ignore failues from setting rss parameters, still have channels */
+ rndis_filter_set_rss_param(rndis_device, netvsc_hash_key,
+ net_device->num_chn);
diff --git a/patches.suse/msft-hv-1418-x86-hyper-v-Include-hyperv-only-when-CONFIG_HYPERV-i.patch b/patches.suse/msft-hv-1418-x86-hyper-v-Include-hyperv-only-when-CONFIG_HYPERV-i.patch
new file mode 100644
index 0000000000..6117198a7c
--- /dev/null
+++ b/patches.suse/msft-hv-1418-x86-hyper-v-Include-hyperv-only-when-CONFIG_HYPERV-i.patch
@@ -0,0 +1,61 @@
+From: Vitaly Kuznetsov <vkuznets@redhat.com>
+Date: Wed, 2 Aug 2017 18:09:13 +0200
+Patch-mainline: v4.14-rc1
+Subject: x86/hyper-v: Include hyperv/ only when CONFIG_HYPERV is set
+Git-commit: 79cadff2d92bb8b1448f6dba6861d15adc3dc4cb
+References: fate#323887
+
+Code is arch/x86/hyperv/ is only needed when CONFIG_HYPERV is set, the
+'basic' support and detection lives in arch/x86/kernel/cpu/mshyperv.c
+which is included when CONFIG_HYPERVISOR_GUEST is set.
+
+Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
+Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Reviewed-by: Stephen Hemminger <sthemmin@microsoft.com>
+Cc: Andy Lutomirski <luto@kernel.org>
+Cc: Haiyang Zhang <haiyangz@microsoft.com>
+Cc: Jork Loeser <Jork.Loeser@microsoft.com>
+Cc: K. Y. Srinivasan <kys@microsoft.com>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Simon Xiao <sixiao@microsoft.com>
+Cc: Steven Rostedt <rostedt@goodmis.org>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Cc: devel@linuxdriverproject.org
+Link: http://lkml.kernel.org/r/20170802160921.21791-2-vkuznets@redhat.com
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Acked-by: Olaf Hering <ohering@suse.de>
+---
+ arch/x86/Kbuild | 2 +-
+ arch/x86/include/asm/mshyperv.h | 7 ++++++-
+ 2 files changed, 7 insertions(+), 2 deletions(-)
+
+diff --git a/arch/x86/Kbuild b/arch/x86/Kbuild
+--- a/arch/x86/Kbuild
++++ b/arch/x86/Kbuild
+@@ -8,7 +8,7 @@ obj-$(CONFIG_KVM) += kvm/
+ obj-$(CONFIG_XEN) += xen/
+
+ # Hyper-V paravirtualization support
+-obj-$(CONFIG_HYPERVISOR_GUEST) += hyperv/
++obj-$(subst m,y,$(CONFIG_HYPERV)) += hyperv/
+
+ # lguest paravirtualization support
+ obj-$(CONFIG_LGUEST_GUEST) += lguest/
+diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h
+--- a/arch/x86/include/asm/mshyperv.h
++++ b/arch/x86/include/asm/mshyperv.h
+@@ -173,7 +173,12 @@ void hyperv_init(void);
+ void hyperv_report_panic(struct pt_regs *regs);
+ bool hv_is_hypercall_page_setup(void);
+ void hyperv_cleanup(void);
+-#endif
++#else /* CONFIG_HYPERV */
++static inline void hyperv_init(void) {}
++static inline bool hv_is_hypercall_page_setup(void) { return false; }
++static inline void hyperv_cleanup(void) {}
++#endif /* CONFIG_HYPERV */
++
+ #ifdef CONFIG_HYPERV_TSCPAGE
+ struct ms_hyperv_tsc_page *hv_get_tsc_page(void);
+ static inline u64 hv_read_tsc_page(const struct ms_hyperv_tsc_page *tsc_pg)
diff --git a/patches.suse/msft-hv-1419-x86-hyper-v-Make-hv_do_hypercall-inline.patch b/patches.suse/msft-hv-1419-x86-hyper-v-Make-hv_do_hypercall-inline.patch
new file mode 100644
index 0000000000..2b995db293
--- /dev/null
+++ b/patches.suse/msft-hv-1419-x86-hyper-v-Make-hv_do_hypercall-inline.patch
@@ -0,0 +1,202 @@
+From: Vitaly Kuznetsov <vkuznets@redhat.com>
+Date: Wed, 2 Aug 2017 18:09:14 +0200
+Patch-mainline: v4.14-rc1
+Subject: x86/hyper-v: Make hv_do_hypercall() inline
+Git-commit: fc53662f13b889a5a1c069e79ee1e3d4534df132
+References: fate#323887
+
+We have only three call sites for hv_do_hypercall() and we're going to
+change HVCALL_SIGNAL_EVENT to doing fast hypercall so we can inline this
+function for optimization.
+
+Hyper-V top level functional specification states that r9-r11 registers
+and flags may be clobbered by the hypervisor during hypercall and with
+inlining this is somewhat important, add the clobbers.
+
+Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
+Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Reviewed-by: Stephen Hemminger <sthemmin@microsoft.com>
+Cc: Andy Lutomirski <luto@kernel.org>
+Cc: Haiyang Zhang <haiyangz@microsoft.com>
+Cc: Jork Loeser <Jork.Loeser@microsoft.com>
+Cc: K. Y. Srinivasan <kys@microsoft.com>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Simon Xiao <sixiao@microsoft.com>
+Cc: Steven Rostedt <rostedt@goodmis.org>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Cc: devel@linuxdriverproject.org
+Link: http://lkml.kernel.org/r/20170802160921.21791-3-vkuznets@redhat.com
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Acked-by: Olaf Hering <ohering@suse.de>
+---
+ arch/x86/hyperv/hv_init.c | 54 ++++-------------------------------------
+ arch/x86/include/asm/mshyperv.h | 40 ++++++++++++++++++++++++++++++
+ drivers/hv/connection.c | 2 ++
+ include/linux/hyperv.h | 1 -
+ 4 files changed, 47 insertions(+), 50 deletions(-)
+
+diff --git a/arch/x86/hyperv/hv_init.c b/arch/x86/hyperv/hv_init.c
+--- a/arch/x86/hyperv/hv_init.c
++++ b/arch/x86/hyperv/hv_init.c
+@@ -75,7 +75,8 @@ static struct clocksource hyperv_cs_msr = {
+ .flags = CLOCK_SOURCE_IS_CONTINUOUS,
+ };
+
+-static void *hypercall_pg;
++void *hv_hypercall_pg;
++EXPORT_SYMBOL_GPL(hv_hypercall_pg);
+ struct clocksource *hyperv_cs;
+ EXPORT_SYMBOL_GPL(hyperv_cs);
+
+@@ -102,15 +103,15 @@ void hyperv_init(void)
+ guest_id = generate_guest_id(0, LINUX_VERSION_CODE, 0);
+ wrmsrl(HV_X64_MSR_GUEST_OS_ID, guest_id);
+
+- hypercall_pg = __vmalloc(PAGE_SIZE, GFP_KERNEL, PAGE_KERNEL_RX);
+- if (hypercall_pg == NULL) {
++ hv_hypercall_pg = __vmalloc(PAGE_SIZE, GFP_KERNEL, PAGE_KERNEL_RX);
++ if (hv_hypercall_pg == NULL) {
+ wrmsrl(HV_X64_MSR_GUEST_OS_ID, 0);
+ return;
+ }
+
+ rdmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64);
+ hypercall_msr.enable = 1;
+- hypercall_msr.guest_physical_address = vmalloc_to_pfn(hypercall_pg);
++ hypercall_msr.guest_physical_address = vmalloc_to_pfn(hv_hypercall_pg);
+ wrmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64);
+
+ /*
+@@ -170,51 +171,6 @@ void hyperv_cleanup(void)
+ }
+ EXPORT_SYMBOL_GPL(hyperv_cleanup);
+
+-/*
+- * hv_do_hypercall- Invoke the specified hypercall
+- */
+-u64 hv_do_hypercall(u64 control, void *input, void *output)
+-{
+- u64 input_address = (input) ? virt_to_phys(input) : 0;
+- u64 output_address = (output) ? virt_to_phys(output) : 0;
+-#ifdef CONFIG_X86_64
+- u64 hv_status = 0;
+-
+- if (!hypercall_pg)
+- return (u64)ULLONG_MAX;
+-
+- __asm__ __volatile__("mov %0, %%r8" : : "r" (output_address) : "r8");
+- __asm__ __volatile__("call *%3" : "=a" (hv_status) :
+- "c" (control), "d" (input_address),
+- "m" (hypercall_pg));
+-
+- return hv_status;
+-
+-#else
+-
+- u32 control_hi = control >> 32;
+- u32 control_lo = control & 0xFFFFFFFF;
+- u32 hv_status_hi = 1;
+- u32 hv_status_lo = 1;
+- u32 input_address_hi = input_address >> 32;
+- u32 input_address_lo = input_address & 0xFFFFFFFF;
+- u32 output_address_hi = output_address >> 32;
+- u32 output_address_lo = output_address & 0xFFFFFFFF;
+-
+- if (!hypercall_pg)
+- return (u64)ULLONG_MAX;
+-
+- __asm__ __volatile__ ("call *%8" : "=d"(hv_status_hi),
+- "=a"(hv_status_lo) : "d" (control_hi),
+- "a" (control_lo), "b" (input_address_hi),
+- "c" (input_address_lo), "D"(output_address_hi),
+- "S"(output_address_lo), "m" (hypercall_pg));
+-
+- return hv_status_lo | ((u64)hv_status_hi << 32);
+-#endif /* !x86_64 */
+-}
+-EXPORT_SYMBOL_GPL(hv_do_hypercall);
+-
+ void hyperv_report_panic(struct pt_regs *regs)
+ {
+ static bool panic_reported;
+diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h
+--- a/arch/x86/include/asm/mshyperv.h
++++ b/arch/x86/include/asm/mshyperv.h
+@@ -3,6 +3,7 @@
+
+ #include <linux/types.h>
+ #include <linux/atomic.h>
++#include <asm/io.h>
+ #include <asm/hyperv.h>
+
+ /*
+@@ -168,6 +169,45 @@ void hv_remove_crash_handler(void);
+
+ #if IS_ENABLED(CONFIG_HYPERV)
+ extern struct clocksource *hyperv_cs;
++extern void *hv_hypercall_pg;
++
++static inline u64 hv_do_hypercall(u64 control, void *input, void *output)
++{
++ u64 input_address = input ? virt_to_phys(input) : 0;
++ u64 output_address = output ? virt_to_phys(output) : 0;
++ u64 hv_status;
++ register void *__sp asm(_ASM_SP);
++
++#ifdef CONFIG_X86_64
++ if (!hv_hypercall_pg)
++ return U64_MAX;
++
++ __asm__ __volatile__("mov %4, %%r8\n"
++ "call *%5"
++ : "=a" (hv_status), "+r" (__sp),
++ "+c" (control), "+d" (input_address)
++ : "r" (output_address), "m" (hv_hypercall_pg)
++ : "cc", "memory", "r8", "r9", "r10", "r11");
++#else
++ u32 input_address_hi = upper_32_bits(input_address);
++ u32 input_address_lo = lower_32_bits(input_address);
++ u32 output_address_hi = upper_32_bits(output_address);
++ u32 output_address_lo = lower_32_bits(output_address);
++
++ if (!hv_hypercall_pg)
++ return U64_MAX;
++
++ __asm__ __volatile__("call *%7"
++ : "=A" (hv_status),
++ "+c" (input_address_lo), "+r" (__sp)
++ : "A" (control),
++ "b" (input_address_hi),
++ "D"(output_address_hi), "S"(output_address_lo),
++ "m" (hv_hypercall_pg)
++ : "cc", "memory");
++#endif /* !x86_64 */
++ return hv_status;
++}
+
+ void hyperv_init(void);
+ void hyperv_report_panic(struct pt_regs *regs);
+diff --git a/drivers/hv/connection.c b/drivers/hv/connection.c
+--- a/drivers/hv/connection.c
++++ b/drivers/hv/connection.c
+@@ -32,6 +32,8 @@
+ #include <linux/hyperv.h>
+ #include <linux/export.h>
+ #include <asm/hyperv.h>
++#include <asm/mshyperv.h>
++
+ #include "hyperv_vmbus.h"
+
+
+diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
+--- a/include/linux/hyperv.h
++++ b/include/linux/hyperv.h
+@@ -1187,7 +1187,6 @@ int vmbus_allocate_mmio(struct resource **new, struct hv_device *device_obj,
+ bool fb_overlap_ok);
+ void vmbus_free_mmio(resource_size_t start, resource_size_t size);
+ int vmbus_cpu_number_to_vp_number(int cpu_number);
+-u64 hv_do_hypercall(u64 control, void *input, void *output);
+
+ /*
+ * GUID definitions of various offer types - services offered to the guest.
diff --git a/patches.suse/msft-hv-1420-x86-hyper-v-Introduce-fast-hypercall-implementation.patch b/patches.suse/msft-hv-1420-x86-hyper-v-Introduce-fast-hypercall-implementation.patch
new file mode 100644
index 0000000000..7da18dd589
--- /dev/null
+++ b/patches.suse/msft-hv-1420-x86-hyper-v-Introduce-fast-hypercall-implementation.patch
@@ -0,0 +1,75 @@
+From: Vitaly Kuznetsov <vkuznets@redhat.com>
+Date: Wed, 2 Aug 2017 18:09:15 +0200
+Patch-mainline: v4.14-rc1
+Subject: x86/hyper-v: Introduce fast hypercall implementation
+Git-commit: 6a8edbd0c54ae266b12f4f63e406313481c9d4bc
+References: fate#323887
+
+Hyper-V supports 'fast' hypercalls when all parameters are passed through
+registers. Implement an inline version of a simpliest of these calls:
+hypercall with one 8-byte input and no output.
+
+Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
+Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Reviewed-by: Stephen Hemminger <sthemmin@microsoft.com>
+Cc: Andy Lutomirski <luto@kernel.org>
+Cc: Haiyang Zhang <haiyangz@microsoft.com>
+Cc: Jork Loeser <Jork.Loeser@microsoft.com>
+Cc: K. Y. Srinivasan <kys@microsoft.com>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Simon Xiao <sixiao@microsoft.com>
+Cc: Steven Rostedt <rostedt@goodmis.org>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Cc: devel@linuxdriverproject.org
+Link: http://lkml.kernel.org/r/20170802160921.21791-4-vkuznets@redhat.com
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Acked-by: Olaf Hering <ohering@suse.de>
+---
+ arch/x86/include/asm/mshyperv.h | 34 ++++++++++++++++++++++++++++++++++
+ 1 file changed, 34 insertions(+)
+
+diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h
+--- a/arch/x86/include/asm/mshyperv.h
++++ b/arch/x86/include/asm/mshyperv.h
+@@ -209,6 +209,40 @@ static inline u64 hv_do_hypercall(u64 control, void *input, void *output)
+ return hv_status;
+ }
+
++#define HV_HYPERCALL_FAST_BIT BIT(16)
++
++/* Fast hypercall with 8 bytes of input and no output */
++static inline u64 hv_do_fast_hypercall8(u16 code, u64 input1)
++{
++ u64 hv_status, control = (u64)code | HV_HYPERCALL_FAST_BIT;
++ register void *__sp asm(_ASM_SP);
++
++#ifdef CONFIG_X86_64
++ {
++ __asm__ __volatile__("call *%4"
++ : "=a" (hv_status), "+r" (__sp),
++ "+c" (control), "+d" (input1)
++ : "m" (hv_hypercall_pg)
++ : "cc", "r8", "r9", "r10", "r11");
++ }
++#else
++ {
++ u32 input1_hi = upper_32_bits(input1);
++ u32 input1_lo = lower_32_bits(input1);
++
++ __asm__ __volatile__ ("call *%5"
++ : "=A"(hv_status),
++ "+c"(input1_lo),
++ "+r"(__sp)
++ : "A" (control),
++ "b" (input1_hi),
++ "m" (hv_hypercall_pg)
++ : "cc", "edi", "esi");
++ }
++#endif
++ return hv_status;
++}
++
+ void hyperv_init(void);
+ void hyperv_report_panic(struct pt_regs *regs);
+ bool hv_is_hypercall_page_setup(void);
diff --git a/patches.suse/msft-hv-1421-hyper-v-Use-fast-hypercall-for-HVCALL_SIGNAL_EVENT.patch b/patches.suse/msft-hv-1421-hyper-v-Use-fast-hypercall-for-HVCALL_SIGNAL_EVENT.patch
new file mode 100644
index 0000000000..cb597eebf1
--- /dev/null
+++ b/patches.suse/msft-hv-1421-hyper-v-Use-fast-hypercall-for-HVCALL_SIGNAL_EVENT.patch
@@ -0,0 +1,103 @@
+From: Vitaly Kuznetsov <vkuznets@redhat.com>
+Date: Wed, 2 Aug 2017 18:09:16 +0200
+Patch-mainline: v4.14-rc1
+Subject: hyper-v: Use fast hypercall for HVCALL_SIGNAL_EVENT
+Git-commit: 057841713cfff62b4485cdd2b245f05b7ea3ba16
+References: fate#323887
+
+We need to pass only 8 bytes of input for HvSignalEvent which makes it a
+perfect fit for fast hypercall. hv_input_signal_event_buffer is not needed
+any more and hv_input_signal_event is converted to union for convenience.
+
+Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
+Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Reviewed-by: Stephen Hemminger <sthemmin@microsoft.com>
+Cc: Andy Lutomirski <luto@kernel.org>
+Cc: Haiyang Zhang <haiyangz@microsoft.com>
+Cc: Jork Loeser <Jork.Loeser@microsoft.com>
+Cc: K. Y. Srinivasan <kys@microsoft.com>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Simon Xiao <sixiao@microsoft.com>
+Cc: Steven Rostedt <rostedt@goodmis.org>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Cc: devel@linuxdriverproject.org
+Link: http://lkml.kernel.org/r/20170802160921.21791-5-vkuznets@redhat.com
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Acked-by: Olaf Hering <ohering@suse.de>
+---
+ drivers/hv/channel_mgmt.c | 13 ++-----------
+ drivers/hv/connection.c | 2 +-
+ include/linux/hyperv.h | 15 +--------------
+ 3 files changed, 4 insertions(+), 26 deletions(-)
+
+diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c
+--- a/drivers/hv/channel_mgmt.c
++++ b/drivers/hv/channel_mgmt.c
+@@ -805,21 +805,12 @@ static void vmbus_onoffer(struct vmbus_channel_message_header *hdr)
+ /*
+ * Setup state for signalling the host.
+ */
+- newchannel->sig_event = (struct hv_input_signal_event *)
+- (ALIGN((unsigned long)
+- &newchannel->sig_buf,
+- HV_HYPERCALL_PARAM_ALIGN));
+-
+- newchannel->sig_event->connectionid.asu32 = 0;
+- newchannel->sig_event->connectionid.u.id = VMBUS_EVENT_CONNECTION_ID;
+- newchannel->sig_event->flag_number = 0;
+- newchannel->sig_event->rsvdz = 0;
++ newchannel->sig_event = VMBUS_EVENT_CONNECTION_ID;
+
+ if (vmbus_proto_version != VERSION_WS2008) {
+ newchannel->is_dedicated_interrupt =
+ (offer->is_dedicated_interrupt != 0);
+- newchannel->sig_event->connectionid.u.id =
+- offer->connection_id;
++ newchannel->sig_event = offer->connection_id;
+ }
+
+ memcpy(&newchannel->offermsg, offer,
+diff --git a/drivers/hv/connection.c b/drivers/hv/connection.c
+--- a/drivers/hv/connection.c
++++ b/drivers/hv/connection.c
+@@ -408,6 +408,6 @@ void vmbus_set_event(struct vmbus_channel *channel)
+ if (!channel->is_dedicated_interrupt)
+ vmbus_send_interrupt(child_relid);
+
+- hv_do_hypercall(HVCALL_SIGNAL_EVENT, channel->sig_event, NULL);
++ hv_do_fast_hypercall8(HVCALL_SIGNAL_EVENT, channel->sig_event);
+ }
+ EXPORT_SYMBOL_GPL(vmbus_set_event);
+diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
+--- a/include/linux/hyperv.h
++++ b/include/linux/hyperv.h
+@@ -677,18 +677,6 @@ union hv_connection_id {
+ } u;
+ };
+
+-/* Definition of the hv_signal_event hypercall input structure. */
+-struct hv_input_signal_event {
+- union hv_connection_id connectionid;
+- u16 flag_number;
+- u16 rsvdz;
+-};
+-
+-struct hv_input_signal_event_buffer {
+- u64 align8;
+- struct hv_input_signal_event event;
+-};
+-
+ enum hv_numa_policy {
+ HV_BALANCED = 0,
+ HV_LOCALIZED,
+@@ -770,8 +758,7 @@ struct vmbus_channel {
+ } callback_mode;
+
+ bool is_dedicated_interrupt;
+- struct hv_input_signal_event_buffer sig_buf;
+- struct hv_input_signal_event *sig_event;
++ u64 sig_event;
+
+ /*
+ * Starting with win8, this field will be used to specify
diff --git a/patches.suse/msft-hv-1422-x86-hyper-v-Implement-rep-hypercalls.patch b/patches.suse/msft-hv-1422-x86-hyper-v-Implement-rep-hypercalls.patch
new file mode 100644
index 0000000000..90ba2f717d
--- /dev/null
+++ b/patches.suse/msft-hv-1422-x86-hyper-v-Implement-rep-hypercalls.patch
@@ -0,0 +1,99 @@
+From: Vitaly Kuznetsov <vkuznets@redhat.com>
+Date: Wed, 2 Aug 2017 18:09:17 +0200
+Patch-mainline: v4.14-rc1
+Subject: x86/hyper-v: Implement rep hypercalls
+Git-commit: 806c89273bab0c8af0202a6fb6279f36042cb2e6
+References: fate#323887
+
+Rep hypercalls are normal hypercalls which perform multiple actions at
+once. Hyper-V guarantees to return exectution to the caller in not more
+than 50us and the caller needs to use hypercall continuation. Touch NMI
+watchdog between hypercall invocations.
+
+This is going to be used for HvFlushVirtualAddressList hypercall for
+remote TLB flushing.
+
+Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
+Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Reviewed-by: Stephen Hemminger <sthemmin@microsoft.com>
+Cc: Andy Lutomirski <luto@kernel.org>
+Cc: Haiyang Zhang <haiyangz@microsoft.com>
+Cc: Jork Loeser <Jork.Loeser@microsoft.com>
+Cc: K. Y. Srinivasan <kys@microsoft.com>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Simon Xiao <sixiao@microsoft.com>
+Cc: Steven Rostedt <rostedt@goodmis.org>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Cc: devel@linuxdriverproject.org
+Link: http://lkml.kernel.org/r/20170802160921.21791-6-vkuznets@redhat.com
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Acked-by: Olaf Hering <ohering@suse.de>
+---
+ arch/x86/include/asm/mshyperv.h | 39 +++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 39 insertions(+)
+
+diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h
+--- a/arch/x86/include/asm/mshyperv.h
++++ b/arch/x86/include/asm/mshyperv.h
+@@ -3,6 +3,7 @@
+
+ #include <linux/types.h>
+ #include <linux/atomic.h>
++#include <linux/nmi.h>
+ #include <asm/io.h>
+ #include <asm/hyperv.h>
+
+@@ -209,7 +210,13 @@ static inline u64 hv_do_hypercall(u64 control, void *input, void *output)
+ return hv_status;
+ }
+
++#define HV_HYPERCALL_RESULT_MASK GENMASK_ULL(15, 0)
+ #define HV_HYPERCALL_FAST_BIT BIT(16)
++#define HV_HYPERCALL_VARHEAD_OFFSET 17
++#define HV_HYPERCALL_REP_COMP_OFFSET 32
++#define HV_HYPERCALL_REP_COMP_MASK GENMASK_ULL(43, 32)
++#define HV_HYPERCALL_REP_START_OFFSET 48
++#define HV_HYPERCALL_REP_START_MASK GENMASK_ULL(59, 48)
+
+ /* Fast hypercall with 8 bytes of input and no output */
+ static inline u64 hv_do_fast_hypercall8(u16 code, u64 input1)
+@@ -243,6 +250,38 @@ static inline u64 hv_do_fast_hypercall8(u16 code, u64 input1)
+ return hv_status;
+ }
+
++/*
++ * Rep hypercalls. Callers of this functions are supposed to ensure that
++ * rep_count and varhead_size comply with Hyper-V hypercall definition.
++ */
++static inline u64 hv_do_rep_hypercall(u16 code, u16 rep_count, u16 varhead_size,
++ void *input, void *output)
++{
++ u64 control = code;
++ u64 status;
++ u16 rep_comp;
++
++ control |= (u64)varhead_size << HV_HYPERCALL_VARHEAD_OFFSET;
++ control |= (u64)rep_count << HV_HYPERCALL_REP_COMP_OFFSET;
++
++ do {
++ status = hv_do_hypercall(control, input, output);
++ if ((status & HV_HYPERCALL_RESULT_MASK) != HV_STATUS_SUCCESS)
++ return status;
++
++ /* Bits 32-43 of status have 'Reps completed' data. */
++ rep_comp = (status & HV_HYPERCALL_REP_COMP_MASK) >>
++ HV_HYPERCALL_REP_COMP_OFFSET;
++
++ control &= ~HV_HYPERCALL_REP_START_MASK;
++ control |= (u64)rep_comp << HV_HYPERCALL_REP_START_OFFSET;
++
++ touch_nmi_watchdog();
++ } while (rep_comp < rep_count);
++
++ return status;
++}
++
+ void hyperv_init(void);
+ void hyperv_report_panic(struct pt_regs *regs);
+ bool hv_is_hypercall_page_setup(void);
diff --git a/patches.suse/msft-hv-1423-hyper-v-Globalize-vp_index.patch b/patches.suse/msft-hv-1423-hyper-v-Globalize-vp_index.patch
new file mode 100644
index 0000000000..f9e902cdce
--- /dev/null
+++ b/patches.suse/msft-hv-1423-hyper-v-Globalize-vp_index.patch
@@ -0,0 +1,366 @@
+From: Vitaly Kuznetsov <vkuznets@redhat.com>
+Date: Wed, 2 Aug 2017 18:09:18 +0200
+Patch-mainline: v4.14-rc1
+Subject: hyper-v: Globalize vp_index
+Git-commit: 7415aea6072bab15969b6c3c5b2a193d88095326
+References: fate#323887
+
+To support implementing remote TLB flushing on Hyper-V with a hypercall
+we need to make vp_index available outside of vmbus module. Rename and
+globalize.
+
+Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
+Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Reviewed-by: Stephen Hemminger <sthemmin@microsoft.com>
+Cc: Andy Lutomirski <luto@kernel.org>
+Cc: Haiyang Zhang <haiyangz@microsoft.com>
+Cc: Jork Loeser <Jork.Loeser@microsoft.com>
+Cc: K. Y. Srinivasan <kys@microsoft.com>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Simon Xiao <sixiao@microsoft.com>
+Cc: Steven Rostedt <rostedt@goodmis.org>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Cc: devel@linuxdriverproject.org
+Link: http://lkml.kernel.org/r/20170802160921.21791-7-vkuznets@redhat.com
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Acked-by: Olaf Hering <ohering@suse.de>
+---
+ arch/x86/hyperv/hv_init.c | 34 +++++++++++++++++++++++++-
+ arch/x86/include/asm/mshyperv.h | 24 ++++++++++++++++++
+ drivers/hv/channel_mgmt.c | 7 +++---
+ drivers/hv/connection.c | 3 ++-
+ drivers/hv/hv.c | 9 -------
+ drivers/hv/hyperv_vmbus.h | 11 ---------
+ drivers/hv/vmbus_drv.c | 17 -------------
+ drivers/pci/host/pci-hyperv.c | 54 +++--------------------------------------
+ include/linux/hyperv.h | 1 -
+ 9 files changed, 65 insertions(+), 95 deletions(-)
+
+diff --git a/arch/x86/hyperv/hv_init.c b/arch/x86/hyperv/hv_init.c
+--- a/arch/x86/hyperv/hv_init.c
++++ b/arch/x86/hyperv/hv_init.c
+@@ -26,6 +26,8 @@
+ #include <linux/mm.h>
+ #include <linux/clockchips.h>
+ #include <linux/hyperv.h>
++#include <linux/slab.h>
++#include <linux/cpuhotplug.h>
+
+ #ifdef CONFIG_HYPERV_TSCPAGE
+
+@@ -80,6 +82,20 @@ EXPORT_SYMBOL_GPL(hv_hypercall_pg);
+ struct clocksource *hyperv_cs;
+ EXPORT_SYMBOL_GPL(hyperv_cs);
+
++u32 *hv_vp_index;
++EXPORT_SYMBOL_GPL(hv_vp_index);
++
++static int hv_cpu_init(unsigned int cpu)
++{
++ u64 msr_vp_index;
++
++ hv_get_vp_index(msr_vp_index);
++
++ hv_vp_index[smp_processor_id()] = msr_vp_index;
++
++ return 0;
++}
++
+ /*
+ * This function is to be invoked early in the boot sequence after the
+ * hypervisor has been detected.
+@@ -95,6 +111,16 @@ void hyperv_init(void)
+ if (x86_hyper != &x86_hyper_ms_hyperv)
+ return;
+
++ /* Allocate percpu VP index */
++ hv_vp_index = kmalloc_array(num_possible_cpus(), sizeof(*hv_vp_index),
++ GFP_KERNEL);
++ if (!hv_vp_index)
++ return;
++
++ if (cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "x86/hyperv_init:online",
++ hv_cpu_init, NULL) < 0)
++ goto free_vp_index;
++
+ /*
+ * Setup the hypercall page and enable hypercalls.
+ * 1. Register the guest ID
+@@ -106,7 +132,7 @@ void hyperv_init(void)
+ hv_hypercall_pg = __vmalloc(PAGE_SIZE, GFP_KERNEL, PAGE_KERNEL_RX);
+ if (hv_hypercall_pg == NULL) {
+ wrmsrl(HV_X64_MSR_GUEST_OS_ID, 0);
+- return;
++ goto free_vp_index;
+ }
+
+ rdmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64);
+@@ -149,6 +175,12 @@ register_msr_cs:
+ hyperv_cs = &hyperv_cs_msr;
+ if (ms_hyperv.features & HV_X64_MSR_TIME_REF_COUNT_AVAILABLE)
+ clocksource_register_hz(&hyperv_cs_msr, NSEC_PER_SEC/100);
++
++ return;
++
++free_vp_index:
++ kfree(hv_vp_index);
++ hv_vp_index = NULL;
+ }
+
+ /*
+diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h
+--- a/arch/x86/include/asm/mshyperv.h
++++ b/arch/x86/include/asm/mshyperv.h
+@@ -282,6 +282,30 @@ static inline u64 hv_do_rep_hypercall(u16 code, u16 rep_count, u16 varhead_size,
+ return status;
+ }
+
++/*
++ * Hypervisor's notion of virtual processor ID is different from
++ * Linux' notion of CPU ID. This information can only be retrieved
++ * in the context of the calling CPU. Setup a map for easy access
++ * to this information.
++ */
++extern u32 *hv_vp_index;
++
++/**
++ * hv_cpu_number_to_vp_number() - Map CPU to VP.
++ * @cpu_number: CPU number in Linux terms
++ *
++ * This function returns the mapping between the Linux processor
++ * number and the hypervisor's virtual processor number, useful
++ * in making hypercalls and such that talk about specific
++ * processors.
++ *
++ * Return: Virtual processor number in Hyper-V terms
++ */
++static inline int hv_cpu_number_to_vp_number(int cpu_number)
++{
++ return hv_vp_index[cpu_number];
++}
++
+ void hyperv_init(void);
+ void hyperv_report_panic(struct pt_regs *regs);
+ bool hv_is_hypercall_page_setup(void);
+diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c
+--- a/drivers/hv/channel_mgmt.c
++++ b/drivers/hv/channel_mgmt.c
+@@ -599,7 +599,7 @@ static void init_vp_index(struct vmbus_channel *channel, u16 dev_type)
+ */
+ channel->numa_node = 0;
+ channel->target_cpu = 0;
+- channel->target_vp = hv_context.vp_index[0];
++ channel->target_vp = hv_cpu_number_to_vp_number(0);
+ return;
+ }
+
+@@ -683,7 +683,7 @@ static void init_vp_index(struct vmbus_channel *channel, u16 dev_type)
+ }
+
+ channel->target_cpu = cur_cpu;
+- channel->target_vp = hv_context.vp_index[cur_cpu];
++ channel->target_vp = hv_cpu_number_to_vp_number(cur_cpu);
+ }
+
+ static void vmbus_wait_for_unload(void)
+@@ -1219,8 +1219,7 @@ struct vmbus_channel *vmbus_get_outgoing_channel(struct vmbus_channel *primary)
+ return outgoing_channel;
+ }
+
+- cur_cpu = hv_context.vp_index[get_cpu()];
+- put_cpu();
++ cur_cpu = hv_cpu_number_to_vp_number(smp_processor_id());
+ list_for_each_safe(cur, tmp, &primary->sc_list) {
+ cur_channel = list_entry(cur, struct vmbus_channel, sc_list);
+ if (cur_channel->state != CHANNEL_OPENED_STATE)
+diff --git a/drivers/hv/connection.c b/drivers/hv/connection.c
+--- a/drivers/hv/connection.c
++++ b/drivers/hv/connection.c
+@@ -96,7 +96,8 @@ static int vmbus_negotiate_version(struct vmbus_channel_msginfo *msginfo,
+ * the CPU attempting to connect may not be CPU 0.
+ */
+ if (version >= VERSION_WIN8_1) {
+- msg->target_vcpu = hv_context.vp_index[smp_processor_id()];
++ msg->target_vcpu =
++ hv_cpu_number_to_vp_number(smp_processor_id());
+ vmbus_connection.connect_cpu = smp_processor_id();
+ } else {
+ msg->target_vcpu = 0;
+diff --git a/drivers/hv/hv.c b/drivers/hv/hv.c
+--- a/drivers/hv/hv.c
++++ b/drivers/hv/hv.c
+@@ -234,7 +234,6 @@ int hv_synic_init(unsigned int cpu)
+ union hv_synic_siefp siefp;
+ union hv_synic_sint shared_sint;
+ union hv_synic_scontrol sctrl;
+- u64 vp_index;
+
+ /* Setup the Synic's message page */
+ hv_get_simp(simp.as_uint64);
+@@ -275,14 +274,6 @@ int hv_synic_init(unsigned int cpu)
+
+ hv_context.synic_initialized = true;
+
+- /*
+- * Setup the mapping between Hyper-V's notion
+- * of cpuid and Linux' notion of cpuid.
+- * This array will be indexed using Linux cpuid.
+- */
+- hv_get_vp_index(vp_index);
+- hv_context.vp_index[cpu] = (u32)vp_index;
+-
+ /*
+ * Register the per-cpu clockevent source.
+ */
+diff --git a/drivers/hv/hyperv_vmbus.h b/drivers/hv/hyperv_vmbus.h
+--- a/drivers/hv/hyperv_vmbus.h
++++ b/drivers/hv/hyperv_vmbus.h
+@@ -228,17 +228,6 @@ struct hv_context {
+
+ struct hv_per_cpu_context __percpu *cpu_context;
+
+- /*
+- * Hypervisor's notion of virtual processor ID is different from
+- * Linux' notion of CPU ID. This information can only be retrieved
+- * in the context of the calling CPU. Setup a map for easy access
+- * to this information:
+- *
+- * vp_index[a] is the Hyper-V's processor ID corresponding to
+- * Linux cpuid 'a'.
+- */
+- u32 vp_index[NR_CPUS];
+-
+ /*
+ * To manage allocations in a NUMA node.
+ * Array indexed by numa node ID.
+diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
+--- a/drivers/hv/vmbus_drv.c
++++ b/drivers/hv/vmbus_drv.c
+@@ -1451,23 +1451,6 @@ void vmbus_free_mmio(resource_size_t start, resource_size_t size)
+ }
+ EXPORT_SYMBOL_GPL(vmbus_free_mmio);
+
+-/**
+- * vmbus_cpu_number_to_vp_number() - Map CPU to VP.
+- * @cpu_number: CPU number in Linux terms
+- *
+- * This function returns the mapping between the Linux processor
+- * number and the hypervisor's virtual processor number, useful
+- * in making hypercalls and such that talk about specific
+- * processors.
+- *
+- * Return: Virtual processor number in Hyper-V terms
+- */
+-int vmbus_cpu_number_to_vp_number(int cpu_number)
+-{
+- return hv_context.vp_index[cpu_number];
+-}
+-EXPORT_SYMBOL_GPL(vmbus_cpu_number_to_vp_number);
+-
+ static int vmbus_acpi_add(struct acpi_device *device)
+ {
+ acpi_status result;
+diff --git a/drivers/pci/host/pci-hyperv.c b/drivers/pci/host/pci-hyperv.c
+--- a/drivers/pci/host/pci-hyperv.c
++++ b/drivers/pci/host/pci-hyperv.c
+@@ -562,52 +562,6 @@ static void put_pcichild(struct hv_pci_dev *hv_pcidev,
+ static void get_hvpcibus(struct hv_pcibus_device *hv_pcibus);
+ static void put_hvpcibus(struct hv_pcibus_device *hv_pcibus);
+
+-
+-/*
+- * Temporary CPU to vCPU mapping to address transitioning
+- * vmbus_cpu_number_to_vp_number() being migrated to
+- * hv_cpu_number_to_vp_number() in a separate patch. Once that patch
+- * has been picked up in the main line, remove this code here and use
+- * the official code.
+- */
+-static struct hv_tmpcpumap
+-{
+- bool initialized;
+- u32 vp_index[NR_CPUS];
+-} hv_tmpcpumap;
+-
+-static void hv_tmpcpumap_init_cpu(void *_unused)
+-{
+- int cpu = smp_processor_id();
+- u64 vp_index;
+-
+- hv_get_vp_index(vp_index);
+-
+- hv_tmpcpumap.vp_index[cpu] = vp_index;
+-}
+-
+-static void hv_tmpcpumap_init(void)
+-{
+- if (hv_tmpcpumap.initialized)
+- return;
+-
+- memset(hv_tmpcpumap.vp_index, -1, sizeof(hv_tmpcpumap.vp_index));
+- on_each_cpu(hv_tmpcpumap_init_cpu, NULL, true);
+- hv_tmpcpumap.initialized = true;
+-}
+-
+-/**
+- * hv_tmp_cpu_nr_to_vp_nr() - Convert Linux CPU nr to Hyper-V vCPU nr
+- *
+- * Remove once vmbus_cpu_number_to_vp_number() has been converted to
+- * hv_cpu_number_to_vp_number() and replace callers appropriately.
+- */
+-static u32 hv_tmp_cpu_nr_to_vp_nr(int cpu)
+-{
+- return hv_tmpcpumap.vp_index[cpu];
+-}
+-
+-
+ /**
+ * devfn_to_wslot() - Convert from Linux PCI slot to Windows
+ * @devfn: The Linux representation of PCI slot
+@@ -971,7 +925,7 @@ static void hv_irq_unmask(struct irq_data *data)
+ var_size = 1 + HV_VP_SET_BANK_COUNT_MAX;
+
+ for_each_cpu_and(cpu, dest, cpu_online_mask) {
+- cpu_vmbus = hv_tmp_cpu_nr_to_vp_nr(cpu);
++ cpu_vmbus = hv_cpu_number_to_vp_number(cpu);
+
+ if (cpu_vmbus >= HV_VP_SET_BANK_COUNT_MAX * 64) {
+ dev_err(&hbus->hdev->device,
+@@ -986,7 +940,7 @@ static void hv_irq_unmask(struct irq_data *data)
+ } else {
+ for_each_cpu_and(cpu, dest, cpu_online_mask) {
+ params->int_target.vp_mask |=
+- (1ULL << hv_tmp_cpu_nr_to_vp_nr(cpu));
++ (1ULL << hv_cpu_number_to_vp_number(cpu));
+ }
+ }
+
+@@ -1063,7 +1017,7 @@ static u32 hv_compose_msi_req_v2(
+ */
+ cpu = cpumask_first_and(affinity, cpu_online_mask);
+ int_pkt->int_desc.processor_array[0] =
+- hv_tmp_cpu_nr_to_vp_nr(cpu);
++ hv_cpu_number_to_vp_number(cpu);
+ int_pkt->int_desc.processor_count = 1;
+
+ return sizeof(*int_pkt);
+@@ -2490,8 +2444,6 @@ static int hv_pci_probe(struct hv_device *hdev,
+ return -ENOMEM;
+ hbus->state = hv_pcibus_init;
+
+- hv_tmpcpumap_init();
+-
+ /*
+ * The PCI bus "domain" is what is called "segment" in ACPI and
+ * other specs. Pull it from the instance ID, to get something
+diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
+--- a/include/linux/hyperv.h
++++ b/include/linux/hyperv.h
+@@ -1173,7 +1173,6 @@ int vmbus_allocate_mmio(struct resource **new, struct hv_device *device_obj,
+ resource_size_t size, resource_size_t align,
+ bool fb_overlap_ok);
+ void vmbus_free_mmio(resource_size_t start, resource_size_t size);
+-int vmbus_cpu_number_to_vp_number(int cpu_number);
+
+ /*
+ * GUID definitions of various offer types - services offered to the guest.
diff --git a/patches.suse/msft-hv-1424-x86-hyper-v-Use-hypercall-for-remote-TLB-flush.patch b/patches.suse/msft-hv-1424-x86-hyper-v-Use-hypercall-for-remote-TLB-flush.patch
new file mode 100644
index 0000000000..c073f0af1f
--- /dev/null
+++ b/patches.suse/msft-hv-1424-x86-hyper-v-Use-hypercall-for-remote-TLB-flush.patch
@@ -0,0 +1,278 @@
+From: Vitaly Kuznetsov <vkuznets@redhat.com>
+Date: Wed, 2 Aug 2017 18:09:19 +0200
+Patch-mainline: v4.14-rc1
+Subject: x86/hyper-v: Use hypercall for remote TLB flush
+Git-commit: 2ffd9e33ce4af4e8cfa3e17bf493defe8474e2eb
+References: fate#323887
+
+Hyper-V host can suggest us to use hypercall for doing remote TLB flush,
+this is supposed to work faster than IPIs.
+
+Implementation details: to do HvFlushVirtualAddress{Space,List} hypercalls
+we need to put the input somewhere in memory and we don't really want to
+have memory allocation on each call so we pre-allocate per cpu memory areas
+on boot.
+
+pv_ops patching is happening very early so we need to separate
+hyperv_setup_mmu_ops() and hyper_alloc_mmu().
+
+It is possible and easy to implement local TLB flushing too and there is
+even a hint for that. However, I don't see a room for optimization on the
+host side as both hypercall and native tlb flush will result in vmexit. The
+hint is also not set on modern Hyper-V versions.
+
+Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
+Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Reviewed-by: Stephen Hemminger <sthemmin@microsoft.com>
+Cc: Andy Lutomirski <luto@kernel.org>
+Cc: Haiyang Zhang <haiyangz@microsoft.com>
+Cc: Jork Loeser <Jork.Loeser@microsoft.com>
+Cc: K. Y. Srinivasan <kys@microsoft.com>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Simon Xiao <sixiao@microsoft.com>
+Cc: Steven Rostedt <rostedt@goodmis.org>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Cc: devel@linuxdriverproject.org
+Link: http://lkml.kernel.org/r/20170802160921.21791-8-vkuznets@redhat.com
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Acked-by: Olaf Hering <ohering@suse.de>
+---
+ arch/x86/hyperv/Makefile | 2 +-
+ arch/x86/hyperv/hv_init.c | 2 +
+ arch/x86/hyperv/mmu.c | 138 +++++++++++++++++++++++++++++++++++++
+ arch/x86/include/asm/mshyperv.h | 3 +
+ arch/x86/include/uapi/asm/hyperv.h | 7 ++
+ arch/x86/kernel/cpu/mshyperv.c | 1 +
+ drivers/hv/Kconfig | 1 +
+ 7 files changed, 153 insertions(+), 1 deletion(-)
+ create mode 100644 arch/x86/hyperv/mmu.c
+
+diff --git a/arch/x86/hyperv/Makefile b/arch/x86/hyperv/Makefile
+--- a/arch/x86/hyperv/Makefile
++++ b/arch/x86/hyperv/Makefile
+@@ -1 +1 @@
+-obj-y := hv_init.o
++obj-y := hv_init.o mmu.o
+diff --git a/arch/x86/hyperv/hv_init.c b/arch/x86/hyperv/hv_init.c
+--- a/arch/x86/hyperv/hv_init.c
++++ b/arch/x86/hyperv/hv_init.c
+@@ -140,6 +140,8 @@ void hyperv_init(void)
+ hypercall_msr.guest_physical_address = vmalloc_to_pfn(hv_hypercall_pg);
+ wrmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64);
+
++ hyper_alloc_mmu();
++
+ /*
+ * Register Hyper-V specific clocksource.
+ */
+diff --git a/arch/x86/hyperv/mmu.c b/arch/x86/hyperv/mmu.c
+new file mode 100644
+index 000000000000..9419a20b1d75
+--- /dev/null
++++ b/arch/x86/hyperv/mmu.c
+@@ -0,0 +1,138 @@
++#define pr_fmt(fmt) "Hyper-V: " fmt
++
++#include <linux/hyperv.h>
++#include <linux/log2.h>
++#include <linux/slab.h>
++#include <linux/types.h>
++
++#include <asm/fpu/api.h>
++#include <asm/mshyperv.h>
++#include <asm/msr.h>
++#include <asm/tlbflush.h>
++
++/* HvFlushVirtualAddressSpace, HvFlushVirtualAddressList hypercalls */
++struct hv_flush_pcpu {
++ u64 address_space;
++ u64 flags;
++ u64 processor_mask;
++ u64 gva_list[];
++};
++
++/* Each gva in gva_list encodes up to 4096 pages to flush */
++#define HV_TLB_FLUSH_UNIT (4096 * PAGE_SIZE)
++
++static struct hv_flush_pcpu __percpu *pcpu_flush;
++
++/*
++ * Fills in gva_list starting from offset. Returns the number of items added.
++ */
++static inline int fill_gva_list(u64 gva_list[], int offset,
++ unsigned long start, unsigned long end)
++{
++ int gva_n = offset;
++ unsigned long cur = start, diff;
++
++ do {
++ diff = end > cur ? end - cur : 0;
++
++ gva_list[gva_n] = cur & PAGE_MASK;
++ /*
++ * Lower 12 bits encode the number of additional
++ * pages to flush (in addition to the 'cur' page).
++ */
++ if (diff >= HV_TLB_FLUSH_UNIT)
++ gva_list[gva_n] |= ~PAGE_MASK;
++ else if (diff)
++ gva_list[gva_n] |= (diff - 1) >> PAGE_SHIFT;
++
++ cur += HV_TLB_FLUSH_UNIT;
++ gva_n++;
++
++ } while (cur < end);
++
++ return gva_n - offset;
++}
++
++static void hyperv_flush_tlb_others(const struct cpumask *cpus,
++struct mm_struct *mm, unsigned long start, unsigned long end)
++{
++ int cpu, vcpu, gva_n, max_gvas;
++ struct hv_flush_pcpu *flush;
++ u64 status = U64_MAX;
++ unsigned long flags;
++
++ if (!pcpu_flush || !hv_hypercall_pg)
++ goto do_native;
++
++ if (cpumask_empty(cpus))
++ return;
++
++ local_irq_save(flags);
++
++ flush = this_cpu_ptr(pcpu_flush);
++
++ if (mm) {
++ flush->address_space = virt_to_phys(mm->pgd);
++ flush->flags = 0;
++ } else {
++ flush->address_space = 0;
++ flush->flags = HV_FLUSH_ALL_VIRTUAL_ADDRESS_SPACES;
++ }
++
++ flush->processor_mask = 0;
++ if (cpumask_equal(cpus, cpu_present_mask)) {
++ flush->flags |= HV_FLUSH_ALL_PROCESSORS;
++ } else {
++ for_each_cpu(cpu, cpus) {
++ vcpu = hv_cpu_number_to_vp_number(cpu);
++ if (vcpu >= 64)
++ goto do_native;
++
++ __set_bit(vcpu, (unsigned long *)
++ &flush->processor_mask);
++ }
++ }
++
++ /*
++ * We can flush not more than max_gvas with one hypercall. Flush the
++ * whole address space if we were asked to do more.
++ */
++ max_gvas = (PAGE_SIZE - sizeof(*flush)) / sizeof(flush->gva_list[0]);
++
++ if (end == TLB_FLUSH_ALL) {
++ flush->flags |= HV_FLUSH_NON_GLOBAL_MAPPINGS_ONLY;
++ status = hv_do_hypercall(HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE,
++ flush, NULL);
++ } else if (end &&
++ ((end - start)/HV_TLB_FLUSH_UNIT) > max_gvas) {
++ status = hv_do_hypercall(HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE,
++ flush, NULL);
++ } else {
++ gva_n = fill_gva_list(flush->gva_list, 0,
++ start, end);
++ status = hv_do_rep_hypercall(HVCALL_FLUSH_VIRTUAL_ADDRESS_LIST,
++ gva_n, 0, flush, NULL);
++ }
++
++ local_irq_restore(flags);
++
++ if (!(status & HV_HYPERCALL_RESULT_MASK))
++ return;
++do_native:
++ native_flush_tlb_others(cpus, mm, start, end);
++}
++
++void hyperv_setup_mmu_ops(void)
++{
++ if (ms_hyperv.hints & HV_X64_REMOTE_TLB_FLUSH_RECOMMENDED) {
++ pr_info("Using hypercall for remote TLB flush\n");
++ pv_mmu_ops.flush_tlb_others = hyperv_flush_tlb_others;
++ setup_clear_cpu_cap(X86_FEATURE_PCID);
++ }
++}
++
++void hyper_alloc_mmu(void)
++{
++ if (ms_hyperv.hints & HV_X64_REMOTE_TLB_FLUSH_RECOMMENDED)
++ pcpu_flush = __alloc_percpu(PAGE_SIZE, PAGE_SIZE);
++}
+diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h
+--- a/arch/x86/include/asm/mshyperv.h
++++ b/arch/x86/include/asm/mshyperv.h
+@@ -307,6 +307,8 @@ static inline int hv_cpu_number_to_vp_number(int cpu_number)
+ }
+
+ void hyperv_init(void);
++void hyperv_setup_mmu_ops(void);
++void hyper_alloc_mmu(void);
+ void hyperv_report_panic(struct pt_regs *regs);
+ bool hv_is_hypercall_page_setup(void);
+ void hyperv_cleanup(void);
+@@ -314,6 +316,7 @@ void hyperv_cleanup(void);
+ static inline void hyperv_init(void) {}
+ static inline bool hv_is_hypercall_page_setup(void) { return false; }
+ static inline void hyperv_cleanup(void) {}
++static inline void hyperv_setup_mmu_ops(void) {}
+ #endif /* CONFIG_HYPERV */
+
+ #ifdef CONFIG_HYPERV_TSCPAGE
+diff --git a/arch/x86/include/uapi/asm/hyperv.h b/arch/x86/include/uapi/asm/hyperv.h
+--- a/arch/x86/include/uapi/asm/hyperv.h
++++ b/arch/x86/include/uapi/asm/hyperv.h
+@@ -242,6 +242,8 @@
+ (~((1ull << HV_X64_MSR_HYPERCALL_PAGE_ADDRESS_SHIFT) - 1))
+
+ /* Declare the various hypercall operations. */
++#define HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE 0x0002
++#define HVCALL_FLUSH_VIRTUAL_ADDRESS_LIST 0x0003
+ #define HVCALL_NOTIFY_LONG_SPIN_WAIT 0x0008
+ #define HVCALL_POST_MESSAGE 0x005c
+ #define HVCALL_SIGNAL_EVENT 0x005d
+@@ -259,6 +261,11 @@
+ #define HV_PROCESSOR_POWER_STATE_C2 2
+ #define HV_PROCESSOR_POWER_STATE_C3 3
+
++#define HV_FLUSH_ALL_PROCESSORS BIT(0)
++#define HV_FLUSH_ALL_VIRTUAL_ADDRESS_SPACES BIT(1)
++#define HV_FLUSH_NON_GLOBAL_MAPPINGS_ONLY BIT(2)
++#define HV_FLUSH_USE_EXTENDED_RANGE_FORMAT BIT(3)
++
+ /* hypercall status code */
+ #define HV_STATUS_SUCCESS 0
+ #define HV_STATUS_INVALID_HYPERCALL_CODE 2
+diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c
+--- a/arch/x86/kernel/cpu/mshyperv.c
++++ b/arch/x86/kernel/cpu/mshyperv.c
+@@ -249,6 +249,7 @@ static void __init ms_hyperv_init_platform(void)
+ * Setup the hook to get control post apic initialization.
+ */
+ x86_platform.apic_post_init = hyperv_init;
++ hyperv_setup_mmu_ops();
+ #endif
+ }
+
+diff --git a/drivers/hv/Kconfig b/drivers/hv/Kconfig
+--- a/drivers/hv/Kconfig
++++ b/drivers/hv/Kconfig
+@@ -3,6 +3,7 @@ menu "Microsoft Hyper-V guest support"
+ config HYPERV
+ tristate "Microsoft Hyper-V client drivers"
+ depends on X86 && ACPI && PCI && X86_LOCAL_APIC && HYPERVISOR_GUEST
++ select PARAVIRT
+ help
+ Select this option to run Linux as a Hyper-V client operating
+ system.
diff --git a/patches.suse/msft-hv-1425-netvsc-delay-setup-of-VF-device.patch b/patches.suse/msft-hv-1425-netvsc-delay-setup-of-VF-device.patch
new file mode 100644
index 0000000000..e2bb6905ba
--- /dev/null
+++ b/patches.suse/msft-hv-1425-netvsc-delay-setup-of-VF-device.patch
@@ -0,0 +1,95 @@
+From: stephen hemminger <stephen@networkplumber.org>
+Date: Wed, 9 Aug 2017 17:46:03 -0700
+Patch-mainline: v4.14-rc1
+Subject: netvsc: delay setup of VF device
+Git-commit: 6123c66854c174e4982f98195100c1d990f9e5e6
+References: fate#323887
+
+When VF device is discovered, delay bring it automatically up in
+order to allow userspace to some simple changes (like renaming).
+
+Reported-by: Vitaly Kuznetsov <vkuznets@redhat.com>
+Signed-off-by: Stephen Hemminger <sthemmin@microsoft.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Acked-by: Olaf Hering <ohering@suse.de>
+---
+ drivers/net/hyperv/hyperv_net.h | 2 +-
+ drivers/net/hyperv/netvsc_drv.c | 15 ++++++++-------
+ 2 files changed, 9 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h
+--- a/drivers/net/hyperv/hyperv_net.h
++++ b/drivers/net/hyperv/hyperv_net.h
+@@ -723,7 +723,7 @@ struct net_device_context {
+ /* State to manage the associated VF interface. */
+ struct net_device __rcu *vf_netdev;
+ struct netvsc_vf_pcpu_stats __percpu *vf_stats;
+- struct work_struct vf_takeover;
++ struct delayed_work vf_takeover;
+
+ /* 1: allocated, serial number is valid. 0: not allocated */
+ u32 vf_alloc;
+diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
+--- a/drivers/net/hyperv/netvsc_drv.c
++++ b/drivers/net/hyperv/netvsc_drv.c
+@@ -47,6 +47,7 @@
+
+ #define RING_SIZE_MIN 64
+ #define LINKCHANGE_INT (2 * HZ)
++#define VF_TAKEOVER_INT (HZ / 10)
+
+ static int ring_size = 128;
+ module_param(ring_size, int, S_IRUGO);
+@@ -1559,7 +1560,9 @@ static int netvsc_vf_join(struct net_device *vf_netdev,
+ /* set slave flag before open to prevent IPv6 addrconf */
+ vf_netdev->flags |= IFF_SLAVE;
+
+- schedule_work(&ndev_ctx->vf_takeover);
++ schedule_delayed_work(&ndev_ctx->vf_takeover, VF_TAKEOVER_INT);
++
++ call_netdevice_notifiers(NETDEV_JOIN, vf_netdev);
+
+ netdev_info(vf_netdev, "joined to %s\n", ndev->name);
+ return 0;
+@@ -1575,8 +1578,6 @@ static void __netvsc_vf_setup(struct net_device *ndev,
+ {
+ int ret;
+
+- call_netdevice_notifiers(NETDEV_JOIN, vf_netdev);
+-
+ /* Align MTU of VF with master */
+ ret = dev_set_mtu(vf_netdev, ndev->mtu);
+ if (ret)
+@@ -1597,12 +1598,12 @@ static void __netvsc_vf_setup(struct net_device *ndev,
+ static void netvsc_vf_setup(struct work_struct *w)
+ {
+ struct net_device_context *ndev_ctx
+- = container_of(w, struct net_device_context, vf_takeover);
++ = container_of(w, struct net_device_context, vf_takeover.work);
+ struct net_device *ndev = hv_get_drvdata(ndev_ctx->device_ctx);
+ struct net_device *vf_netdev;
+
+ if (!rtnl_trylock()) {
+- schedule_work(w);
++ schedule_delayed_work(&ndev_ctx->vf_takeover, 0);
+ return;
+ }
+
+@@ -1706,7 +1707,7 @@ static int netvsc_unregister_vf(struct net_device *vf_netdev)
+ return NOTIFY_DONE;
+
+ net_device_ctx = netdev_priv(ndev);
+- cancel_work_sync(&net_device_ctx->vf_takeover);
++ cancel_delayed_work_sync(&net_device_ctx->vf_takeover);
+
+ netdev_info(ndev, "VF unregistering: %s\n", vf_netdev->name);
+
+@@ -1748,7 +1749,7 @@ static int netvsc_probe(struct hv_device *dev,
+
+ spin_lock_init(&net_device_ctx->lock);
+ INIT_LIST_HEAD(&net_device_ctx->reconfig_events);
+- INIT_WORK(&net_device_ctx->vf_takeover, netvsc_vf_setup);
++ INIT_DELAYED_WORK(&net_device_ctx->vf_takeover, netvsc_vf_setup);
+
+ net_device_ctx->vf_stats
+ = netdev_alloc_pcpu_stats(struct netvsc_vf_pcpu_stats);
diff --git a/patches.suse/msft-hv-1426-netvsc-don-t-signal-host-twice-if-empty.patch b/patches.suse/msft-hv-1426-netvsc-don-t-signal-host-twice-if-empty.patch
new file mode 100644
index 0000000000..edd75d6819
--- /dev/null
+++ b/patches.suse/msft-hv-1426-netvsc-don-t-signal-host-twice-if-empty.patch
@@ -0,0 +1,31 @@
+From: stephen hemminger <stephen@networkplumber.org>
+Date: Wed, 9 Aug 2017 17:46:04 -0700
+Patch-mainline: v4.14-rc1
+Subject: netvsc: don't signal host twice if empty
+Git-commit: 5e20d55a23a76a876396ba1235bdf019e74d0c6f
+References: fate#323887
+
+When hv_pkt_iter_next() returns NULL, it has already called
+hv_pkt_iter_close(). Calling it twice can lead to extra host signal.
+
+Signed-off-by: Stephen Hemminger <sthemmin@microsoft.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Acked-by: Olaf Hering <ohering@suse.de>
+---
+ drivers/net/hyperv/netvsc.c | 4 ----
+ 1 file changed, 4 deletions(-)
+
+diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c
+--- a/drivers/net/hyperv/netvsc.c
++++ b/drivers/net/hyperv/netvsc.c
+@@ -1191,10 +1191,6 @@ int netvsc_poll(struct napi_struct *napi, int budget)
+ nvchan->desc = hv_pkt_iter_next(channel, nvchan->desc);
+ }
+
+- /* if ring is empty, signal host */
+- if (!nvchan->desc)
+- hv_pkt_iter_close(channel);
+-
+ /* If send of pending receive completions suceeded
+ * and did not exhaust NAPI budget this time
+ * and not doing busy poll
diff --git a/patches.suse/msft-hv-1427-netvsc-propagate-MAC-address-change-to-VF-slave.patch b/patches.suse/msft-hv-1427-netvsc-propagate-MAC-address-change-to-VF-slave.patch
new file mode 100644
index 0000000000..9490b24730
--- /dev/null
+++ b/patches.suse/msft-hv-1427-netvsc-propagate-MAC-address-change-to-VF-slave.patch
@@ -0,0 +1,72 @@
+From: stephen hemminger <stephen@networkplumber.org>
+Date: Wed, 9 Aug 2017 17:46:05 -0700
+Patch-mainline: v4.14-rc1
+Subject: netvsc: propagate MAC address change to VF slave
+Git-commit: 16ba3266006be10dc7ec25dd1442f74cef89cb95
+References: fate#323887
+
+If VF is slaved to synthetic device, then any change to netvsc
+MAC address should be propagated to the slave device.
+
+If slave device doesn't support MAC address change then it
+should also be an error to attempt to change synthetic NIC MAC
+address.
+
+It also fixes the error unwind in the original code.
+If give a bad address, the old code would change the device
+MAC address anyway.
+
+Reviewed-by: Haiyang Zhang <haiyangz@microsoft.com>
+Signed-off-by: Stephen Hemminger <sthemmin@microsoft.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Acked-by: Olaf Hering <ohering@suse.de>
+---
+ drivers/net/hyperv/netvsc_drv.c | 26 +++++++++++++++-----------
+ 1 file changed, 15 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
+--- a/drivers/net/hyperv/netvsc_drv.c
++++ b/drivers/net/hyperv/netvsc_drv.c
+@@ -1053,27 +1053,31 @@ static void netvsc_get_stats64(struct net_device *net,
+ static int netvsc_set_mac_addr(struct net_device *ndev, void *p)
+ {
+ struct net_device_context *ndc = netdev_priv(ndev);
++ struct net_device *vf_netdev = rtnl_dereference(ndc->vf_netdev);
+ struct netvsc_device *nvdev = rtnl_dereference(ndc->nvdev);
+ struct sockaddr *addr = p;
+- char save_adr[ETH_ALEN];
+- unsigned char save_aatype;
+ int err;
+
+- memcpy(save_adr, ndev->dev_addr, ETH_ALEN);
+- save_aatype = ndev->addr_assign_type;
+-
+- err = eth_mac_addr(ndev, p);
+- if (err != 0)
++ err = eth_prepare_mac_addr_change(ndev, p);
++ if (err)
+ return err;
+
+ if (!nvdev)
+ return -ENODEV;
+
++ if (vf_netdev) {
++ err = dev_set_mac_address(vf_netdev, addr);
++ if (err)
++ return err;
++ }
++
+ err = rndis_filter_set_device_mac(nvdev, addr->sa_data);
+- if (err != 0) {
+- /* roll back to saved MAC */
+- memcpy(ndev->dev_addr, save_adr, ETH_ALEN);
+- ndev->addr_assign_type = save_aatype;
++ if (!err) {
++ eth_commit_mac_addr_change(ndev, p);
++ } else if (vf_netdev) {
++ /* rollback change on VF */
++ memcpy(addr->sa_data, ndev->dev_addr, ETH_ALEN);
++ dev_set_mac_address(vf_netdev, addr);
+ }
+
+ return err;
diff --git a/patches.suse/msft-hv-1428-netvsc-check-error-return-when-restoring-channels-an.patch b/patches.suse/msft-hv-1428-netvsc-check-error-return-when-restoring-channels-an.patch
new file mode 100644
index 0000000000..c04374d62f
--- /dev/null
+++ b/patches.suse/msft-hv-1428-netvsc-check-error-return-when-restoring-channels-an.patch
@@ -0,0 +1,54 @@
+From: stephen hemminger <stephen@networkplumber.org>
+Date: Wed, 9 Aug 2017 17:46:06 -0700
+Patch-mainline: v4.14-rc1
+Subject: netvsc: check error return when restoring channels and mtu
+Git-commit: 68d715f68541d58033199eea80991394a6886eb7
+References: fate#323887
+
+If setting new values fails, and the attempt to restore original
+settings fails. Then log an error and leave device down.
+This should never happen, but if it does don't go down in flames.
+
+Signed-off-by: Stephen Hemminger <sthemmin@microsoft.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Acked-by: Olaf Hering <ohering@suse.de>
+---
+ drivers/net/hyperv/netvsc_drv.c | 16 ++++++++++++++--
+ 1 file changed, 14 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
+--- a/drivers/net/hyperv/netvsc_drv.c
++++ b/drivers/net/hyperv/netvsc_drv.c
+@@ -845,7 +845,13 @@ static int netvsc_set_channels(struct net_device *net,
+ } else {
+ ret = PTR_ERR(nvdev);
+ device_info.num_chn = orig;
+- rndis_filter_device_add(dev, &device_info);
++ nvdev = rndis_filter_device_add(dev, &device_info);
++
++ if (IS_ERR(nvdev)) {
++ netdev_err(net, "restoring channel setting failed: %ld\n",
++ PTR_ERR(nvdev));
++ return ret;
++ }
+ }
+
+ if (was_opened)
+@@ -953,10 +959,16 @@ static int netvsc_change_mtu(struct net_device *ndev, int mtu)
+
+ /* Attempt rollback to original MTU */
+ ndev->mtu = orig_mtu;
+- rndis_filter_device_add(hdev, &device_info);
++ nvdev = rndis_filter_device_add(hdev, &device_info);
+
+ if (vf_netdev)
+ dev_set_mtu(vf_netdev, orig_mtu);
++
++ if (IS_ERR(nvdev)) {
++ netdev_err(ndev, "restoring mtu failed: %ld\n",
++ PTR_ERR(nvdev));
++ return ret;
++ }
+ }
+
+ if (was_opened)
diff --git a/patches.suse/msft-hv-1429-netvsc-no-need-to-allocate-send-receive-on-numa-node.patch b/patches.suse/msft-hv-1429-netvsc-no-need-to-allocate-send-receive-on-numa-node.patch
new file mode 100644
index 0000000000..e58a86a53c
--- /dev/null
+++ b/patches.suse/msft-hv-1429-netvsc-no-need-to-allocate-send-receive-on-numa-node.patch
@@ -0,0 +1,58 @@
+From: stephen hemminger <stephen@networkplumber.org>
+Date: Wed, 9 Aug 2017 17:46:07 -0700
+Patch-mainline: v4.14-rc1
+Subject: netvsc: no need to allocate send/receive on numa node
+Git-commit: 958333708f2877d3855e3bc31dad428e2f2c8096
+References: fate#323887
+
+The send and receive buffers are both per-device (not per-channel).
+The associated NUMA node is a property of the CPU which is per-channel
+therefore it makes no sense to force the receive/send buffer to be
+allocated on a particular node (since it is a shared resource).
+
+Signed-off-by: Stephen Hemminger <sthemmin@microsoft.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Acked-by: Olaf Hering <ohering@suse.de>
+---
+ drivers/net/hyperv/netvsc.c | 19 +++++--------------
+ 1 file changed, 5 insertions(+), 14 deletions(-)
+
+diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c
+--- a/drivers/net/hyperv/netvsc.c
++++ b/drivers/net/hyperv/netvsc.c
+@@ -246,20 +246,13 @@ int netvsc_alloc_recv_comp_ring(struct netvsc_device *net_device, u32 q_idx)
+ static int netvsc_init_buf(struct hv_device *device,
+ struct netvsc_device *net_device)
+ {
+- int ret = 0;
+- struct nvsp_message *init_packet;
+ struct nvsp_1_message_send_receive_buffer_complete *resp;
+- struct net_device *ndev;
++ struct net_device *ndev = hv_get_drvdata(device);
++ struct nvsp_message *init_packet;
+ size_t map_words;
+- int node;
+-
+- ndev = hv_get_drvdata(device);
+-
+- node = cpu_to_node(device->channel->target_cpu);
+- net_device->recv_buf = vzalloc_node(net_device->recv_buf_size, node);
+- if (!net_device->recv_buf)
+- net_device->recv_buf = vzalloc(net_device->recv_buf_size);
++ int ret = 0;
+
++ net_device->recv_buf = vzalloc(net_device->recv_buf_size);
+ if (!net_device->recv_buf) {
+ netdev_err(ndev, "unable to allocate receive "
+ "buffer of size %d\n", net_device->recv_buf_size);
+@@ -340,9 +333,7 @@ static int netvsc_init_buf(struct hv_device *device,
+ goto cleanup;
+
+ /* Now setup the send buffer. */
+- net_device->send_buf = vzalloc_node(net_device->send_buf_size, node);
+- if (!net_device->send_buf)
+- net_device->send_buf = vzalloc(net_device->send_buf_size);
++ net_device->send_buf = vzalloc(net_device->send_buf_size);
+ if (!net_device->send_buf) {
+ netdev_err(ndev, "unable to allocate send "
+ "buffer of size %d\n", net_device->send_buf_size);
diff --git a/patches.suse/msft-hv-1430-netvsc-whitespace-cleanup.patch b/patches.suse/msft-hv-1430-netvsc-whitespace-cleanup.patch
new file mode 100644
index 0000000000..b07c4d98eb
--- /dev/null
+++ b/patches.suse/msft-hv-1430-netvsc-whitespace-cleanup.patch
@@ -0,0 +1,65 @@
+From: stephen hemminger <stephen@networkplumber.org>
+Date: Wed, 9 Aug 2017 17:46:08 -0700
+Patch-mainline: v4.14-rc1
+Subject: netvsc: whitespace cleanup
+Git-commit: 89bb42b11370c2daf19d8820398f7255f8499ab7
+References: fate#323887
+
+Fix some minor indentation issues.
+
+Signed-off-by: Stephen Hemminger <sthemmin@microsoft.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Acked-by: Olaf Hering <ohering@suse.de>
+---
+ drivers/net/hyperv/netvsc_drv.c | 11 ++++++-----
+ 1 file changed, 6 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
+--- a/drivers/net/hyperv/netvsc_drv.c
++++ b/drivers/net/hyperv/netvsc_drv.c
+@@ -165,7 +165,7 @@ static int netvsc_close(struct net_device *net)
+ }
+
+ static void *init_ppi_data(struct rndis_message *msg, u32 ppi_size,
+- int pkt_type)
++ int pkt_type)
+ {
+ struct rndis_packet *rndis_pkt;
+ struct rndis_per_packet_info *ppi;
+@@ -286,7 +286,7 @@ static u16 netvsc_select_queue(struct net_device *ndev, struct sk_buff *skb,
+ }
+
+ static u32 fill_pg_buf(struct page *page, u32 offset, u32 len,
+- struct hv_page_buffer *pb)
++ struct hv_page_buffer *pb)
+ {
+ int j = 0;
+
+@@ -626,6 +626,7 @@ no_memory:
+ ++net_device_ctx->eth_stats.tx_no_memory;
+ goto drop;
+ }
++
+ /*
+ * netvsc_linkstatus_callback - Link up/down notification
+ */
+@@ -649,8 +650,8 @@ void netvsc_linkstatus_callback(struct hv_device *device_obj,
+ if (indicate->status == RNDIS_STATUS_LINK_SPEED_CHANGE) {
+ u32 speed;
+
+- speed = *(u32 *)((void *)indicate + indicate->
+- status_buf_offset) / 10000;
++ speed = *(u32 *)((void *)indicate
++ + indicate->status_buf_offset) / 10000;
+ ndev_ctx->speed = speed;
+ return;
+ }
+@@ -1018,7 +1019,7 @@ static void netvsc_get_stats64(struct net_device *net,
+ struct net_device_context *ndev_ctx = netdev_priv(net);
+ struct netvsc_device *nvdev = rcu_dereference_rtnl(ndev_ctx->nvdev);
+ struct netvsc_vf_pcpu_stats vf_tot;
+- int i;
++ int i;
+
+ if (!nvdev)
+ return;
diff --git a/patches.suse/msft-hv-1431-netvsc-remove-unnecessary-cast-of-void-pointer.patch b/patches.suse/msft-hv-1431-netvsc-remove-unnecessary-cast-of-void-pointer.patch
new file mode 100644
index 0000000000..f4a35a6b50
--- /dev/null
+++ b/patches.suse/msft-hv-1431-netvsc-remove-unnecessary-cast-of-void-pointer.patch
@@ -0,0 +1,43 @@
+From: stephen hemminger <stephen@networkplumber.org>
+Date: Wed, 9 Aug 2017 17:46:09 -0700
+Patch-mainline: v4.14-rc1
+Subject: netvsc: remove unnecessary cast of void pointer
+Git-commit: 00f5024e821e60c0d1d7df44f2577a2c277b5cc9
+References: fate#323887
+
+Assignment to a typed pointer is sufficient in C.
+No cast is needed.
+
+Signed-off-by: Stephen Hemminger <sthemmin@microsoft.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Acked-by: Olaf Hering <ohering@suse.de>
+---
+ drivers/net/hyperv/netvsc_drv.c | 9 ++++-----
+ 1 file changed, 4 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
+--- a/drivers/net/hyperv/netvsc_drv.c
++++ b/drivers/net/hyperv/netvsc_drv.c
+@@ -523,9 +523,9 @@ static int netvsc_start_xmit(struct sk_buff *skb, struct net_device *net)
+
+ rndis_msg_size += NDIS_VLAN_PPI_SIZE;
+ ppi = init_ppi_data(rndis_msg, NDIS_VLAN_PPI_SIZE,
+- IEEE_8021Q_INFO);
+- vlan = (struct ndis_pkt_8021q_info *)((void *)ppi +
+- ppi->ppi_offset);
++ IEEE_8021Q_INFO);
++
++ vlan = (void *)ppi + ppi->ppi_offset;
+ vlan->vlanid = skb->vlan_tci & VLAN_VID_MASK;
+ vlan->pri = (skb->vlan_tci & VLAN_PRIO_MASK) >>
+ VLAN_PRIO_SHIFT;
+@@ -538,8 +538,7 @@ static int netvsc_start_xmit(struct sk_buff *skb, struct net_device *net)
+ ppi = init_ppi_data(rndis_msg, NDIS_LSO_PPI_SIZE,
+ TCP_LARGESEND_PKTINFO);
+
+- lso_info = (struct ndis_tcp_lso_info *)((void *)ppi +
+- ppi->ppi_offset);
++ lso_info = (void *)ppi + ppi->ppi_offset;
+
+ lso_info->lso_v2_transmit.type = NDIS_TCP_LARGE_SEND_OFFLOAD_V2_TYPE;
+ if (skb->protocol == htons(ETH_P_IP)) {
diff --git a/patches.suse/msft-hv-1432-netvsc-remove-unnecessary-check-for-NULL-hdr.patch b/patches.suse/msft-hv-1432-netvsc-remove-unnecessary-check-for-NULL-hdr.patch
new file mode 100644
index 0000000000..376cef756e
--- /dev/null
+++ b/patches.suse/msft-hv-1432-netvsc-remove-unnecessary-check-for-NULL-hdr.patch
@@ -0,0 +1,34 @@
+From: stephen hemminger <stephen@networkplumber.org>
+Date: Wed, 9 Aug 2017 17:46:10 -0700
+Patch-mainline: v4.14-rc1
+Subject: netvsc: remove unnecessary check for NULL hdr
+Git-commit: ea5a32c00bcacce1d8ac834a70a82f95a1c79425
+References: fate#323887
+
+The function init_page_array is always called with a valid pointer
+to RNDIS header. No check for NULL is needed.
+
+Signed-off-by: Stephen Hemminger <sthemmin@microsoft.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Acked-by: Olaf Hering <ohering@suse.de>
+---
+ drivers/net/hyperv/netvsc_drv.c | 7 +++----
+ 1 file changed, 3 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
+--- a/drivers/net/hyperv/netvsc_drv.c
++++ b/drivers/net/hyperv/netvsc_drv.c
+@@ -333,10 +333,9 @@ static u32 init_page_array(void *hdr, u32 len, struct sk_buff *skb,
+ * 2. skb linear data
+ * 3. skb fragment data
+ */
+- if (hdr != NULL)
+- slots_used += fill_pg_buf(virt_to_page(hdr),
+- offset_in_page(hdr),
+- len, &pb[slots_used]);
++ slots_used += fill_pg_buf(virt_to_page(hdr),
++ offset_in_page(hdr),
++ len, &pb[slots_used]);
+
+ packet->rmsg_size = len;
+ packet->rmsg_pgcnt = slots_used;
diff --git a/patches.suse/msft-hv-1433-netvsc-allow-controlling-send-recv-buffer-size.patch b/patches.suse/msft-hv-1433-netvsc-allow-controlling-send-recv-buffer-size.patch
new file mode 100644
index 0000000000..5c5fe94fd9
--- /dev/null
+++ b/patches.suse/msft-hv-1433-netvsc-allow-controlling-send-recv-buffer-size.patch
@@ -0,0 +1,412 @@
+From: stephen hemminger <stephen@networkplumber.org>
+Date: Wed, 9 Aug 2017 17:46:11 -0700
+Patch-mainline: v4.14-rc1
+Subject: netvsc: allow controlling send/recv buffer size
+Git-commit: 8b5327975ae171ca54dfd93e6c042d1292945867
+References: fate#323887
+
+Control the size of the buffer areas via ethtool ring settings.
+They aren't really traditional hardware rings, but host API breaks
+receive and send buffer into chunks. The final size of the chunks are
+controlled by the host.
+
+The default value of send and receive buffer area for host DMA
+is much larger than it needs to be. Experimentation shows that
+4M receive and 1M send is sufficient.
+
+Signed-off-by: Stephen Hemminger <sthemmin@microsoft.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Acked-by: Olaf Hering <ohering@suse.de>
+---
+ drivers/net/hyperv/hyperv_net.h | 9 ++--
+ drivers/net/hyperv/netvsc.c | 70 +++++++++++++-----------
+ drivers/net/hyperv/netvsc_drv.c | 117 ++++++++++++++++++++++++++++++++++++++--
+ 3 files changed, 157 insertions(+), 39 deletions(-)
+
+diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h
+--- a/drivers/net/hyperv/hyperv_net.h
++++ b/drivers/net/hyperv/hyperv_net.h
+@@ -148,6 +148,8 @@ struct netvsc_device_info {
+ unsigned char mac_adr[ETH_ALEN];
+ int ring_size;
+ u32 num_chn;
++ u32 send_sections;
++ u32 recv_sections;
+ };
+
+ enum rndis_device_state {
+@@ -634,12 +636,12 @@ struct nvsp_message {
+ #define NETVSC_SEND_BUFFER_SIZE (1024 * 1024 * 15) /* 15MB */
+ #define NETVSC_INVALID_INDEX -1
+
++#define NETVSC_SEND_SECTION_SIZE 6144
++#define NETVSC_RECV_SECTION_SIZE 1728
+
+ #define NETVSC_RECEIVE_BUFFER_ID 0xcafe
+ #define NETVSC_SEND_BUFFER_ID 0
+
+-#define NETVSC_PACKET_SIZE 4096
+-
+ #define VRSS_SEND_TAB_SIZE 16 /* must be power of 2 */
+ #define VRSS_CHANNEL_MAX 64
+ #define VRSS_CHANNEL_DEFAULT 8
+@@ -754,14 +756,13 @@ struct netvsc_device {
+
+ /* Receive buffer allocated by us but manages by NetVSP */
+ void *recv_buf;
+- u32 recv_buf_size;
+ u32 recv_buf_gpadl_handle;
+ u32 recv_section_cnt;
++ u32 recv_section_size;
+ u32 recv_completion_cnt;
+
+ /* Send buffer allocated by us */
+ void *send_buf;
+- u32 send_buf_size;
+ u32 send_buf_gpadl_handle;
+ u32 send_section_cnt;
+ u32 send_section_size;
+diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c
+--- a/drivers/net/hyperv/netvsc.c
++++ b/drivers/net/hyperv/netvsc.c
+@@ -75,6 +75,10 @@ static struct netvsc_device *alloc_net_device(void)
+ atomic_set(&net_device->open_cnt, 0);
+ net_device->max_pkt = RNDIS_MAX_PKT_DEFAULT;
+ net_device->pkt_align = RNDIS_PKT_ALIGN_DEFAULT;
++
++ net_device->recv_section_size = NETVSC_RECV_SECTION_SIZE;
++ net_device->send_section_size = NETVSC_SEND_SECTION_SIZE;
++
+ init_completion(&net_device->channel_init_wait);
+ init_waitqueue_head(&net_device->subchan_open);
+
+@@ -143,6 +147,7 @@ static void netvsc_destroy_buf(struct hv_device *device)
+ "revoke receive buffer to netvsp\n");
+ return;
+ }
++ net_device->recv_section_cnt = 0;
+ }
+
+ /* Teardown the gpadl on the vsp end */
+@@ -173,7 +178,7 @@ static void netvsc_destroy_buf(struct hv_device *device)
+ * NVSP_MSG1_TYPE_SEND_SEND_BUF msg) therefore, we need
+ * to send a revoke msg here
+ */
+- if (net_device->send_section_size) {
++ if (net_device->send_section_cnt) {
+ /* Send the revoke receive buffer */
+ revoke_packet = &net_device->revoke_packet;
+ memset(revoke_packet, 0, sizeof(struct nvsp_message));
+@@ -205,6 +210,7 @@ static void netvsc_destroy_buf(struct hv_device *device)
+ "revoke send buffer to netvsp\n");
+ return;
+ }
++ net_device->send_section_cnt = 0;
+ }
+ /* Teardown the gpadl on the vsp end */
+ if (net_device->send_buf_gpadl_handle) {
+@@ -244,18 +250,25 @@ int netvsc_alloc_recv_comp_ring(struct netvsc_device *net_device, u32 q_idx)
+ }
+
+ static int netvsc_init_buf(struct hv_device *device,
+- struct netvsc_device *net_device)
++ struct netvsc_device *net_device,
++ const struct netvsc_device_info *device_info)
+ {
+ struct nvsp_1_message_send_receive_buffer_complete *resp;
+ struct net_device *ndev = hv_get_drvdata(device);
+ struct nvsp_message *init_packet;
++ unsigned int buf_size;
+ size_t map_words;
+ int ret = 0;
+
+- net_device->recv_buf = vzalloc(net_device->recv_buf_size);
++ /* Get receive buffer area. */
++ buf_size = device_info->recv_sections * net_device->recv_section_size;
++ buf_size = roundup(buf_size, PAGE_SIZE);
++
++ net_device->recv_buf = vzalloc(buf_size);
+ if (!net_device->recv_buf) {
+- netdev_err(ndev, "unable to allocate receive "
+- "buffer of size %d\n", net_device->recv_buf_size);
++ netdev_err(ndev,
++ "unable to allocate receive buffer of size %u\n",
++ buf_size);
+ ret = -ENOMEM;
+ goto cleanup;
+ }
+@@ -266,7 +279,7 @@ static int netvsc_init_buf(struct hv_device *device,
+ * than the channel to establish the gpadl handle.
+ */
+ ret = vmbus_establish_gpadl(device->channel, net_device->recv_buf,
+- net_device->recv_buf_size,
++ buf_size,
+ &net_device->recv_buf_gpadl_handle);
+ if (ret != 0) {
+ netdev_err(ndev,
+@@ -312,31 +325,31 @@ static int netvsc_init_buf(struct hv_device *device,
+ resp->num_sections, resp->sections[0].sub_alloc_size,
+ resp->sections[0].num_sub_allocs);
+
+- net_device->recv_section_cnt = resp->num_sections;
+-
+- /*
+- * For 1st release, there should only be 1 section that represents the
+- * entire receive buffer
+- */
+- if (net_device->recv_section_cnt != 1 ||
+- resp->sections[0].offset != 0) {
++ /* There should only be one section for the entire receive buffer */
++ if (resp->num_sections != 1 || resp->sections[0].offset != 0) {
+ ret = -EINVAL;
+ goto cleanup;
+ }
+
++ net_device->recv_section_size = resp->sections[0].sub_alloc_size;
++ net_device->recv_section_cnt = resp->sections[0].num_sub_allocs;
++
+ /* Setup receive completion ring */
+ net_device->recv_completion_cnt
+- = round_up(resp->sections[0].num_sub_allocs + 1,
++ = round_up(net_device->recv_section_cnt + 1,
+ PAGE_SIZE / sizeof(u64));
+ ret = netvsc_alloc_recv_comp_ring(net_device, 0);
+ if (ret)
+ goto cleanup;
+
+ /* Now setup the send buffer. */
+- net_device->send_buf = vzalloc(net_device->send_buf_size);
++ buf_size = device_info->send_sections * net_device->send_section_size;
++ buf_size = round_up(buf_size, PAGE_SIZE);
++
++ net_device->send_buf = vzalloc(buf_size);
+ if (!net_device->send_buf) {
+- netdev_err(ndev, "unable to allocate send "
+- "buffer of size %d\n", net_device->send_buf_size);
++ netdev_err(ndev, "unable to allocate send buffer of size %u\n",
++ buf_size);
+ ret = -ENOMEM;
+ goto cleanup;
+ }
+@@ -346,7 +359,7 @@ static int netvsc_init_buf(struct hv_device *device,
+ * than the channel to establish the gpadl handle.
+ */
+ ret = vmbus_establish_gpadl(device->channel, net_device->send_buf,
+- net_device->send_buf_size,
++ buf_size,
+ &net_device->send_buf_gpadl_handle);
+ if (ret != 0) {
+ netdev_err(ndev,
+@@ -391,10 +404,8 @@ static int netvsc_init_buf(struct hv_device *device,
+ net_device->send_section_size = init_packet->msg.
+ v1_msg.send_send_buf_complete.section_size;
+
+- /* Section count is simply the size divided by the section size.
+- */
+- net_device->send_section_cnt =
+- net_device->send_buf_size / net_device->send_section_size;
++ /* Section count is simply the size divided by the section size. */
++ net_device->send_section_cnt = buf_size / net_device->send_section_size;
+
+ netdev_dbg(ndev, "Send section size: %d, Section count:%d\n",
+ net_device->send_section_size, net_device->send_section_cnt);
+@@ -472,7 +483,8 @@ static int negotiate_nvsp_ver(struct hv_device *device,
+ }
+
+ static int netvsc_connect_vsp(struct hv_device *device,
+- struct netvsc_device *net_device)
++ struct netvsc_device *net_device,
++ const struct netvsc_device_info *device_info)
+ {
+ const u32 ver_list[] = {
+ NVSP_PROTOCOL_VERSION_1, NVSP_PROTOCOL_VERSION_2,
+@@ -522,14 +534,8 @@ static int netvsc_connect_vsp(struct hv_device *device,
+ if (ret != 0)
+ goto cleanup;
+
+- /* Post the big receive buffer to NetVSP */
+- if (net_device->nvsp_version <= NVSP_PROTOCOL_VERSION_2)
+- net_device->recv_buf_size = NETVSC_RECEIVE_BUFFER_SIZE_LEGACY;
+- else
+- net_device->recv_buf_size = NETVSC_RECEIVE_BUFFER_SIZE;
+- net_device->send_buf_size = NETVSC_SEND_BUFFER_SIZE;
+
+- ret = netvsc_init_buf(device, net_device);
++ ret = netvsc_init_buf(device, net_device, device_info);
+
+ cleanup:
+ return ret;
+@@ -1287,7 +1293,7 @@ struct netvsc_device *netvsc_device_add(struct hv_device *device,
+ rcu_assign_pointer(net_device_ctx->nvdev, net_device);
+
+ /* Connect with the NetVsp */
+- ret = netvsc_connect_vsp(device, net_device);
++ ret = netvsc_connect_vsp(device, net_device, device_info);
+ if (ret != 0) {
+ netdev_err(ndev,
+ "unable to connect to NetVSP - %d\n", ret);
+diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
+--- a/drivers/net/hyperv/netvsc_drv.c
++++ b/drivers/net/hyperv/netvsc_drv.c
+@@ -45,7 +45,12 @@
+
+ #include "hyperv_net.h"
+
+-#define RING_SIZE_MIN 64
++#define RING_SIZE_MIN 64
++#define NETVSC_MIN_TX_SECTIONS 10
++#define NETVSC_DEFAULT_TX 192 /* ~1M */
++#define NETVSC_MIN_RX_SECTIONS 10 /* ~64K */
++#define NETVSC_DEFAULT_RX 2048 /* ~4M */
++
+ #define LINKCHANGE_INT (2 * HZ)
+ #define VF_TAKEOVER_INT (HZ / 10)
+
+@@ -831,11 +836,13 @@ static int netvsc_set_channels(struct net_device *net,
+ if (was_opened)
+ rndis_filter_close(nvdev);
+
+- rndis_filter_device_remove(dev, nvdev);
+-
+ memset(&device_info, 0, sizeof(device_info));
+ device_info.num_chn = count;
+ device_info.ring_size = ring_size;
++ device_info.send_sections = nvdev->send_section_cnt;
++ device_info.recv_sections = nvdev->recv_section_cnt;
++
++ rndis_filter_device_remove(dev, nvdev);
+
+ nvdev = rndis_filter_device_add(dev, &device_info);
+ if (!IS_ERR(nvdev)) {
+@@ -947,6 +954,8 @@ static int netvsc_change_mtu(struct net_device *ndev, int mtu)
+ memset(&device_info, 0, sizeof(device_info));
+ device_info.ring_size = ring_size;
+ device_info.num_chn = nvdev->num_chn;
++ device_info.send_sections = nvdev->send_section_cnt;
++ device_info.recv_sections = nvdev->recv_section_cnt;
+
+ rndis_filter_device_remove(hdev, nvdev);
+
+@@ -1351,6 +1360,104 @@ static int netvsc_set_rxfh(struct net_device *dev, const u32 *indir,
+ return rndis_filter_set_rss_param(rndis_dev, key, ndev->num_chn);
+ }
+
++/* Hyper-V RNDIS protocol does not have ring in the HW sense.
++ * It does have pre-allocated receive area which is divided into sections.
++ */
++static void __netvsc_get_ringparam(struct netvsc_device *nvdev,
++ struct ethtool_ringparam *ring)
++{
++ u32 max_buf_size;
++
++ ring->rx_pending = nvdev->recv_section_cnt;
++ ring->tx_pending = nvdev->send_section_cnt;
++
++ if (nvdev->nvsp_version <= NVSP_PROTOCOL_VERSION_2)
++ max_buf_size = NETVSC_RECEIVE_BUFFER_SIZE_LEGACY;
++ else
++ max_buf_size = NETVSC_RECEIVE_BUFFER_SIZE;
++
++ ring->rx_max_pending = max_buf_size / nvdev->recv_section_size;
++ ring->tx_max_pending = NETVSC_SEND_BUFFER_SIZE
++ / nvdev->send_section_size;
++}
++
++static void netvsc_get_ringparam(struct net_device *ndev,
++ struct ethtool_ringparam *ring)
++{
++ struct net_device_context *ndevctx = netdev_priv(ndev);
++ struct netvsc_device *nvdev = rtnl_dereference(ndevctx->nvdev);
++
++ if (!nvdev)
++ return;
++
++ __netvsc_get_ringparam(nvdev, ring);
++}
++
++static int netvsc_set_ringparam(struct net_device *ndev,
++ struct ethtool_ringparam *ring)
++{
++ struct net_device_context *ndevctx = netdev_priv(ndev);
++ struct netvsc_device *nvdev = rtnl_dereference(ndevctx->nvdev);
++ struct hv_device *hdev = ndevctx->device_ctx;
++ struct netvsc_device_info device_info;
++ struct ethtool_ringparam orig;
++ u32 new_tx, new_rx;
++ bool was_opened;
++ int ret = 0;
++
++ if (!nvdev || nvdev->destroy)
++ return -ENODEV;
++
++ memset(&orig, 0, sizeof(orig));
++ __netvsc_get_ringparam(nvdev, &orig);
++
++ new_tx = clamp_t(u32, ring->tx_pending,
++ NETVSC_MIN_TX_SECTIONS, orig.tx_max_pending);
++ new_rx = clamp_t(u32, ring->rx_pending,
++ NETVSC_MIN_RX_SECTIONS, orig.rx_max_pending);
++
++ if (new_tx == orig.tx_pending &&
++ new_rx == orig.rx_pending)
++ return 0; /* no change */
++
++ memset(&device_info, 0, sizeof(device_info));
++ device_info.num_chn = nvdev->num_chn;
++ device_info.ring_size = ring_size;
++ device_info.send_sections = new_tx;
++ device_info.recv_sections = new_rx;
++
++ netif_device_detach(ndev);
++ was_opened = rndis_filter_opened(nvdev);
++ if (was_opened)
++ rndis_filter_close(nvdev);
++
++ rndis_filter_device_remove(hdev, nvdev);
++
++ nvdev = rndis_filter_device_add(hdev, &device_info);
++ if (IS_ERR(nvdev)) {
++ ret = PTR_ERR(nvdev);
++
++ device_info.send_sections = orig.tx_pending;
++ device_info.recv_sections = orig.rx_pending;
++ nvdev = rndis_filter_device_add(hdev, &device_info);
++ if (IS_ERR(nvdev)) {
++ netdev_err(ndev, "restoring ringparam failed: %ld\n",
++ PTR_ERR(nvdev));
++ return ret;
++ }
++ }
++
++ if (was_opened)
++ rndis_filter_open(nvdev);
++ netif_device_attach(ndev);
++
++ /* We may have missed link change notifications */
++ ndevctx->last_reconfig = 0;
++ schedule_delayed_work(&ndevctx->dwork, 0);
++
++ return ret;
++}
++
+ static const struct ethtool_ops ethtool_ops = {
+ .get_drvinfo = netvsc_get_drvinfo,
+ .get_link = ethtool_op_get_link,
+@@ -1367,6 +1474,8 @@ static const struct ethtool_ops ethtool_ops = {
+ .set_rxfh = netvsc_set_rxfh,
+ .get_link_ksettings = netvsc_get_link_ksettings,
+ .set_link_ksettings = netvsc_set_link_ksettings,
++ .get_ringparam = netvsc_get_ringparam,
++ .set_ringparam = netvsc_set_ringparam,
+ };
+
+ static const struct net_device_ops device_ops = {
+@@ -1782,6 +1891,8 @@ static int netvsc_probe(struct hv_device *dev,
+ memset(&device_info, 0, sizeof(device_info));
+ device_info.ring_size = ring_size;
+ device_info.num_chn = VRSS_CHANNEL_DEFAULT;
++ device_info.send_sections = NETVSC_DEFAULT_TX;
++ device_info.recv_sections = NETVSC_DEFAULT_RX;
+
+ nvdev = rndis_filter_device_add(dev, &device_info);
+ if (IS_ERR(nvdev)) {
diff --git a/patches.suse/msft-hv-1434-netvsc-keep-track-of-some-non-fatal-overload-conditi.patch b/patches.suse/msft-hv-1434-netvsc-keep-track-of-some-non-fatal-overload-conditi.patch
new file mode 100644
index 0000000000..48818b8cf1
--- /dev/null
+++ b/patches.suse/msft-hv-1434-netvsc-keep-track-of-some-non-fatal-overload-conditi.patch
@@ -0,0 +1,104 @@
+From: stephen hemminger <stephen@networkplumber.org>
+Date: Wed, 9 Aug 2017 17:46:12 -0700
+Patch-mainline: v4.14-rc1
+Subject: netvsc: keep track of some non-fatal overload conditions
+Git-commit: cad5c197704d82faf33ffdbef414f15db08d9ef9
+References: fate#323887
+
+Add ethtool statistics for case where send chimmeny buffer is
+exhausted and driver has to fall back to doing scatter/gather
+send. Also, add statistic for case where ring buffer is full and
+receive completions are delayed.
+
+Signed-off-by: Stephen Hemminger <sthemmin@microsoft.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Acked-by: Olaf Hering <ohering@suse.de>
+---
+ drivers/net/hyperv/hyperv_net.h | 2 ++
+ drivers/net/hyperv/netvsc.c | 19 +++++++++++++------
+ drivers/net/hyperv/netvsc_drv.c | 2 ++
+ 3 files changed, 17 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h
+--- a/drivers/net/hyperv/hyperv_net.h
++++ b/drivers/net/hyperv/hyperv_net.h
+@@ -680,6 +680,8 @@ struct netvsc_ethtool_stats {
+ unsigned long tx_no_space;
+ unsigned long tx_too_big;
+ unsigned long tx_busy;
++ unsigned long tx_send_full;
++ unsigned long rx_comp_busy;
+ };
+
+ struct netvsc_vf_pcpu_stats {
+diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c
+--- a/drivers/net/hyperv/netvsc.c
++++ b/drivers/net/hyperv/netvsc.c
+@@ -883,7 +883,9 @@ int netvsc_send(struct net_device_context *ndev_ctx,
+ } else if (pktlen + net_device->pkt_align <
+ net_device->send_section_size) {
+ section_index = netvsc_get_next_send_section(net_device);
+- if (section_index != NETVSC_INVALID_INDEX) {
++ if (unlikely(section_index == NETVSC_INVALID_INDEX)) {
++ ++ndev_ctx->eth_stats.tx_send_full;
++ } else {
+ move_pkt_msd(&msd_send, &msd_skb, msdp);
+ msd_len = 0;
+ }
+@@ -949,9 +951,10 @@ send_now:
+ }
+
+ /* Send pending recv completions */
+-static int send_recv_completions(struct netvsc_channel *nvchan)
++static int send_recv_completions(struct net_device *ndev,
++ struct netvsc_device *nvdev,
++ struct netvsc_channel *nvchan)
+ {
+- struct netvsc_device *nvdev = nvchan->net_device;
+ struct multi_recv_comp *mrc = &nvchan->mrc;
+ struct recv_comp_msg {
+ struct nvsp_message_header hdr;
+@@ -969,8 +972,12 @@ static int send_recv_completions(struct netvsc_channel *nvchan)
+ msg.status = rcd->status;
+ ret = vmbus_sendpacket(nvchan->channel, &msg, sizeof(msg),
+ rcd->tid, VM_PKT_COMP, 0);
+- if (unlikely(ret))
++ if (unlikely(ret)) {
++ struct net_device_context *ndev_ctx = netdev_priv(ndev);
++
++ ++ndev_ctx->eth_stats.rx_comp_busy;
+ return ret;
++ }
+
+ if (++mrc->first == nvdev->recv_completion_cnt)
+ mrc->first = 0;
+@@ -1011,7 +1018,7 @@ static void enq_receive_complete(struct net_device *ndev,
+ recv_comp_slot_avail(nvdev, mrc, &filled, &avail);
+
+ if (unlikely(filled > NAPI_POLL_WEIGHT)) {
+- send_recv_completions(nvchan);
++ send_recv_completions(ndev, nvdev, nvchan);
+ recv_comp_slot_avail(nvdev, mrc, &filled, &avail);
+ }
+
+@@ -1194,7 +1201,7 @@ int netvsc_poll(struct napi_struct *napi, int budget)
+ * then re-enable host interrupts
+ * and reschedule if ring is not empty.
+ */
+- if (send_recv_completions(nvchan) == 0 &&
++ if (send_recv_completions(ndev, net_device, nvchan) == 0 &&
+ work_done < budget &&
+ napi_complete_done(napi, work_done) &&
+ hv_end_read(&channel->inbound)) {
+diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
+--- a/drivers/net/hyperv/netvsc_drv.c
++++ b/drivers/net/hyperv/netvsc_drv.c
+@@ -1112,6 +1112,8 @@ static const struct {
+ { "tx_no_space", offsetof(struct netvsc_ethtool_stats, tx_no_space) },
+ { "tx_too_big", offsetof(struct netvsc_ethtool_stats, tx_too_big) },
+ { "tx_busy", offsetof(struct netvsc_ethtool_stats, tx_busy) },
++ { "tx_send_full", offsetof(struct netvsc_ethtool_stats, tx_send_full) },
++ { "rx_comp_busy", offsetof(struct netvsc_ethtool_stats, rx_comp_busy) },
+ }, vf_stats[] = {
+ { "vf_rx_packets", offsetof(struct netvsc_vf_pcpu_stats, rx_packets) },
+ { "vf_rx_bytes", offsetof(struct netvsc_vf_pcpu_stats, rx_bytes) },
diff --git a/patches.suse/msft-hv-1435-Tools-hv-vss-Skip-freezing-filesystems-backed-by-loo.patch b/patches.suse/msft-hv-1435-Tools-hv-vss-Skip-freezing-filesystems-backed-by-loo.patch
new file mode 100644
index 0000000000..84c749bc7c
--- /dev/null
+++ b/patches.suse/msft-hv-1435-Tools-hv-vss-Skip-freezing-filesystems-backed-by-loo.patch
@@ -0,0 +1,63 @@
+From: Alex Ng <alexng@messages.microsoft.com>
+Date: Sun, 6 Aug 2017 13:12:52 -0700
+Patch-mainline: v4.14-rc1
+Subject: Tools: hv: vss: Skip freezing filesystems backed by loop
+Git-commit: ea81fdf0981d9a4a998a015d325bed67624811f7
+References: fate#323887
+
+Since a loop device is backed by a file, a backup will already result in
+its parent filesystem being frozen. It's sufficient to just freeze the
+parent filesystem, so we can skip the loop device.
+
+This avoids a situation where a loop device and its parent filesystem are
+both frozen and then thawed out of order. For example, if the loop device
+is enumerated first, we would thaw it while its parent filesystem is still
+frozen. The thaw operation fails and the loop device remains frozen.
+
+Signed-off-by: Alex Ng <alexng@messages.microsoft.com>
+Signed-off-by: Vyronas Tsingaras <vyronas@vtsingaras.me>
+Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Acked-by: Olaf Hering <ohering@suse.de>
+---
+ tools/hv/hv_vss_daemon.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/tools/hv/hv_vss_daemon.c b/tools/hv/hv_vss_daemon.c
+--- a/tools/hv/hv_vss_daemon.c
++++ b/tools/hv/hv_vss_daemon.c
+@@ -21,6 +21,7 @@
+ #include <sys/types.h>
+ #include <sys/poll.h>
+ #include <sys/ioctl.h>
++#include <sys/stat.h>
+ #include <fcntl.h>
+ #include <stdio.h>
+ #include <mntent.h>
+@@ -30,6 +31,7 @@
+ #include <ctype.h>
+ #include <errno.h>
+ #include <linux/fs.h>
++#include <linux/major.h>
+ #include <linux/hyperv.h>
+ #include <syslog.h>
+ #include <getopt.h>
+@@ -70,6 +72,7 @@ static int vss_operate(int operation)
+ char match[] = "/dev/";
+ FILE *mounts;
+ struct mntent *ent;
++ struct stat sb;
+ char errdir[1024] = {0};
+ unsigned int cmd;
+ int error = 0, root_seen = 0, save_errno = 0;
+@@ -92,6 +95,10 @@ static int vss_operate(int operation)
+ while ((ent = getmntent(mounts))) {
+ if (strncmp(ent->mnt_fsname, match, strlen(match)))
+ continue;
++ if (stat(ent->mnt_fsname, &sb) == -1)
++ continue;
++ if (S_ISBLK(sb.st_mode) && major(sb.st_rdev) == LOOP_MAJOR)
++ continue;
+ if (hasmntopt(ent, MNTOPT_RO) != NULL)
+ continue;
+ if (strcmp(ent->mnt_type, "vfat") == 0)
diff --git a/patches.suse/msft-hv-1436-Drivers-hv-balloon-Correctly-update-onlined-page-cou.patch b/patches.suse/msft-hv-1436-Drivers-hv-balloon-Correctly-update-onlined-page-cou.patch
new file mode 100644
index 0000000000..5fda7de3a7
--- /dev/null
+++ b/patches.suse/msft-hv-1436-Drivers-hv-balloon-Correctly-update-onlined-page-cou.patch
@@ -0,0 +1,45 @@
+From: Alex Ng <alexng@messages.microsoft.com>
+Date: Sun, 6 Aug 2017 13:12:53 -0700
+Patch-mainline: v4.14-rc1
+Subject: Drivers: hv: balloon: Correctly update onlined page count
+Git-commit: 6df8d9aaf3afe25aacf20c69022a4c6d57b77a95
+References: fate#323887
+
+Previously, num_pages_onlined was updated using value from memory online
+notifier. This is incorrect because they assume that all hot-added pages
+are online, even though we only online the amount that's backed by the
+host. We should update num_pages_onlined only when the balloon driver
+marks a page as online.
+
+Signed-off-by: Alex Ng <alexng@messages.microsoft.com>
+Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Acked-by: Olaf Hering <ohering@suse.de>
+---
+ drivers/hv/hv_balloon.c | 7 +++----
+ 1 file changed, 3 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/hv/hv_balloon.c b/drivers/hv/hv_balloon.c
+--- a/drivers/hv/hv_balloon.c
++++ b/drivers/hv/hv_balloon.c
+@@ -584,10 +584,6 @@ static int hv_memory_notifier(struct notifier_block *nb, unsigned long val,
+
+ switch (val) {
+ case MEM_ONLINE:
+- spin_lock_irqsave(&dm_device.ha_lock, flags);
+- dm_device.num_pages_onlined += mem->nr_pages;
+- spin_unlock_irqrestore(&dm_device.ha_lock, flags);
+- /* Fall through */
+ case MEM_CANCEL_ONLINE:
+ if (dm_device.ha_waiting) {
+ dm_device.ha_waiting = false;
+@@ -644,6 +640,9 @@ static void hv_page_online_one(struct hv_hotadd_state *has, struct page *pg)
+ __online_page_set_limits(pg);
+ __online_page_increment_counters(pg);
+ __online_page_free(pg);
++
++ WARN_ON_ONCE(!spin_is_locked(&dm_device.ha_lock));
++ dm_device.num_pages_onlined++;
+ }
+
+ static void hv_bring_pgs_online(struct hv_hotadd_state *has,
diff --git a/patches.suse/msft-hv-1437-Drivers-hv-balloon-Show-the-max-dynamic-memory-assig.patch b/patches.suse/msft-hv-1437-Drivers-hv-balloon-Show-the-max-dynamic-memory-assig.patch
new file mode 100644
index 0000000000..d31d96eb96
--- /dev/null
+++ b/patches.suse/msft-hv-1437-Drivers-hv-balloon-Show-the-max-dynamic-memory-assig.patch
@@ -0,0 +1,33 @@
+From: Alex Ng <alexng@messages.microsoft.com>
+Date: Sun, 6 Aug 2017 13:12:54 -0700
+Patch-mainline: v4.14-rc1
+Subject: Drivers: hv: balloon: Show the max dynamic memory assigned
+Git-commit: 7b6e54b524b66b60e4cf49e8aa7c43045ebb987d
+References: fate#323887
+
+Previously we were only showing max number of pages. We should make it
+more clear that this value is the max amount of dynamic memory that the
+Hyper-V host is willing to assign to this guest.
+
+Signed-off-by: Alex Ng <alexng@messages.microsoft.com>
+Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Acked-by: Olaf Hering <ohering@suse.de>
+---
+ drivers/hv/hv_balloon.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/hv/hv_balloon.c b/drivers/hv/hv_balloon.c
+--- a/drivers/hv/hv_balloon.c
++++ b/drivers/hv/hv_balloon.c
+@@ -1035,8 +1035,8 @@ static void process_info(struct hv_dynmem_device *dm, struct dm_info_msg *msg)
+ if (info_hdr->data_size == sizeof(__u64)) {
+ __u64 *max_page_count = (__u64 *)&info_hdr[1];
+
+- pr_info("INFO_TYPE_MAX_PAGE_CNT = %llu\n",
+- *max_page_count);
++ pr_info("Max. dynamic memory size: %llu MB\n",
++ (*max_page_count) >> (20 - PAGE_SHIFT));
+ }
+
+ break;
diff --git a/patches.suse/msft-hv-1438-Drivers-hv-balloon-Initialize-last_post_time-on-star.patch b/patches.suse/msft-hv-1438-Drivers-hv-balloon-Initialize-last_post_time-on-star.patch
new file mode 100644
index 0000000000..44e1776bcd
--- /dev/null
+++ b/patches.suse/msft-hv-1438-Drivers-hv-balloon-Initialize-last_post_time-on-star.patch
@@ -0,0 +1,36 @@
+From: Alex Ng <alexng@messages.microsoft.com>
+Date: Sun, 6 Aug 2017 13:12:55 -0700
+Patch-mainline: v4.14-rc1
+Subject: Drivers: hv: balloon: Initialize last_post_time on startup
+Git-commit: c548f3957efa57b6f1a1f4c90013232f6f488682
+References: fate#323887
+
+When left uninitialized, this sometimes fails the following check in
+post_status():
+
+ if (!time_after(now, (last_post_time + HZ))) {
+ return;
+ }
+
+This causes unnecessary delays in reporting memory pressure to host after
+booting up.
+
+Signed-off-by: Alex Ng <alexng@messages.microsoft.com>
+Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Acked-by: Olaf Hering <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
+--- a/drivers/hv/hv_balloon.c
++++ b/drivers/hv/hv_balloon.c
+@@ -1655,6 +1655,7 @@ static int balloon_probe(struct hv_device *dev,
+ }
+
+ dm_device.state = DM_INITIALIZED;
++ last_post_time = jiffies;
+
+ return 0;
+
diff --git a/patches.suse/msft-hv-1439-Drivers-hv-kvp-Use-MAX_ADAPTER_ID_SIZE-for-translati.patch b/patches.suse/msft-hv-1439-Drivers-hv-kvp-Use-MAX_ADAPTER_ID_SIZE-for-translati.patch
new file mode 100644
index 0000000000..ea8f7e6e02
--- /dev/null
+++ b/patches.suse/msft-hv-1439-Drivers-hv-kvp-Use-MAX_ADAPTER_ID_SIZE-for-translati.patch
@@ -0,0 +1,35 @@
+From: Alex Ng <alexng@messages.microsoft.com>
+Date: Sun, 6 Aug 2017 13:12:56 -0700
+Patch-mainline: v4.14-rc1
+Subject: Drivers: hv: kvp: Use MAX_ADAPTER_ID_SIZE for translating adapter id
+Git-commit: ddce54b6a95ed5ee3011b4771fda69c2d8a6d538
+References: fate#323887
+
+There's a bug which passes the output buffer size as MAX_IP_ADDR_SIZE,
+when converting the adapter_id field to UTF16. This is much larger than
+the actual size (MAX_ADAPTER_ID_SIZE). Fix this by passing the proper
+size.
+
+Fortunately, the translation is limited by the length of the input. This
+explains why we haven't seen output buffer overflow conditions.
+
+Signed-off-by: Alex Ng <alexng@messages.microsoft.com>
+Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Acked-by: Olaf Hering <ohering@suse.de>
+---
+ drivers/hv/hv_kvp.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/hv/hv_kvp.c b/drivers/hv/hv_kvp.c
+--- a/drivers/hv/hv_kvp.c
++++ b/drivers/hv/hv_kvp.c
+@@ -304,7 +304,7 @@ static int process_ob_ipinfo(void *in_msg, void *out_msg, int op)
+ strlen((char *)in->body.kvp_ip_val.adapter_id),
+ UTF16_HOST_ENDIAN,
+ (wchar_t *)out->kvp_ip_val.adapter_id,
+- MAX_IP_ADDR_SIZE);
++ MAX_ADAPTER_ID_SIZE);
+ if (len < 0)
+ return len;
+
diff --git a/patches.suse/msft-hv-1440-Tools-hv-fix-snprintf-warning-in-kvp_daemon.patch b/patches.suse/msft-hv-1440-Tools-hv-fix-snprintf-warning-in-kvp_daemon.patch
new file mode 100644
index 0000000000..df097a7273
--- /dev/null
+++ b/patches.suse/msft-hv-1440-Tools-hv-fix-snprintf-warning-in-kvp_daemon.patch
@@ -0,0 +1,30 @@
+From: Olaf Hering <olaf@aepfle.de>
+Date: Thu, 10 Aug 2017 15:45:15 -0700
+Patch-mainline: v4.14-rc1
+Subject: Tools: hv: fix snprintf warning in kvp_daemon
+Git-commit: 3619350cf0d630d83dedd9c0d7d297da211f5ff0
+References: fate#323887
+
+Increase buffer size so that "_{-INT_MAX}" will fit.
+Spotted by the gcc7 snprintf checker.
+
+Signed-off-by: Olaf Hering <olaf@aepfle.de>
+Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Acked-by: Olaf Hering <ohering@suse.de>
+---
+ tools/hv/hv_kvp_daemon.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/hv/hv_kvp_daemon.c b/tools/hv/hv_kvp_daemon.c
+--- a/tools/hv/hv_kvp_daemon.c
++++ b/tools/hv/hv_kvp_daemon.c
+@@ -1136,7 +1136,7 @@ static int process_ip_string(FILE *f, char *ip_string, int type)
+ int i = 0;
+ int j = 0;
+ char str[256];
+- char sub_str[10];
++ char sub_str[13];
+ int offset = 0;
+
+ memset(addr, 0, sizeof(addr));
diff --git a/patches.suse/msft-hv-1441-Tools-hv-update-buffer-handling-in-hv_fcopy_daemon.patch b/patches.suse/msft-hv-1441-Tools-hv-update-buffer-handling-in-hv_fcopy_daemon.patch
new file mode 100644
index 0000000000..5edddb2bbb
--- /dev/null
+++ b/patches.suse/msft-hv-1441-Tools-hv-update-buffer-handling-in-hv_fcopy_daemon.patch
@@ -0,0 +1,100 @@
+From: Olaf Hering <olaf@aepfle.de>
+Date: Thu, 10 Aug 2017 15:45:16 -0700
+Patch-mainline: v4.14-rc1
+Subject: Tools: hv: update buffer handling in hv_fcopy_daemon
+Git-commit: 3f2baa8a7d2efaa836f1dc4b8ee8c3ca4ba9e101
+References: fate#323887
+
+Currently this warning is triggered when compiling hv_fcopy_daemon:
+
+hv_fcopy_daemon.c:216:4: warning: dereferencing type-punned pointer will break
+strict-aliasing rules [-Wstrict-aliasing]
+ kernel_modver = *(__u32 *)buffer;
+
+Convert the send/receive buffer to a union and pass individual members as
+needed. This also gives the correct size for the buffer.
+
+Signed-off-by: Olaf Hering <olaf@aepfle.de>
+Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Acked-by: Olaf Hering <ohering@suse.de>
+---
+ tools/hv/hv_fcopy_daemon.c | 32 +++++++++++++++++---------------
+ 1 file changed, 17 insertions(+), 15 deletions(-)
+
+diff --git a/tools/hv/hv_fcopy_daemon.c b/tools/hv/hv_fcopy_daemon.c
+--- a/tools/hv/hv_fcopy_daemon.c
++++ b/tools/hv/hv_fcopy_daemon.c
+@@ -138,14 +138,17 @@ void print_usage(char *argv[])
+
+ int main(int argc, char *argv[])
+ {
+- int fcopy_fd, len;
++ int fcopy_fd;
+ int error;
+ int daemonize = 1, long_index = 0, opt;
+ int version = FCOPY_CURRENT_VERSION;
+- char *buffer[4096 * 2];
+- struct hv_fcopy_hdr *in_msg;
++ union {
++ struct hv_fcopy_hdr hdr;
++ struct hv_start_fcopy start;
++ struct hv_do_fcopy copy;
++ __u32 kernel_modver;
++ } buffer = { };
+ int in_handshake = 1;
+- __u32 kernel_modver;
+
+ static struct option long_options[] = {
+ {"help", no_argument, 0, 'h' },
+@@ -195,32 +198,31 @@ int main(int argc, char *argv[])
+ * In this loop we process fcopy messages after the
+ * handshake is complete.
+ */
+- len = pread(fcopy_fd, buffer, (4096 * 2), 0);
++ ssize_t len;
++
++ len = pread(fcopy_fd, &buffer, sizeof(buffer), 0);
+ if (len < 0) {
+ syslog(LOG_ERR, "pread failed: %s", strerror(errno));
+ exit(EXIT_FAILURE);
+ }
+
+ if (in_handshake) {
+- if (len != sizeof(kernel_modver)) {
++ if (len != sizeof(buffer.kernel_modver)) {
+ syslog(LOG_ERR, "invalid version negotiation");
+ exit(EXIT_FAILURE);
+ }
+- kernel_modver = *(__u32 *)buffer;
+ in_handshake = 0;
+- syslog(LOG_INFO, "kernel module version: %d",
+- kernel_modver);
++ syslog(LOG_INFO, "kernel module version: %u",
++ buffer.kernel_modver);
+ continue;
+ }
+
+- in_msg = (struct hv_fcopy_hdr *)buffer;
+-
+- switch (in_msg->operation) {
++ switch (buffer.hdr.operation) {
+ case START_FILE_COPY:
+- error = hv_start_fcopy((struct hv_start_fcopy *)in_msg);
++ error = hv_start_fcopy(&buffer.start);
+ break;
+ case WRITE_TO_FILE:
+- error = hv_copy_data((struct hv_do_fcopy *)in_msg);
++ error = hv_copy_data(&buffer.copy);
+ break;
+ case COMPLETE_FCOPY:
+ error = hv_copy_finished();
+@@ -231,7 +233,7 @@ int main(int argc, char *argv[])
+
+ default:
+ syslog(LOG_ERR, "Unknown operation: %d",
+- in_msg->operation);
++ buffer.hdr.operation);
+
+ }
+
diff --git a/patches.suse/msft-hv-1442-Drivers-hv-vmbus-Fix-rescind-handling-issues.patch b/patches.suse/msft-hv-1442-Drivers-hv-vmbus-Fix-rescind-handling-issues.patch
new file mode 100644
index 0000000000..3b5d476cf7
--- /dev/null
+++ b/patches.suse/msft-hv-1442-Drivers-hv-vmbus-Fix-rescind-handling-issues.patch
@@ -0,0 +1,161 @@
+From: "K. Y. Srinivasan" <kys@microsoft.com>
+Date: Fri, 11 Aug 2017 10:03:59 -0700
+Patch-mainline: v4.14-rc1
+Subject: Drivers: hv: vmbus: Fix rescind handling issues
+Git-commit: 6f3d791f300618caf82a2be0c27456edd76d5164
+References: fate#323887
+
+This patch handles the following issues that were observed when we are
+handling racing channel offer message and rescind message for the same
+offer:
+
+1. Since the host does not respond to messages on a rescinded channel,
+in the current code, we could be indefinitely blocked on the vmbus_open() call.
+
+2. When a rescinded channel is being closed, if there is a pending interrupt on the
+channel, we could end up freeing the channel that the interrupt handler would run on.
+
+Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
+Reviewed-by: Dexuan Cui <decui@microsoft.com>
+Tested-by: Dexuan Cui <decui@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Acked-by: Olaf Hering <ohering@suse.de>
+---
+ drivers/hv/channel.c | 14 ++++++++++++++
+ drivers/hv/channel_mgmt.c | 29 ++++++++++++++++++++++++++---
+ drivers/hv/vmbus_drv.c | 3 +++
+ include/linux/hyperv.h | 2 ++
+ 4 files changed, 45 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c
+--- a/drivers/hv/channel.c
++++ b/drivers/hv/channel.c
+@@ -177,6 +177,11 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size,
+ &vmbus_connection.chn_msg_list);
+ spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags);
+
++ if (newchannel->rescind) {
++ err = -ENODEV;
++ goto error_free_gpadl;
++ }
++
+ ret = vmbus_post_msg(open_msg,
+ sizeof(struct vmbus_channel_open_channel), true);
+
+@@ -421,6 +426,11 @@ int vmbus_establish_gpadl(struct vmbus_channel *channel, void *kbuffer,
+
+ spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags);
+
++ if (channel->rescind) {
++ ret = -ENODEV;
++ goto cleanup;
++ }
++
+ ret = vmbus_post_msg(gpadlmsg, msginfo->msgsize -
+ sizeof(*msginfo), true);
+ if (ret != 0)
+@@ -494,6 +504,10 @@ int vmbus_teardown_gpadl(struct vmbus_channel *channel, u32 gpadl_handle)
+ list_add_tail(&info->msglistentry,
+ &vmbus_connection.chn_msg_list);
+ spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags);
++
++ if (channel->rescind)
++ goto post_msg_err;
++
+ ret = vmbus_post_msg(msg, sizeof(struct vmbus_channel_gpadl_teardown),
+ true);
+
+diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c
+--- a/drivers/hv/channel_mgmt.c
++++ b/drivers/hv/channel_mgmt.c
+@@ -451,6 +451,12 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel)
+ /* Make sure this is a new offer */
+ mutex_lock(&vmbus_connection.channel_mutex);
+
++ /*
++ * Now that we have acquired the channel_mutex,
++ * we can release the potentially racing rescind thread.
++ */
++ atomic_dec(&vmbus_connection.offer_in_progress);
++
+ list_for_each_entry(channel, &vmbus_connection.chn_list, listentry) {
+ if (!uuid_le_cmp(channel->offermsg.offer.if_type,
+ newchannel->offermsg.offer.if_type) &&
+@@ -481,7 +487,6 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel)
+ channel->num_sc++;
+ spin_unlock_irqrestore(&channel->lock, flags);
+ } else {
+- atomic_dec(&vmbus_connection.offer_in_progress);
+ goto err_free_chan;
+ }
+ }
+@@ -510,7 +515,6 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel)
+ if (!fnew) {
+ if (channel->sc_creation_callback != NULL)
+ channel->sc_creation_callback(newchannel);
+- atomic_dec(&vmbus_connection.offer_in_progress);
+ return;
+ }
+
+@@ -541,7 +545,7 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel)
+ goto err_deq_chan;
+ }
+
+- atomic_dec(&vmbus_connection.offer_in_progress);
++ newchannel->probe_done = true;
+ return;
+
+ err_deq_chan:
+@@ -882,8 +886,27 @@ static void vmbus_onoffer_rescind(struct vmbus_channel_message_header *hdr)
+ channel->rescind = true;
+ spin_unlock_irqrestore(&channel->lock, flags);
+
++ /*
++ * Now that we have posted the rescind state, perform
++ * rescind related cleanup.
++ */
+ vmbus_rescind_cleanup(channel);
+
++ /*
++ * Now wait for offer handling to complete.
++ */
++ while (READ_ONCE(channel->probe_done) == false) {
++ /*
++ * We wait here until any channel offer is currently
++ * being processed.
++ */
++ msleep(1);
++ }
++
++ /*
++ * At this point, the rescind handling can proceed safely.
++ */
++
+ if (channel->device_obj) {
+ if (channel->chn_rescind_callback) {
+ channel->chn_rescind_callback(channel);
+diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
+--- a/drivers/hv/vmbus_drv.c
++++ b/drivers/hv/vmbus_drv.c
+@@ -940,6 +940,9 @@ static void vmbus_chan_sched(struct hv_per_cpu_context *hv_cpu)
+ if (channel->offermsg.child_relid != relid)
+ continue;
+
++ if (channel->rescind)
++ continue;
++
+ switch (channel->callback_mode) {
+ case HV_CALL_ISR:
+ vmbus_channel_isr(channel);
+diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
+--- a/include/linux/hyperv.h
++++ b/include/linux/hyperv.h
+@@ -879,6 +879,8 @@ struct vmbus_channel {
+ */
+ enum hv_numa_policy affinity_policy;
+
++ bool probe_done;
++
+ };
+
+ static inline bool is_hvsock_channel(const struct vmbus_channel *c)
diff --git a/patches.suse/msft-hv-1443-vmbus-remove-unused-vmbus_sendpacket_multipagebuffer.patch b/patches.suse/msft-hv-1443-vmbus-remove-unused-vmbus_sendpacket_multipagebuffer.patch
new file mode 100644
index 0000000000..7152fd99fe
--- /dev/null
+++ b/patches.suse/msft-hv-1443-vmbus-remove-unused-vmbus_sendpacket_multipagebuffer.patch
@@ -0,0 +1,99 @@
+From: stephen hemminger <stephen@networkplumber.org>
+Date: Wed, 16 Aug 2017 08:56:24 -0700
+Patch-mainline: v4.14-rc1
+Subject: vmbus: remove unused vmbus_sendpacket_multipagebuffer
+Git-commit: 9a603b8e1136f2b55f780fefbcbf84d31844ff2b
+References: fate#323887
+
+This function is not used anywhere in current code.
+
+Signed-off-by: Stephen Hemminger <sthemmin@microsoft.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Acked-by: Olaf Hering <ohering@suse.de>
+---
+ drivers/hv/channel.c | 56 --------------------------------------------------
+ include/linux/hyperv.h | 6 ------
+ 2 files changed, 62 deletions(-)
+
+diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c
+--- a/drivers/hv/channel.c
++++ b/drivers/hv/channel.c
+@@ -814,62 +814,6 @@ int vmbus_sendpacket_mpb_desc(struct vmbus_channel *channel,
+ }
+ EXPORT_SYMBOL_GPL(vmbus_sendpacket_mpb_desc);
+
+-/*
+- * vmbus_sendpacket_multipagebuffer - Send a multi-page buffer packet
+- * using a GPADL Direct packet type.
+- */
+-int vmbus_sendpacket_multipagebuffer(struct vmbus_channel *channel,
+- struct hv_multipage_buffer *multi_pagebuffer,
+- void *buffer, u32 bufferlen, u64 requestid)
+-{
+- struct vmbus_channel_packet_multipage_buffer desc;
+- u32 descsize;
+- u32 packetlen;
+- u32 packetlen_aligned;
+- struct kvec bufferlist[3];
+- u64 aligned_data = 0;
+- u32 pfncount = NUM_PAGES_SPANNED(multi_pagebuffer->offset,
+- multi_pagebuffer->len);
+-
+- if (pfncount > MAX_MULTIPAGE_BUFFER_COUNT)
+- return -EINVAL;
+-
+- /*
+- * Adjust the size down since vmbus_channel_packet_multipage_buffer is
+- * the largest size we support
+- */
+- descsize = sizeof(struct vmbus_channel_packet_multipage_buffer) -
+- ((MAX_MULTIPAGE_BUFFER_COUNT - pfncount) *
+- sizeof(u64));
+- packetlen = descsize + bufferlen;
+- packetlen_aligned = ALIGN(packetlen, sizeof(u64));
+-
+-
+- /* Setup the descriptor */
+- desc.type = VM_PKT_DATA_USING_GPA_DIRECT;
+- desc.flags = VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED;
+- desc.dataoffset8 = descsize >> 3; /* in 8-bytes granularity */
+- desc.length8 = (u16)(packetlen_aligned >> 3);
+- desc.transactionid = requestid;
+- desc.rangecount = 1;
+-
+- desc.range.len = multi_pagebuffer->len;
+- desc.range.offset = multi_pagebuffer->offset;
+-
+- memcpy(desc.range.pfn_array, multi_pagebuffer->pfn_array,
+- pfncount * sizeof(u64));
+-
+- bufferlist[0].iov_base = &desc;
+- bufferlist[0].iov_len = descsize;
+- bufferlist[1].iov_base = buffer;
+- bufferlist[1].iov_len = bufferlen;
+- bufferlist[2].iov_base = &aligned_data;
+- bufferlist[2].iov_len = (packetlen_aligned - packetlen);
+-
+- return hv_ringbuffer_write(channel, bufferlist, 3);
+-}
+-EXPORT_SYMBOL_GPL(vmbus_sendpacket_multipagebuffer);
+-
+ /**
+ * vmbus_recvpacket() - Retrieve the user packet on the specified channel
+ * @channel: Pointer to vmbus_channel structure.
+diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
+--- a/include/linux/hyperv.h
++++ b/include/linux/hyperv.h
+@@ -1052,12 +1052,6 @@ extern int vmbus_sendpacket_pagebuffer_ctl(struct vmbus_channel *channel,
+ u64 requestid,
+ u32 flags);
+
+-extern int vmbus_sendpacket_multipagebuffer(struct vmbus_channel *channel,
+- struct hv_multipage_buffer *mpb,
+- void *buffer,
+- u32 bufferlen,
+- u64 requestid);
+-
+ extern int vmbus_sendpacket_mpb_desc(struct vmbus_channel *channel,
+ struct vmbus_packet_mpb_array *mpb,
+ u32 desc_size,
diff --git a/patches.suse/msft-hv-1444-vmbus-remove-unused-vmubs_sendpacket_pagebuffer_ctl.patch b/patches.suse/msft-hv-1444-vmbus-remove-unused-vmubs_sendpacket_pagebuffer_ctl.patch
new file mode 100644
index 0000000000..7efd1601f2
--- /dev/null
+++ b/patches.suse/msft-hv-1444-vmbus-remove-unused-vmubs_sendpacket_pagebuffer_ctl.patch
@@ -0,0 +1,116 @@
+From: stephen hemminger <stephen@networkplumber.org>
+Date: Wed, 16 Aug 2017 08:56:25 -0700
+Patch-mainline: v4.14-rc1
+Subject: vmbus: remove unused vmubs_sendpacket_pagebuffer_ctl
+Git-commit: 5a668d8cddbe8bf14379ce110c49ca088a1e9fae
+References: fate#323887
+
+The function vmbus_sendpacket_pagebuffer_ctl was never used directly.
+Just have vmbus_send_pagebuffer
+
+Signed-off-by: Stephen Hemminger <sthemmin@microsoft.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Acked-by: Olaf Hering <ohering@suse.de>
+---
+ drivers/hv/channel.c | 30 ++++++------------------------
+ drivers/net/hyperv/netvsc.c | 10 ++++------
+ include/linux/hyperv.h | 8 --------
+ 3 files changed, 10 insertions(+), 38 deletions(-)
+
+diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c
+--- a/drivers/hv/channel.c
++++ b/drivers/hv/channel.c
+@@ -702,16 +702,16 @@ int vmbus_sendpacket(struct vmbus_channel *channel, void *buffer,
+ EXPORT_SYMBOL(vmbus_sendpacket);
+
+ /*
+- * vmbus_sendpacket_pagebuffer_ctl - Send a range of single-page buffer
++ * vmbus_sendpacket_pagebuffer - 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_ctl(struct vmbus_channel *channel,
+- struct hv_page_buffer pagebuffers[],
+- u32 pagecount, void *buffer, u32 bufferlen,
+- u64 requestid, u32 flags)
++int vmbus_sendpacket_pagebuffer(struct vmbus_channel *channel,
++ struct hv_page_buffer pagebuffers[],
++ u32 pagecount, void *buffer, u32 bufferlen,
++ u64 requestid)
+ {
+ int i;
+ struct vmbus_channel_packet_page_buffer desc;
+@@ -736,7 +736,7 @@ int vmbus_sendpacket_pagebuffer_ctl(struct vmbus_channel *channel,
+
+ /* Setup the descriptor */
+ desc.type = VM_PKT_DATA_USING_GPA_DIRECT;
+- desc.flags = flags;
++ desc.flags = VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED;
+ desc.dataoffset8 = descsize >> 3; /* in 8-bytes granularity */
+ desc.length8 = (u16)(packetlen_aligned >> 3);
+ desc.transactionid = requestid;
+@@ -757,24 +757,6 @@ int vmbus_sendpacket_pagebuffer_ctl(struct vmbus_channel *channel,
+
+ return hv_ringbuffer_write(channel, bufferlist, 3);
+ }
+-EXPORT_SYMBOL_GPL(vmbus_sendpacket_pagebuffer_ctl);
+-
+-/*
+- * 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);
+-
+-}
+ EXPORT_SYMBOL_GPL(vmbus_sendpacket_pagebuffer);
+
+ /*
+diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c
+--- a/drivers/net/hyperv/netvsc.c
++++ b/drivers/net/hyperv/netvsc.c
+@@ -775,12 +775,10 @@ static inline int netvsc_send_pkt(
+ if (packet->cp_partial)
+ pb += packet->rmsg_pgcnt;
+
+- ret = vmbus_sendpacket_pagebuffer_ctl(out_channel,
+- pb, packet->page_buf_cnt,
+- &nvmsg,
+- sizeof(struct nvsp_message),
+- req_id,
+- VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
++ ret = vmbus_sendpacket_pagebuffer(out_channel,
++ pb, packet->page_buf_cnt,
++ &nvmsg, sizeof(nvmsg),
++ req_id);
+ } else {
+ ret = vmbus_sendpacket_ctl(out_channel, &nvmsg,
+ sizeof(struct nvsp_message),
+diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
+--- a/include/linux/hyperv.h
++++ b/include/linux/hyperv.h
+@@ -1044,14 +1044,6 @@ 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);
+-
+ extern int vmbus_sendpacket_mpb_desc(struct vmbus_channel *channel,
+ struct vmbus_packet_mpb_array *mpb,
+ u32 desc_size,
diff --git a/patches.suse/msft-hv-1445-vmbus-remove-unused-vmbus_sendpacket_ctl.patch b/patches.suse/msft-hv-1445-vmbus-remove-unused-vmbus_sendpacket_ctl.patch
new file mode 100644
index 0000000000..5f2d23ef5c
--- /dev/null
+++ b/patches.suse/msft-hv-1445-vmbus-remove-unused-vmbus_sendpacket_ctl.patch
@@ -0,0 +1,114 @@
+From: stephen hemminger <stephen@networkplumber.org>
+Date: Wed, 16 Aug 2017 08:56:26 -0700
+Patch-mainline: v4.14-rc1
+Subject: vmbus: remove unused vmbus_sendpacket_ctl
+Git-commit: 5dd0fb9b9ffc0ef9b312d05604f4ad0fffc50505
+References: fate#323887
+
+The only usage of vmbus_sendpacket_ctl was by vmbus_sendpacket.
+
+Signed-off-by: Stephen Hemminger <sthemmin@microsoft.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Acked-by: Olaf Hering <ohering@suse.de>
+---
+ drivers/hv/channel.c | 43 +++++++++++++++++--------------------------
+ drivers/net/hyperv/netvsc.c | 9 ++++-----
+ include/linux/hyperv.h | 7 -------
+ 3 files changed, 21 insertions(+), 38 deletions(-)
+
+diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c
+--- a/drivers/hv/channel.c
++++ b/drivers/hv/channel.c
+@@ -647,9 +647,23 @@ void vmbus_close(struct vmbus_channel *channel)
+ }
+ EXPORT_SYMBOL_GPL(vmbus_close);
+
+-int vmbus_sendpacket_ctl(struct vmbus_channel *channel, void *buffer,
+- u32 bufferlen, u64 requestid,
+- enum vmbus_packet_type type, u32 flags)
++/**
++ * 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)
+ {
+ struct vmpacket_descriptor desc;
+ u32 packetlen = sizeof(struct vmpacket_descriptor) + bufferlen;
+@@ -676,29 +690,6 @@ int vmbus_sendpacket_ctl(struct vmbus_channel *channel, void *buffer,
+
+ return hv_ringbuffer_write(channel, bufferlist, num_vecs);
+ }
+-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);
+-}
+ EXPORT_SYMBOL(vmbus_sendpacket);
+
+ /*
+diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c
+--- a/drivers/net/hyperv/netvsc.c
++++ b/drivers/net/hyperv/netvsc.c
+@@ -780,11 +780,10 @@ static inline int netvsc_send_pkt(
+ &nvmsg, sizeof(nvmsg),
+ req_id);
+ } else {
+- ret = vmbus_sendpacket_ctl(out_channel, &nvmsg,
+- sizeof(struct nvsp_message),
+- req_id,
+- VM_PKT_DATA_INBAND,
+- VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
++ ret = vmbus_sendpacket(out_channel,
++ &nvmsg, sizeof(nvmsg),
++ req_id, VM_PKT_DATA_INBAND,
++ VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
+ }
+
+ if (ret == 0) {
+diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
+--- a/include/linux/hyperv.h
++++ b/include/linux/hyperv.h
+@@ -1030,13 +1030,6 @@ 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);
+-
+ extern int vmbus_sendpacket_pagebuffer(struct vmbus_channel *channel,
+ struct hv_page_buffer pagebuffers[],
+ u32 pagecount,
diff --git a/patches.suse/msft-hv-1446-hv_netvsc-Clean-up-unused-parameter-from-netvsc_get_.patch b/patches.suse/msft-hv-1446-hv_netvsc-Clean-up-unused-parameter-from-netvsc_get_.patch
new file mode 100644
index 0000000000..bb05737b5e
--- /dev/null
+++ b/patches.suse/msft-hv-1446-hv_netvsc-Clean-up-unused-parameter-from-netvsc_get_.patch
@@ -0,0 +1,37 @@
+From: Haiyang Zhang <haiyangz@microsoft.com>
+Date: Mon, 21 Aug 2017 19:22:37 -0700
+Patch-mainline: v4.14-rc1
+Subject: hv_netvsc: Clean up unused parameter from netvsc_get_hash()
+Git-commit: fcba1569a0c87cea40404af9a29b319f4e491839
+References: fate#323887
+
+The parameter "sk" is not in use.
+
+Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Acked-by: Olaf Hering <ohering@suse.de>
+---
+ drivers/net/hyperv/netvsc_drv.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
+--- a/drivers/net/hyperv/netvsc_drv.c
++++ b/drivers/net/hyperv/netvsc_drv.c
+@@ -193,7 +193,7 @@ static void *init_ppi_data(struct rndis_message *msg, u32 ppi_size,
+ /* Azure hosts don't support non-TCP port numbers in hashing yet. We compute
+ * hash for non-TCP traffic with only IP numbers.
+ */
+-static inline u32 netvsc_get_hash(struct sk_buff *skb, struct sock *sk)
++static inline u32 netvsc_get_hash(struct sk_buff *skb)
+ {
+ struct flow_keys flow;
+ u32 hash;
+@@ -227,7 +227,7 @@ static inline int netvsc_get_tx_queue(struct net_device *ndev,
+ struct sock *sk = skb->sk;
+ int q_idx;
+
+- q_idx = ndc->tx_send_table[netvsc_get_hash(skb, sk) &
++ q_idx = ndc->tx_send_table[netvsc_get_hash(skb) &
+ (VRSS_SEND_TAB_SIZE - 1)];
+
+ /* If queue index changed record the new value */
diff --git a/patches.suse/msft-hv-1447-hv_netvsc-Clean-up-unused-parameter-from-netvsc_get_.patch b/patches.suse/msft-hv-1447-hv_netvsc-Clean-up-unused-parameter-from-netvsc_get_.patch
new file mode 100644
index 0000000000..7775178312
--- /dev/null
+++ b/patches.suse/msft-hv-1447-hv_netvsc-Clean-up-unused-parameter-from-netvsc_get_.patch
@@ -0,0 +1,38 @@
+From: Haiyang Zhang <haiyangz@microsoft.com>
+Date: Mon, 21 Aug 2017 19:22:38 -0700
+Patch-mainline: v4.14-rc1
+Subject: hv_netvsc: Clean up unused parameter from netvsc_get_rss_hash_opts()
+Git-commit: 4c0e2cbfd9b519722529526f4d87f8aab3c32ffd
+References: fate#323887
+
+The parameter "nvdev" is not in use.
+
+Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Acked-by: Olaf Hering <ohering@suse.de>
+---
+ drivers/net/hyperv/netvsc_drv.c | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
+--- a/drivers/net/hyperv/netvsc_drv.c
++++ b/drivers/net/hyperv/netvsc_drv.c
+@@ -1228,8 +1228,7 @@ static void netvsc_get_strings(struct net_device *dev, u32 stringset, u8 *data)
+ }
+
+ static int
+-netvsc_get_rss_hash_opts(struct netvsc_device *nvdev,
+- struct ethtool_rxnfc *info)
++netvsc_get_rss_hash_opts(struct ethtool_rxnfc *info)
+ {
+ info->data = RXH_IP_SRC | RXH_IP_DST;
+
+@@ -1267,7 +1266,7 @@ netvsc_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *info,
+ return 0;
+
+ case ETHTOOL_GRXFH:
+- return netvsc_get_rss_hash_opts(nvdev, info);
++ return netvsc_get_rss_hash_opts(info);
+ }
+ return -EOPNOTSUPP;
+ }
diff --git a/patches.suse/msft-hv-1448-hv_netvsc-Add-ethtool-handler-to-set-and-get-UDP-has.patch b/patches.suse/msft-hv-1448-hv_netvsc-Add-ethtool-handler-to-set-and-get-UDP-has.patch
new file mode 100644
index 0000000000..61888c287e
--- /dev/null
+++ b/patches.suse/msft-hv-1448-hv_netvsc-Add-ethtool-handler-to-set-and-get-UDP-has.patch
@@ -0,0 +1,187 @@
+From: Haiyang Zhang <haiyangz@microsoft.com>
+Date: Mon, 21 Aug 2017 19:22:39 -0700
+Patch-mainline: v4.14-rc1
+Subject: hv_netvsc: Add ethtool handler to set and get UDP hash levels
+Git-commit: 4823eb2f3af44e2b9f7f02bed5a211e9ce79051f
+References: fate#323887
+
+The patch add the functions to switch UDP hash level between
+L3 and L4 by ethtool command. UDP over IPv4 and v6 can be set
+differently. The default hash level is L4. We currently only
+allow switching TX hash level from within the guests.
+
+On Azure, fragmented UDP packets have high loss rate with L4
+hashing. Using L3 hashing is recommended in this case.
+
+For example, for UDP over IPv4 on eth0:
+To include UDP port numbers in hasing:
+ ethtool -N eth0 rx-flow-hash udp4 sdfn
+To exclude UDP port numbers in hasing:
+ ethtool -N eth0 rx-flow-hash udp4 sd
+To show UDP hash level:
+ ethtool -n eth0 rx-flow-hash udp4
+
+Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Acked-by: Olaf Hering <ohering@suse.de>
+---
+ drivers/net/hyperv/hyperv_net.h | 2 ++
+ drivers/net/hyperv/netvsc_drv.c | 78 ++++++++++++++++++++++++++++++++++++-----
+ 2 files changed, 72 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h
+--- a/drivers/net/hyperv/hyperv_net.h
++++ b/drivers/net/hyperv/hyperv_net.h
+@@ -720,6 +720,8 @@ struct net_device_context {
+ u32 tx_send_table[VRSS_SEND_TAB_SIZE];
+
+ /* Ethtool settings */
++ bool udp4_l4_hash;
++ bool udp6_l4_hash;
+ u8 duplex;
+ u32 speed;
+ struct netvsc_ethtool_stats eth_stats;
+diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
+--- a/drivers/net/hyperv/netvsc_drv.c
++++ b/drivers/net/hyperv/netvsc_drv.c
+@@ -190,10 +190,12 @@ static void *init_ppi_data(struct rndis_message *msg, u32 ppi_size,
+ return ppi;
+ }
+
+-/* Azure hosts don't support non-TCP port numbers in hashing yet. We compute
+- * hash for non-TCP traffic with only IP numbers.
++/* Azure hosts don't support non-TCP port numbers in hashing for fragmented
++ * packets. We can use ethtool to change UDP hash level when necessary.
+ */
+-static inline u32 netvsc_get_hash(struct sk_buff *skb)
++static inline u32 netvsc_get_hash(
++ struct sk_buff *skb,
++ const struct net_device_context *ndc)
+ {
+ struct flow_keys flow;
+ u32 hash;
+@@ -204,7 +206,11 @@ static inline u32 netvsc_get_hash(struct sk_buff *skb)
+ if (!skb_flow_dissect_flow_keys(skb, &flow, 0))
+ return 0;
+
+- if (flow.basic.ip_proto == IPPROTO_TCP) {
++ if (flow.basic.ip_proto == IPPROTO_TCP ||
++ (flow.basic.ip_proto == IPPROTO_UDP &&
++ ((flow.basic.n_proto == htons(ETH_P_IP) && ndc->udp4_l4_hash) ||
++ (flow.basic.n_proto == htons(ETH_P_IPV6) &&
++ ndc->udp6_l4_hash)))) {
+ return skb_get_hash(skb);
+ } else {
+ if (flow.basic.n_proto == htons(ETH_P_IP))
+@@ -227,7 +233,7 @@ static inline int netvsc_get_tx_queue(struct net_device *ndev,
+ struct sock *sk = skb->sk;
+ int q_idx;
+
+- q_idx = ndc->tx_send_table[netvsc_get_hash(skb) &
++ q_idx = ndc->tx_send_table[netvsc_get_hash(skb, ndc) &
+ (VRSS_SEND_TAB_SIZE - 1)];
+
+ /* If queue index changed record the new value */
+@@ -891,6 +897,9 @@ static void netvsc_init_settings(struct net_device *dev)
+ {
+ struct net_device_context *ndc = netdev_priv(dev);
+
++ ndc->udp4_l4_hash = true;
++ ndc->udp6_l4_hash = true;
++
+ ndc->speed = SPEED_UNKNOWN;
+ ndc->duplex = DUPLEX_FULL;
+ }
+@@ -1228,7 +1237,8 @@ static void netvsc_get_strings(struct net_device *dev, u32 stringset, u8 *data)
+ }
+
+ static int
+-netvsc_get_rss_hash_opts(struct ethtool_rxnfc *info)
++netvsc_get_rss_hash_opts(struct net_device_context *ndc,
++ struct ethtool_rxnfc *info)
+ {
+ info->data = RXH_IP_SRC | RXH_IP_DST;
+
+@@ -1236,9 +1246,20 @@ netvsc_get_rss_hash_opts(struct ethtool_rxnfc *info)
+ case TCP_V4_FLOW:
+ case TCP_V6_FLOW:
+ info->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
+- /* fallthrough */
++ break;
++
+ case UDP_V4_FLOW:
++ if (ndc->udp4_l4_hash)
++ info->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
++
++ break;
++
+ case UDP_V6_FLOW:
++ if (ndc->udp6_l4_hash)
++ info->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
++
++ break;
++
+ case IPV4_FLOW:
+ case IPV6_FLOW:
+ break;
+@@ -1266,11 +1287,51 @@ netvsc_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *info,
+ return 0;
+
+ case ETHTOOL_GRXFH:
+- return netvsc_get_rss_hash_opts(info);
++ return netvsc_get_rss_hash_opts(ndc, info);
+ }
+ return -EOPNOTSUPP;
+ }
+
++static int netvsc_set_rss_hash_opts(struct net_device_context *ndc,
++ struct ethtool_rxnfc *info)
++{
++ if (info->data == (RXH_IP_SRC | RXH_IP_DST |
++ RXH_L4_B_0_1 | RXH_L4_B_2_3)) {
++ if (info->flow_type == UDP_V4_FLOW)
++ ndc->udp4_l4_hash = true;
++ else if (info->flow_type == UDP_V6_FLOW)
++ ndc->udp6_l4_hash = true;
++ else
++ return -EOPNOTSUPP;
++
++ return 0;
++ }
++
++ if (info->data == (RXH_IP_SRC | RXH_IP_DST)) {
++ if (info->flow_type == UDP_V4_FLOW)
++ ndc->udp4_l4_hash = false;
++ else if (info->flow_type == UDP_V6_FLOW)
++ ndc->udp6_l4_hash = false;
++ else
++ return -EOPNOTSUPP;
++
++ return 0;
++ }
++
++ return -EOPNOTSUPP;
++}
++
++static int
++netvsc_set_rxnfc(struct net_device *ndev, struct ethtool_rxnfc *info)
++{
++ struct net_device_context *ndc = netdev_priv(ndev);
++
++ if (info->cmd == ETHTOOL_SRXFH)
++ return netvsc_set_rss_hash_opts(ndc, info);
++
++ return -EOPNOTSUPP;
++}
++
+ #ifdef CONFIG_NET_POLL_CONTROLLER
+ static void netvsc_poll_controller(struct net_device *dev)
+ {
+@@ -1469,6 +1530,7 @@ static const struct ethtool_ops ethtool_ops = {
+ .set_channels = netvsc_set_channels,
+ .get_ts_info = ethtool_op_get_ts_info,
+ .get_rxnfc = netvsc_get_rxnfc,
++ .set_rxnfc = netvsc_set_rxnfc,
+ .get_rxfh_key_size = netvsc_get_rxfh_key_size,
+ .get_rxfh_indir_size = netvsc_rss_indir_size,
+ .get_rxfh = netvsc_get_rxfh,
diff --git a/patches.suse/msft-hv-1449-hv_netvsc-Fix-rndis_filter_close-error-during-netvsc.patch b/patches.suse/msft-hv-1449-hv_netvsc-Fix-rndis_filter_close-error-during-netvsc.patch
new file mode 100644
index 0000000000..ed71f30a29
--- /dev/null
+++ b/patches.suse/msft-hv-1449-hv_netvsc-Fix-rndis_filter_close-error-during-netvsc.patch
@@ -0,0 +1,48 @@
+From: Haiyang Zhang <haiyangz@microsoft.com>
+Date: Thu, 24 Aug 2017 11:50:02 -0700
+Patch-mainline: v4.14-rc1
+Subject: hv_netvsc: Fix rndis_filter_close error during netvsc_remove
+Git-commit: c6f71c418fcc46f59fc87ac93ce9336c12d7898b
+References: fate#323887
+
+We now remove rndis filter before unregister_netdev(), which calls
+device close. It involves closing rndis filter already removed.
+
+This patch fixes this error.
+
+Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Acked-by: Olaf Hering <ohering@suse.de>
+---
+ drivers/net/hyperv/netvsc_drv.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
+--- a/drivers/net/hyperv/netvsc_drv.c
++++ b/drivers/net/hyperv/netvsc_drv.c
+@@ -119,12 +119,16 @@ static int netvsc_close(struct net_device *net)
+ struct net_device *vf_netdev
+ = rtnl_dereference(net_device_ctx->vf_netdev);
+ struct netvsc_device *nvdev = rtnl_dereference(net_device_ctx->nvdev);
+- int ret;
++ int ret = 0;
+ u32 aread, i, msec = 10, retry = 0, retry_max = 20;
+ struct vmbus_channel *chn;
+
+ netif_tx_disable(net);
+
++ /* No need to close rndis filter if it is removed already */
++ if (!nvdev)
++ goto out;
++
+ ret = rndis_filter_close(nvdev);
+ if (ret != 0) {
+ netdev_err(net, "unable to close device (ret %d).\n", ret);
+@@ -163,6 +167,7 @@ static int netvsc_close(struct net_device *net)
+ ret = -ETIMEDOUT;
+ }
+
++out:
+ if (vf_netdev)
+ dev_close(vf_netdev);
+
diff --git a/patches.suse/msft-hv-1452-scsi-storvsc-fix-memory-leak-on-ring-buffer-busy.patch b/patches.suse/msft-hv-1452-scsi-storvsc-fix-memory-leak-on-ring-buffer-busy.patch
new file mode 100644
index 0000000000..4c8c1d6694
--- /dev/null
+++ b/patches.suse/msft-hv-1452-scsi-storvsc-fix-memory-leak-on-ring-buffer-busy.patch
@@ -0,0 +1,37 @@
+From: Long Li <longli@microsoft.com>
+Date: Mon, 28 Aug 2017 17:43:59 -0700
+Patch-mainline: v4.14-rc1
+Subject: scsi: storvsc: fix memory leak on ring buffer busy
+Git-commit: 0208eeaa650c5c866a3242201678a19e6dc4a14e
+References: fate#323887
+
+When storvsc is sending I/O to Hyper-v, it may allocate a bigger buffer
+descriptor for large data payload that can't fit into a pre-allocated
+buffer descriptor. This bigger buffer is freed on return path.
+
+If I/O request to Hyper-v fails due to ring buffer busy, the storvsc
+allocated buffer descriptor should also be freed.
+
+[mkp: applied by hand]
+
+Fixes: be0cf6ca301c ("scsi: storvsc: Set the tablesize based on the information given by the host")
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Long Li <longli@microsoft.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Olaf Hering <ohering@suse.de>
+---
+ drivers/scsi/storvsc_drv.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
+--- a/drivers/scsi/storvsc_drv.c
++++ b/drivers/scsi/storvsc_drv.c
+@@ -1640,6 +1640,8 @@ static int storvsc_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *scmnd)
+ put_cpu();
+
+ if (ret == -EAGAIN) {
++ if (payload_sz > sizeof(cmd_request->mpb))
++ kfree(payload);
+ /* no more space */
+ return SCSI_MLQUEUE_DEVICE_BUSY;
+ }
diff --git a/patches.suse/msft-hv-1453-x86-hyper-v-Support-extended-CPU-ranges-for-TLB-flus.patch b/patches.suse/msft-hv-1453-x86-hyper-v-Support-extended-CPU-ranges-for-TLB-flus.patch
new file mode 100644
index 0000000000..566f0b11b7
--- /dev/null
+++ b/patches.suse/msft-hv-1453-x86-hyper-v-Support-extended-CPU-ranges-for-TLB-flus.patch
@@ -0,0 +1,236 @@
+From: Vitaly Kuznetsov <vkuznets@redhat.com>
+Date: Wed, 2 Aug 2017 18:09:20 +0200
+Patch-mainline: v4.14-rc1
+Subject: x86/hyper-v: Support extended CPU ranges for TLB flush hypercalls
+Git-commit: 628f54cc6451d2706ba8a56763dbf93be02aaa80
+References: fate#323887
+
+Hyper-V hosts may support more than 64 vCPUs, we need to use
+HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE_EX/LIST_EX hypercalls in this
+case.
+
+Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
+Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Reviewed-by: Stephen Hemminger <sthemmin@microsoft.com>
+Cc: Andy Lutomirski <luto@kernel.org>
+Cc: Haiyang Zhang <haiyangz@microsoft.com>
+Cc: Jork Loeser <Jork.Loeser@microsoft.com>
+Cc: K. Y. Srinivasan <kys@microsoft.com>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Simon Xiao <sixiao@microsoft.com>
+Cc: Steven Rostedt <rostedt@goodmis.org>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Cc: devel@linuxdriverproject.org
+Link: http://lkml.kernel.org/r/20170802160921.21791-9-vkuznets@redhat.com
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Acked-by: Olaf Hering <ohering@suse.de>
+---
+ arch/x86/hyperv/mmu.c | 133 ++++++++++++++++++++++++++++++++++++-
+ arch/x86/include/uapi/asm/hyperv.h | 10 +++
+ 2 files changed, 140 insertions(+), 3 deletions(-)
+
+diff --git a/arch/x86/hyperv/mmu.c b/arch/x86/hyperv/mmu.c
+--- a/arch/x86/hyperv/mmu.c
++++ b/arch/x86/hyperv/mmu.c
+@@ -18,11 +18,25 @@ struct hv_flush_pcpu {
+ u64 gva_list[];
+ };
+
++/* HvFlushVirtualAddressSpaceEx, HvFlushVirtualAddressListEx hypercalls */
++struct hv_flush_pcpu_ex {
++ u64 address_space;
++ u64 flags;
++ struct {
++ u64 format;
++ u64 valid_bank_mask;
++ u64 bank_contents[];
++ } hv_vp_set;
++ u64 gva_list[];
++};
++
+ /* Each gva in gva_list encodes up to 4096 pages to flush */
+ #define HV_TLB_FLUSH_UNIT (4096 * PAGE_SIZE)
+
+ static struct hv_flush_pcpu __percpu *pcpu_flush;
+
++static struct hv_flush_pcpu_ex __percpu *pcpu_flush_ex;
++
+ /*
+ * Fills in gva_list starting from offset. Returns the number of items added.
+ */
+@@ -53,6 +67,34 @@ static inline int fill_gva_list(u64 gva_list[], int offset,
+ return gva_n - offset;
+ }
+
++/* Return the number of banks in the resulting vp_set */
++static inline int cpumask_to_vp_set(struct hv_flush_pcpu_ex *flush,
++ const struct cpumask *cpus)
++{
++ int cpu, vcpu, vcpu_bank, vcpu_offset, nr_bank = 1;
++
++ /*
++ * Some banks may end up being empty but this is acceptable.
++ */
++ for_each_cpu(cpu, cpus) {
++ vcpu = hv_cpu_number_to_vp_number(cpu);
++ vcpu_bank = vcpu / 64;
++ vcpu_offset = vcpu % 64;
++
++ /* valid_bank_mask can represent up to 64 banks */
++ if (vcpu_bank >= 64)
++ return 0;
++
++ __set_bit(vcpu_offset, (unsigned long *)
++ &flush->hv_vp_set.bank_contents[vcpu_bank]);
++ if (vcpu_bank >= nr_bank)
++ nr_bank = vcpu_bank + 1;
++ }
++ flush->hv_vp_set.valid_bank_mask = GENMASK_ULL(nr_bank - 1, 0);
++
++ return nr_bank;
++}
++
+ static void hyperv_flush_tlb_others(const struct cpumask *cpus,
+ struct mm_struct *mm, unsigned long start, unsigned long end)
+ {
+@@ -122,17 +164,102 @@ do_native:
+ native_flush_tlb_others(cpus, mm, start, end);
+ }
+
++static void hyperv_flush_tlb_others_ex(const struct cpumask *cpus,
++struct mm_struct *mm, unsigned long start, unsigned long end)
++{
++ int nr_bank = 0, max_gvas, gva_n;
++ struct hv_flush_pcpu_ex *flush;
++ u64 status = U64_MAX;
++ unsigned long flags;
++
++ if (!pcpu_flush_ex || !hv_hypercall_pg)
++ goto do_native;
++
++ if (cpumask_empty(cpus))
++ return;
++
++ local_irq_save(flags);
++
++ flush = this_cpu_ptr(pcpu_flush_ex);
++
++ if (mm) {
++ flush->address_space = virt_to_phys(mm->pgd);
++ flush->flags = 0;
++ } else {
++ flush->address_space = 0;
++ flush->flags = HV_FLUSH_ALL_VIRTUAL_ADDRESS_SPACES;
++ }
++
++ flush->hv_vp_set.valid_bank_mask = 0;
++
++ if (!cpumask_equal(cpus, cpu_present_mask)) {
++ flush->hv_vp_set.format = HV_GENERIC_SET_SPARCE_4K;
++ nr_bank = cpumask_to_vp_set(flush, cpus);
++ }
++
++ if (!nr_bank) {
++ flush->hv_vp_set.format = HV_GENERIC_SET_ALL;
++ flush->flags |= HV_FLUSH_ALL_PROCESSORS;
++ }
++
++ /*
++ * We can flush not more than max_gvas with one hypercall. Flush the
++ * whole address space if we were asked to do more.
++ */
++ max_gvas =
++ (PAGE_SIZE - sizeof(*flush) - nr_bank *
++ sizeof(flush->hv_vp_set.bank_contents[0])) /
++ sizeof(flush->gva_list[0]);
++
++ if (end == TLB_FLUSH_ALL) {
++ flush->flags |= HV_FLUSH_NON_GLOBAL_MAPPINGS_ONLY;
++ status = hv_do_rep_hypercall(
++ HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE_EX,
++ 0, nr_bank + 2, flush, NULL);
++ } else if (end &&
++ ((end - start)/HV_TLB_FLUSH_UNIT) > max_gvas) {
++ status = hv_do_rep_hypercall(
++ HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE_EX,
++ 0, nr_bank + 2, flush, NULL);
++ } else {
++ gva_n = fill_gva_list(flush->gva_list, nr_bank,
++ start, end);
++ status = hv_do_rep_hypercall(
++ HVCALL_FLUSH_VIRTUAL_ADDRESS_LIST_EX,
++ gva_n, nr_bank + 2, flush, NULL);
++ }
++
++ local_irq_restore(flags);
++
++ if (!(status & HV_HYPERCALL_RESULT_MASK))
++ return;
++do_native:
++ native_flush_tlb_others(cpus, mm, start, end);
++}
++
+ void hyperv_setup_mmu_ops(void)
+ {
+- if (ms_hyperv.hints & HV_X64_REMOTE_TLB_FLUSH_RECOMMENDED) {
++ if (!(ms_hyperv.hints & HV_X64_REMOTE_TLB_FLUSH_RECOMMENDED))
++ return;
++
++ setup_clear_cpu_cap(X86_FEATURE_PCID);
++
++ if (!(ms_hyperv.hints & HV_X64_EX_PROCESSOR_MASKS_RECOMMENDED)) {
+ pr_info("Using hypercall for remote TLB flush\n");
+ pv_mmu_ops.flush_tlb_others = hyperv_flush_tlb_others;
+- setup_clear_cpu_cap(X86_FEATURE_PCID);
++ } else {
++ pr_info("Using ext hypercall for remote TLB flush\n");
++ pv_mmu_ops.flush_tlb_others = hyperv_flush_tlb_others_ex;
+ }
+ }
+
+ void hyper_alloc_mmu(void)
+ {
+- if (ms_hyperv.hints & HV_X64_REMOTE_TLB_FLUSH_RECOMMENDED)
++ if (!(ms_hyperv.hints & HV_X64_REMOTE_TLB_FLUSH_RECOMMENDED))
++ return;
++
++ if (!(ms_hyperv.hints & HV_X64_EX_PROCESSOR_MASKS_RECOMMENDED))
+ pcpu_flush = __alloc_percpu(PAGE_SIZE, PAGE_SIZE);
++ else
++ pcpu_flush_ex = __alloc_percpu(PAGE_SIZE, PAGE_SIZE);
+ }
+diff --git a/arch/x86/include/uapi/asm/hyperv.h b/arch/x86/include/uapi/asm/hyperv.h
+--- a/arch/x86/include/uapi/asm/hyperv.h
++++ b/arch/x86/include/uapi/asm/hyperv.h
+@@ -149,6 +149,9 @@
+ */
+ #define HV_X64_DEPRECATING_AEOI_RECOMMENDED (1 << 9)
+
++/* Recommend using the newer ExProcessorMasks interface */
++#define HV_X64_EX_PROCESSOR_MASKS_RECOMMENDED (1 << 11)
++
+ /*
+ * HV_VP_SET available
+ */
+@@ -245,6 +248,8 @@
+ #define HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE 0x0002
+ #define HVCALL_FLUSH_VIRTUAL_ADDRESS_LIST 0x0003
+ #define HVCALL_NOTIFY_LONG_SPIN_WAIT 0x0008
++#define HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE_EX 0x0013
++#define HVCALL_FLUSH_VIRTUAL_ADDRESS_LIST_EX 0x0014
+ #define HVCALL_POST_MESSAGE 0x005c
+ #define HVCALL_SIGNAL_EVENT 0x005d
+
+@@ -266,6 +271,11 @@
+ #define HV_FLUSH_NON_GLOBAL_MAPPINGS_ONLY BIT(2)
+ #define HV_FLUSH_USE_EXTENDED_RANGE_FORMAT BIT(3)
+
++enum HV_GENERIC_SET_FORMAT {
++ HV_GENERIC_SET_SPARCE_4K,
++ HV_GENERIC_SET_ALL,
++};
++
+ /* hypercall status code */
+ #define HV_STATUS_SUCCESS 0
+ #define HV_STATUS_INVALID_HYPERCALL_CODE 2
diff --git a/patches.suse/msft-hv-1454-tracing-hyper-v-Trace-hyperv_mmu_flush_tlb_others.patch b/patches.suse/msft-hv-1454-tracing-hyper-v-Trace-hyperv_mmu_flush_tlb_others.patch
new file mode 100644
index 0000000000..1b38bfd68c
--- /dev/null
+++ b/patches.suse/msft-hv-1454-tracing-hyper-v-Trace-hyperv_mmu_flush_tlb_others.patch
@@ -0,0 +1,121 @@
+From: Vitaly Kuznetsov <vkuznets@redhat.com>
+Date: Wed, 2 Aug 2017 18:09:21 +0200
+Patch-mainline: v4.14-rc1
+Subject: tracing/hyper-v: Trace hyperv_mmu_flush_tlb_others()
+Git-commit: 773b79f7a7c7839fb9d09c0e206734173a8b0a6b
+References: fate#323887
+
+Add Hyper-V tracing subsystem and trace hyperv_mmu_flush_tlb_others().
+Tracing is done the same way we do xen_mmu_flush_tlb_others().
+
+Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
+Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Reviewed-by: Stephen Hemminger <sthemmin@microsoft.com>
+Reviewed-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
+Cc: Andy Lutomirski <luto@kernel.org>
+Cc: Haiyang Zhang <haiyangz@microsoft.com>
+Cc: Jork Loeser <Jork.Loeser@microsoft.com>
+Cc: K. Y. Srinivasan <kys@microsoft.com>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Simon Xiao <sixiao@microsoft.com>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Cc: devel@linuxdriverproject.org
+Link: http://lkml.kernel.org/r/20170802160921.21791-10-vkuznets@redhat.com
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Acked-by: Olaf Hering <ohering@suse.de>
+---
+ MAINTAINERS | 1 +
+ arch/x86/hyperv/mmu.c | 7 +++++++
+ arch/x86/include/asm/trace/hyperv.h | 40 +++++++++++++++++++++++++++++++++++++
+ 3 files changed, 48 insertions(+)
+ create mode 100644 arch/x86/include/asm/trace/hyperv.h
+
+diff --git a/MAINTAINERS b/MAINTAINERS
+--- a/MAINTAINERS
++++ b/MAINTAINERS
+@@ -6258,6 +6258,7 @@ M: Stephen Hemminger <sthemmin@microsoft.com>
+ L: devel@linuxdriverproject.org
+ S: Maintained
+ F: arch/x86/include/asm/mshyperv.h
++F: arch/x86/include/asm/trace/hyperv.h
+ F: arch/x86/include/uapi/asm/hyperv.h
+ F: arch/x86/kernel/cpu/mshyperv.c
+ F: arch/x86/hyperv
+diff --git a/arch/x86/hyperv/mmu.c b/arch/x86/hyperv/mmu.c
+--- a/arch/x86/hyperv/mmu.c
++++ b/arch/x86/hyperv/mmu.c
+@@ -10,6 +10,9 @@
+ #include <asm/msr.h>
+ #include <asm/tlbflush.h>
+
++#define CREATE_TRACE_POINTS
++#include <asm/trace/hyperv.h>
++
+ /* HvFlushVirtualAddressSpace, HvFlushVirtualAddressList hypercalls */
+ struct hv_flush_pcpu {
+ u64 address_space;
+@@ -103,6 +106,8 @@ static void hyperv_flush_tlb_others(const struct cpumask *cpus,
+ u64 status = U64_MAX;
+ unsigned long flags;
+
++ trace_hyperv_mmu_flush_tlb_others(cpus, mm, start, end);
++
+ if (!pcpu_flush || !hv_hypercall_pg)
+ goto do_native;
+
+@@ -172,6 +177,8 @@ static void hyperv_flush_tlb_others_ex(const struct cpumask *cpus,
+ u64 status = U64_MAX;
+ unsigned long flags;
+
++ trace_hyperv_mmu_flush_tlb_others(cpus, mm, start, end);
++
+ if (!pcpu_flush_ex || !hv_hypercall_pg)
+ goto do_native;
+
+diff --git a/arch/x86/include/asm/trace/hyperv.h b/arch/x86/include/asm/trace/hyperv.h
+new file mode 100644
+index 000000000000..4253bca99989
+--- /dev/null
++++ b/arch/x86/include/asm/trace/hyperv.h
+@@ -0,0 +1,40 @@
++#undef TRACE_SYSTEM
++#define TRACE_SYSTEM hyperv
++
++#if !defined(_TRACE_HYPERV_H) || defined(TRACE_HEADER_MULTI_READ)
++#define _TRACE_HYPERV_H
++
++#include <linux/tracepoint.h>
++
++#if IS_ENABLED(CONFIG_HYPERV)
++
++TRACE_EVENT(hyperv_mmu_flush_tlb_others,
++ TP_PROTO(const struct cpumask *cpus,
++ struct mm_struct *mm, unsigned long start, unsigned long end),
++ TP_ARGS(cpus, mm, start, end),
++ TP_STRUCT__entry(
++ __field(unsigned int, ncpus)
++ __field(struct mm_struct *, mm)
++ __field(unsigned long, addr)
++ __field(unsigned long, end)
++ ),
++ TP_fast_assign(__entry->ncpus = cpumask_weight(cpus);
++ __entry->mm = mm;
++ __entry->addr = start;
++ __entry->end = end;
++ ),
++ TP_printk("ncpus %d mm %p addr %lx, end %lx",
++ __entry->ncpus, __entry->mm,
++ __entry->addr, __entry->end)
++ );
++
++#endif /* CONFIG_HYPERV */
++
++#undef TRACE_INCLUDE_PATH
++#define TRACE_INCLUDE_PATH asm/trace/
++#undef TRACE_INCLUDE_FILE
++#define TRACE_INCLUDE_FILE hyperv
++#endif /* _TRACE_HYPERV_H */
++
++/* This part must be outside protection */
++#include <trace/define_trace.h>
diff --git a/patches.suse/msft-hv-1455-netvsc-cleanup-datapath-switch.patch b/patches.suse/msft-hv-1455-netvsc-cleanup-datapath-switch.patch
new file mode 100644
index 0000000000..ecdba381be
--- /dev/null
+++ b/patches.suse/msft-hv-1455-netvsc-cleanup-datapath-switch.patch
@@ -0,0 +1,84 @@
+From: Stephen Hemminger <stephen@networkplumber.org>
+Date: Thu, 31 Aug 2017 16:16:12 -0700
+Patch-mainline: v4.14-rc1
+Subject: netvsc: cleanup datapath switch
+Git-commit: 9a0c48df0d77602da3958a4c8fc2abb9521b0ade
+References: fate#323887
+
+Use one routine for datapath up/down. Don't need to reopen
+the rndis layer.
+
+Signed-off-by: Stephen Hemminger <sthemmin@microsoft.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Acked-by: Olaf Hering <ohering@suse.de>
+---
+ drivers/net/hyperv/netvsc_drv.c | 38 +++++++-------------------------------
+ 1 file changed, 7 insertions(+), 31 deletions(-)
+
+diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
+--- a/drivers/net/hyperv/netvsc_drv.c
++++ b/drivers/net/hyperv/netvsc_drv.c
+@@ -1847,11 +1847,13 @@ static int netvsc_register_vf(struct net_device *vf_netdev)
+ return NOTIFY_OK;
+ }
+
+-static int netvsc_vf_up(struct net_device *vf_netdev)
++/* VF up/down change detected, schedule to change data path */
++static int netvsc_vf_changed(struct net_device *vf_netdev)
+ {
+ struct net_device_context *net_device_ctx;
+ struct netvsc_device *netvsc_dev;
+ struct net_device *ndev;
++ bool vf_is_up = netif_running(vf_netdev);
+
+ ndev = get_netvsc_byref(vf_netdev);
+ if (!ndev)
+@@ -1862,34 +1864,9 @@ static int netvsc_vf_up(struct net_device *vf_netdev)
+ if (!netvsc_dev)
+ return NOTIFY_DONE;
+
+- /* Bump refcount when datapath is acvive - Why? */
+- rndis_filter_open(netvsc_dev);
+-
+- /* notify the host to switch the data path. */
+- netvsc_switch_datapath(ndev, true);
+- netdev_info(ndev, "Data path switched to VF: %s\n", vf_netdev->name);
+-
+- return NOTIFY_OK;
+-}
+-
+-static int netvsc_vf_down(struct net_device *vf_netdev)
+-{
+- struct net_device_context *net_device_ctx;
+- struct netvsc_device *netvsc_dev;
+- struct net_device *ndev;
+-
+- ndev = get_netvsc_byref(vf_netdev);
+- if (!ndev)
+- return NOTIFY_DONE;
+-
+- net_device_ctx = netdev_priv(ndev);
+- netvsc_dev = rtnl_dereference(net_device_ctx->nvdev);
+- if (!netvsc_dev)
+- return NOTIFY_DONE;
+-
+- netvsc_switch_datapath(ndev, false);
+- netdev_info(ndev, "Data path switched from VF: %s\n", vf_netdev->name);
+- rndis_filter_close(netvsc_dev);
++ netvsc_switch_datapath(ndev, vf_is_up);
++ netdev_info(ndev, "Data path switched %s VF: %s\n",
++ vf_is_up ? "to" : "from", vf_netdev->name);
+
+ return NOTIFY_OK;
+ }
+@@ -2099,9 +2076,8 @@ static int netvsc_netdev_event(struct notifier_block *this,
+ case NETDEV_UNREGISTER:
+ return netvsc_unregister_vf(event_dev);
+ case NETDEV_UP:
+- return netvsc_vf_up(event_dev);
+ case NETDEV_DOWN:
+- return netvsc_vf_down(event_dev);
++ return netvsc_vf_changed(event_dev);
+ default:
+ return NOTIFY_DONE;
+ }
diff --git a/patches.suse/msft-hv-1456-netvsc-allow-driver-to-be-removed-even-if-VF-is-pres.patch b/patches.suse/msft-hv-1456-netvsc-allow-driver-to-be-removed-even-if-VF-is-pres.patch
new file mode 100644
index 0000000000..34193996ef
--- /dev/null
+++ b/patches.suse/msft-hv-1456-netvsc-allow-driver-to-be-removed-even-if-VF-is-pres.patch
@@ -0,0 +1,77 @@
+From: Stephen Hemminger <stephen@networkplumber.org>
+Date: Thu, 31 Aug 2017 16:16:13 -0700
+Patch-mainline: v4.14-rc1
+Subject: netvsc: allow driver to be removed even if VF is present
+Git-commit: ec158f77def2df084d9f62565357e3037b04bd3f
+References: fate#323887
+
+If VF is attached then can still allow netvsc driver module to
+be removed. Just have to make sure and do the cleanup.
+
+Also, avoid extra rtnl round trip when calling unregister.
+
+Signed-off-by: Stephen Hemminger <sthemmin@microsoft.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Acked-by: Olaf Hering <ohering@suse.de>
+---
+ drivers/net/hyperv/netvsc_drv.c | 17 +++++++++--------
+ 1 file changed, 9 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
+--- a/drivers/net/hyperv/netvsc_drv.c
++++ b/drivers/net/hyperv/netvsc_drv.c
+@@ -1839,9 +1839,6 @@ static int netvsc_register_vf(struct net_device *vf_netdev)
+
+ netdev_info(ndev, "VF registering: %s\n", vf_netdev->name);
+
+- /* Prevent this module from being unloaded while VF is registered */
+- try_module_get(THIS_MODULE);
+-
+ dev_hold(vf_netdev);
+ rcu_assign_pointer(net_device_ctx->vf_netdev, vf_netdev);
+ return NOTIFY_OK;
+@@ -1885,10 +1882,11 @@ static int netvsc_unregister_vf(struct net_device *vf_netdev)
+
+ netdev_info(ndev, "VF unregistering: %s\n", vf_netdev->name);
+
++ netdev_rx_handler_unregister(vf_netdev);
+ netdev_upper_dev_unlink(vf_netdev, ndev);
+ RCU_INIT_POINTER(net_device_ctx->vf_netdev, NULL);
+ dev_put(vf_netdev);
+- module_put(THIS_MODULE);
++
+ return NOTIFY_OK;
+ }
+
+@@ -1992,11 +1990,11 @@ no_net:
+
+ static int netvsc_remove(struct hv_device *dev)
+ {
+- struct net_device *net;
+ struct net_device_context *ndev_ctx;
++ struct net_device *vf_netdev;
++ struct net_device *net;
+
+ net = hv_get_drvdata(dev);
+-
+ if (net == NULL) {
+ dev_err(&dev->device, "No net device to remove\n");
+ return 0;
+@@ -2013,12 +2011,15 @@ static int netvsc_remove(struct hv_device *dev)
+ * removed. Also blocks mtu and channel changes.
+ */
+ rtnl_lock();
++ vf_netdev = rtnl_dereference(ndev_ctx->vf_netdev);
++ if (vf_netdev)
++ netvsc_unregister_vf(vf_netdev);
++
+ rndis_filter_device_remove(dev,
+ rtnl_dereference(ndev_ctx->nvdev));
++ unregister_netdevice(net);
+ rtnl_unlock();
+
+- unregister_netdev(net);
+-
+ hv_set_drvdata(dev, NULL);
+
+ free_percpu(ndev_ctx->vf_stats);
diff --git a/patches.suse/msft-hv-1457-hv_netvsc-Clean-up-an-unused-parameter-in-rndis_filt.patch b/patches.suse/msft-hv-1457-hv_netvsc-Clean-up-an-unused-parameter-in-rndis_filt.patch
new file mode 100644
index 0000000000..a09a26f5e2
--- /dev/null
+++ b/patches.suse/msft-hv-1457-hv_netvsc-Clean-up-an-unused-parameter-in-rndis_filt.patch
@@ -0,0 +1,65 @@
+From: Haiyang Zhang <haiyangz@microsoft.com>
+Date: Fri, 1 Sep 2017 14:30:04 -0700
+Patch-mainline: v4.14-rc1
+Subject: hv_netvsc: Clean up an unused parameter in rndis_filter_set_rss_param()
+Git-commit: 715e2ec532f6bffc8ee1cb9282c9e6cbf8809591
+References: fate#323887
+
+This patch removes the parameter, num_queue in
+rndis_filter_set_rss_param(), which is no longer in use.
+
+Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Acked-by: Olaf Hering <ohering@suse.de>
+---
+ drivers/net/hyperv/hyperv_net.h | 2 +-
+ drivers/net/hyperv/netvsc_drv.c | 2 +-
+ drivers/net/hyperv/rndis_filter.c | 5 ++---
+ 3 files changed, 4 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h
+--- a/drivers/net/hyperv/hyperv_net.h
++++ b/drivers/net/hyperv/hyperv_net.h
+@@ -213,7 +213,7 @@ void rndis_filter_update(struct netvsc_device *nvdev);
+ void rndis_filter_device_remove(struct hv_device *dev,
+ struct netvsc_device *nvdev);
+ int rndis_filter_set_rss_param(struct rndis_device *rdev,
+- const u8 *key, int num_queue);
++ const u8 *key);
+ int rndis_filter_receive(struct net_device *ndev,
+ struct netvsc_device *net_dev,
+ struct hv_device *dev,
+diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
+--- a/drivers/net/hyperv/netvsc_drv.c
++++ b/drivers/net/hyperv/netvsc_drv.c
+@@ -1424,7 +1424,7 @@ static int netvsc_set_rxfh(struct net_device *dev, const u32 *indir,
+ key = rndis_dev->rss_key;
+ }
+
+- return rndis_filter_set_rss_param(rndis_dev, key, ndev->num_chn);
++ return rndis_filter_set_rss_param(rndis_dev, key);
+ }
+
+ /* Hyper-V RNDIS protocol does not have ring in the HW sense.
+diff --git a/drivers/net/hyperv/rndis_filter.c b/drivers/net/hyperv/rndis_filter.c
+--- a/drivers/net/hyperv/rndis_filter.c
++++ b/drivers/net/hyperv/rndis_filter.c
+@@ -717,7 +717,7 @@ cleanup:
+ }
+
+ int rndis_filter_set_rss_param(struct rndis_device *rdev,
+- const u8 *rss_key, int num_queue)
++ const u8 *rss_key)
+ {
+ struct net_device *ndev = rdev->ndev;
+ struct rndis_request *request;
+@@ -1258,8 +1258,7 @@ struct netvsc_device *rndis_filter_device_add(struct hv_device *dev,
+ atomic_read(&net_device->open_chn) == net_device->num_chn);
+
+ /* ignore failues from setting rss parameters, still have channels */
+- rndis_filter_set_rss_param(rndis_device, netvsc_hash_key,
+- net_device->num_chn);
++ rndis_filter_set_rss_param(rndis_device, netvsc_hash_key);
+ out:
+ if (ret) {
+ net_device->max_chn = 1;
diff --git a/patches.suse/msft-hv-1458-hv_netvsc-Simplify-num_chn-checking-in-rndis_filter_.patch b/patches.suse/msft-hv-1458-hv_netvsc-Simplify-num_chn-checking-in-rndis_filter_.patch
new file mode 100644
index 0000000000..3a298f1e76
--- /dev/null
+++ b/patches.suse/msft-hv-1458-hv_netvsc-Simplify-num_chn-checking-in-rndis_filter_.patch
@@ -0,0 +1,40 @@
+From: Haiyang Zhang <haiyangz@microsoft.com>
+Date: Fri, 1 Sep 2017 14:30:05 -0700
+Patch-mainline: v4.14-rc1
+Subject: hv_netvsc: Simplify num_chn checking in rndis_filter_device_add()
+Git-commit: 5c4217d05d3258fa9999ad959c9b6da791b70bfa
+References: fate#323887
+
+The minus one and assignment to a local variable is not necessary.
+This patch simplifies it.
+
+Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Acked-by: Olaf Hering <ohering@suse.de>
+---
+ drivers/net/hyperv/rndis_filter.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/hyperv/rndis_filter.c b/drivers/net/hyperv/rndis_filter.c
+--- a/drivers/net/hyperv/rndis_filter.c
++++ b/drivers/net/hyperv/rndis_filter.c
+@@ -1067,7 +1067,7 @@ struct netvsc_device *rndis_filter_device_add(struct hv_device *dev,
+ struct ndis_recv_scale_cap rsscap;
+ u32 rsscap_size = sizeof(struct ndis_recv_scale_cap);
+ unsigned int gso_max_size = GSO_MAX_SIZE;
+- u32 mtu, size, num_rss_qs;
++ u32 mtu, size;
+ const struct cpumask *node_cpu_mask;
+ u32 num_possible_rss_qs;
+ int i, ret;
+@@ -1215,8 +1215,8 @@ struct netvsc_device *rndis_filter_device_add(struct hv_device *dev,
+ net_device->num_chn);
+
+ atomic_set(&net_device->open_chn, 1);
+- num_rss_qs = net_device->num_chn - 1;
+- if (num_rss_qs == 0)
++
++ if (net_device->num_chn == 1)
+ return net_device;
+
+ for (i = 1; i < net_device->num_chn; i++) {
diff --git a/patches.suse/msft-hv-1459-hv_netvsc-Simplify-the-limit-check-in-netvsc_set_cha.patch b/patches.suse/msft-hv-1459-hv_netvsc-Simplify-the-limit-check-in-netvsc_set_cha.patch
new file mode 100644
index 0000000000..67d0c1466e
--- /dev/null
+++ b/patches.suse/msft-hv-1459-hv_netvsc-Simplify-the-limit-check-in-netvsc_set_cha.patch
@@ -0,0 +1,39 @@
+From: Haiyang Zhang <haiyangz@microsoft.com>
+Date: Fri, 1 Sep 2017 14:30:06 -0700
+Patch-mainline: v4.14-rc1
+Subject: hv_netvsc: Simplify the limit check in netvsc_set_channels()
+Git-commit: 06be580ac7b650938cb3f2cf8cd02d73ff96d3e4
+References: fate#323887
+
+Because of the following code, net->num_tx_queues equals to
+VRSS_CHANNEL_MAX, and max_chn is less than or equals to VRSS_CHANNEL_MAX.
+
+netvsc_drv.c:
+alloc_etherdev_mq(sizeof(struct net_device_context),
+ VRSS_CHANNEL_MAX);
+rndis_filter.c:
+net_device->max_chn = min_t(u32, VRSS_CHANNEL_MAX, num_possible_rss_qs);
+
+So this patch removes the unnecessary limit check before comparing
+with "max_chn".
+
+Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Acked-by: Olaf Hering <ohering@suse.de>
+---
+ drivers/net/hyperv/netvsc_drv.c | 3 ---
+ 1 file changed, 3 deletions(-)
+
+diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
+--- a/drivers/net/hyperv/netvsc_drv.c
++++ b/drivers/net/hyperv/netvsc_drv.c
+@@ -830,9 +830,6 @@ static int netvsc_set_channels(struct net_device *net,
+ channels->rx_count || channels->tx_count || channels->other_count)
+ return -EINVAL;
+
+- if (count > net->num_tx_queues || count > VRSS_CHANNEL_MAX)
+- return -EINVAL;
+-
+ if (!nvdev || nvdev->destroy)
+ return -ENODEV;
+
diff --git a/patches.suse/msft-hv-1460-hv_netvsc-Fix-the-channel-limit-in-netvsc_set_rxfh.patch b/patches.suse/msft-hv-1460-hv_netvsc-Fix-the-channel-limit-in-netvsc_set_rxfh.patch
new file mode 100644
index 0000000000..35140eeaf7
--- /dev/null
+++ b/patches.suse/msft-hv-1460-hv_netvsc-Fix-the-channel-limit-in-netvsc_set_rxfh.patch
@@ -0,0 +1,29 @@
+From: Haiyang Zhang <haiyangz@microsoft.com>
+Date: Fri, 1 Sep 2017 14:30:07 -0700
+Patch-mainline: v4.14-rc1
+Subject: hv_netvsc: Fix the channel limit in netvsc_set_rxfh()
+Git-commit: db3cd7af9d0f174475cbcc02c0e96a5408fe2dc2
+References: fate#323887
+
+The limit of setting receive indirection table value should be
+the current number of channels, not the VRSS_CHANNEL_MAX.
+
+Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Acked-by: Olaf Hering <ohering@suse.de>
+---
+ drivers/net/hyperv/netvsc_drv.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
+--- a/drivers/net/hyperv/netvsc_drv.c
++++ b/drivers/net/hyperv/netvsc_drv.c
+@@ -1407,7 +1407,7 @@ static int netvsc_set_rxfh(struct net_device *dev, const u32 *indir,
+ rndis_dev = ndev->extension;
+ if (indir) {
+ for (i = 0; i < ITAB_NUM; i++)
+- if (indir[i] >= VRSS_CHANNEL_MAX)
++ if (indir[i] >= ndev->num_chn)
+ return -EINVAL;
+
+ for (i = 0; i < ITAB_NUM; i++)
diff --git a/patches.suse/msft-hv-1461-hv_netvsc-fix-deadlock-on-hotplug.patch b/patches.suse/msft-hv-1461-hv_netvsc-fix-deadlock-on-hotplug.patch
new file mode 100644
index 0000000000..c45504bdea
--- /dev/null
+++ b/patches.suse/msft-hv-1461-hv_netvsc-fix-deadlock-on-hotplug.patch
@@ -0,0 +1,291 @@
+From: Stephen Hemminger <stephen@networkplumber.org>
+Date: Wed, 6 Sep 2017 13:53:05 -0700
+Patch-mainline: v4.14-rc1
+Subject: hv_netvsc: fix deadlock on hotplug
+Git-commit: 8195b1396ec86dddbba443c74b2188b423556c74
+References: fate#323887
+
+When a virtual device is added dynamically (via host console), then
+the vmbus sends an offer message for the primary channel. The processing
+of this message for networking causes the network device to then
+initialize the sub channels.
+
+The problem is that setting up the sub channels needs to wait until
+the subsequent subchannel offers have been processed. These offers
+come in on the same ring buffer and work queue as where the primary
+offer is being processed; leading to a deadlock.
+
+This did not happen in older kernels, because the sub channel waiting
+logic was broken (it wasn't really waiting).
+
+The solution is to do the sub channel setup in its own work queue
+context that is scheduled by the primary channel setup; and then
+happens later.
+
+Fixes: 732e49850c5e ("netvsc: fix race on sub channel creation")
+Reported-by: Dexuan Cui <decui@microsoft.com>
+Signed-off-by: Stephen Hemminger <sthemmin@microsoft.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Acked-by: Olaf Hering <ohering@suse.de>
+---
+ drivers/net/hyperv/hyperv_net.h | 3 +
+ drivers/net/hyperv/netvsc.c | 3 +
+ drivers/net/hyperv/netvsc_drv.c | 11 +---
+ drivers/net/hyperv/rndis_filter.c | 122 ++++++++++++++++++++++++++------------
+ 4 files changed, 94 insertions(+), 45 deletions(-)
+
+diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h
+--- a/drivers/net/hyperv/hyperv_net.h
++++ b/drivers/net/hyperv/hyperv_net.h
+@@ -204,6 +204,8 @@ int netvsc_recv_callback(struct net_device *net,
+ const struct ndis_pkt_8021q_info *vlan);
+ void netvsc_channel_cb(void *context);
+ int netvsc_poll(struct napi_struct *napi, int budget);
++
++void rndis_set_subchannel(struct work_struct *w);
+ bool rndis_filter_opened(const struct netvsc_device *nvdev);
+ int rndis_filter_open(struct netvsc_device *nvdev);
+ int rndis_filter_close(struct netvsc_device *nvdev);
+@@ -782,6 +784,7 @@ struct netvsc_device {
+ u32 num_chn;
+
+ atomic_t open_chn;
++ struct work_struct subchan_work;
+ wait_queue_head_t subchan_open;
+
+ struct rndis_device *extension;
+diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c
+--- a/drivers/net/hyperv/netvsc.c
++++ b/drivers/net/hyperv/netvsc.c
+@@ -81,6 +81,7 @@ static struct netvsc_device *alloc_net_device(void)
+
+ init_completion(&net_device->channel_init_wait);
+ init_waitqueue_head(&net_device->subchan_open);
++ INIT_WORK(&net_device->subchan_work, rndis_set_subchannel);
+
+ return net_device;
+ }
+@@ -557,6 +558,8 @@ void netvsc_device_remove(struct hv_device *device)
+ = rtnl_dereference(net_device_ctx->nvdev);
+ int i;
+
++ cancel_work_sync(&net_device->subchan_work);
++
+ netvsc_disconnect_vsp(device);
+
+ RCU_INIT_POINTER(net_device_ctx->nvdev, NULL);
+diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
+--- a/drivers/net/hyperv/netvsc_drv.c
++++ b/drivers/net/hyperv/netvsc_drv.c
+@@ -853,10 +853,7 @@ static int netvsc_set_channels(struct net_device *net,
+ rndis_filter_device_remove(dev, nvdev);
+
+ nvdev = rndis_filter_device_add(dev, &device_info);
+- if (!IS_ERR(nvdev)) {
+- netif_set_real_num_tx_queues(net, nvdev->num_chn);
+- netif_set_real_num_rx_queues(net, nvdev->num_chn);
+- } else {
++ if (IS_ERR(nvdev)) {
+ ret = PTR_ERR(nvdev);
+ device_info.num_chn = orig;
+ nvdev = rndis_filter_device_add(dev, &device_info);
+@@ -1954,9 +1951,6 @@ static int netvsc_probe(struct hv_device *dev,
+ NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX;
+ net->vlan_features = net->features;
+
+- netif_set_real_num_tx_queues(net, nvdev->num_chn);
+- netif_set_real_num_rx_queues(net, nvdev->num_chn);
+-
+ netdev_lockdep_set_classes(net);
+
+ /* MTU range: 68 - 1500 or 65521 */
+@@ -2012,9 +2006,10 @@ static int netvsc_remove(struct hv_device *dev)
+ if (vf_netdev)
+ netvsc_unregister_vf(vf_netdev);
+
++ unregister_netdevice(net);
++
+ rndis_filter_device_remove(dev,
+ rtnl_dereference(ndev_ctx->nvdev));
+- unregister_netdevice(net);
+ rtnl_unlock();
+
+ hv_set_drvdata(dev, NULL);
+diff --git a/drivers/net/hyperv/rndis_filter.c b/drivers/net/hyperv/rndis_filter.c
+--- a/drivers/net/hyperv/rndis_filter.c
++++ b/drivers/net/hyperv/rndis_filter.c
+@@ -1039,8 +1039,6 @@ static void netvsc_sc_open(struct vmbus_channel *new_sc)
+
+ /* Set the channel before opening.*/
+ nvchan->channel = new_sc;
+- netif_napi_add(ndev, &nvchan->napi,
+- netvsc_poll, NAPI_POLL_WEIGHT);
+
+ ret = vmbus_open(new_sc, nvscdev->ring_size * PAGE_SIZE,
+ nvscdev->ring_size * PAGE_SIZE, NULL, 0,
+@@ -1048,12 +1046,88 @@ static void netvsc_sc_open(struct vmbus_channel *new_sc)
+ if (ret == 0)
+ napi_enable(&nvchan->napi);
+ else
+- netif_napi_del(&nvchan->napi);
++ netdev_notice(ndev, "sub channel open failed: %d\n", ret);
+
+ atomic_inc(&nvscdev->open_chn);
+ wake_up(&nvscdev->subchan_open);
+ }
+
++/* Open sub-channels after completing the handling of the device probe.
++ * This breaks overlap of processing the host message for the
++ * new primary channel with the initialization of sub-channels.
++ */
++void rndis_set_subchannel(struct work_struct *w)
++{
++ struct netvsc_device *nvdev
++ = container_of(w, struct netvsc_device, subchan_work);
++ struct nvsp_message *init_packet = &nvdev->channel_init_pkt;
++ struct net_device_context *ndev_ctx;
++ struct rndis_device *rdev;
++ struct net_device *ndev;
++ struct hv_device *hv_dev;
++ int i, ret;
++
++ if (!rtnl_trylock()) {
++ schedule_work(w);
++ return;
++ }
++
++ rdev = nvdev->extension;
++ if (!rdev)
++ goto unlock; /* device was removed */
++
++ ndev = rdev->ndev;
++ ndev_ctx = netdev_priv(ndev);
++ hv_dev = ndev_ctx->device_ctx;
++
++ memset(init_packet, 0, sizeof(struct nvsp_message));
++ init_packet->hdr.msg_type = NVSP_MSG5_TYPE_SUBCHANNEL;
++ init_packet->msg.v5_msg.subchn_req.op = NVSP_SUBCHANNEL_ALLOCATE;
++ init_packet->msg.v5_msg.subchn_req.num_subchannels =
++ nvdev->num_chn - 1;
++ ret = vmbus_sendpacket(hv_dev->channel, init_packet,
++ sizeof(struct nvsp_message),
++ (unsigned long)init_packet,
++ VM_PKT_DATA_INBAND,
++ VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
++ if (ret) {
++ netdev_err(ndev, "sub channel allocate send failed: %d\n", ret);
++ goto failed;
++ }
++
++ wait_for_completion(&nvdev->channel_init_wait);
++ if (init_packet->msg.v5_msg.subchn_comp.status != NVSP_STAT_SUCCESS) {
++ netdev_err(ndev, "sub channel request failed\n");
++ goto failed;
++ }
++
++ nvdev->num_chn = 1 +
++ init_packet->msg.v5_msg.subchn_comp.num_subchannels;
++
++ /* wait for all sub channels to open */
++ wait_event(nvdev->subchan_open,
++ atomic_read(&nvdev->open_chn) == nvdev->num_chn);
++
++ /* ignore failues from setting rss parameters, still have channels */
++ rndis_filter_set_rss_param(rdev, netvsc_hash_key);
++
++ netif_set_real_num_tx_queues(ndev, nvdev->num_chn);
++ netif_set_real_num_rx_queues(ndev, nvdev->num_chn);
++
++ rtnl_unlock();
++ return;
++
++failed:
++ /* fallback to only primary channel */
++ for (i = 1; i < nvdev->num_chn; i++)
++ netif_napi_del(&nvdev->chan_table[i].napi);
++
++ nvdev->max_chn = 1;
++ nvdev->num_chn = 1;
++unlock:
++ rtnl_unlock();
++}
++
+ struct netvsc_device *rndis_filter_device_add(struct hv_device *dev,
+ struct netvsc_device_info *device_info)
+ {
+@@ -1063,7 +1137,6 @@ struct netvsc_device *rndis_filter_device_add(struct hv_device *dev,
+ struct rndis_device *rndis_device;
+ struct ndis_offload hwcaps;
+ struct ndis_offload_params offloads;
+- struct nvsp_message *init_packet;
+ struct ndis_recv_scale_cap rsscap;
+ u32 rsscap_size = sizeof(struct ndis_recv_scale_cap);
+ unsigned int gso_max_size = GSO_MAX_SIZE;
+@@ -1215,9 +1288,7 @@ struct netvsc_device *rndis_filter_device_add(struct hv_device *dev,
+ net_device->num_chn);
+
+ atomic_set(&net_device->open_chn, 1);
+-
+- if (net_device->num_chn == 1)
+- return net_device;
++ vmbus_set_sc_create_callback(dev->channel, netvsc_sc_open);
+
+ for (i = 1; i < net_device->num_chn; i++) {
+ ret = netvsc_alloc_recv_comp_ring(net_device, i);
+@@ -1228,38 +1299,15 @@ struct netvsc_device *rndis_filter_device_add(struct hv_device *dev,
+ }
+ }
+
+- vmbus_set_sc_create_callback(dev->channel, netvsc_sc_open);
++ for (i = 1; i < net_device->num_chn; i++)
++ netif_napi_add(net, &net_device->chan_table[i].napi,
++ netvsc_poll, NAPI_POLL_WEIGHT);
+
+- init_packet = &net_device->channel_init_pkt;
+- memset(init_packet, 0, sizeof(struct nvsp_message));
+- init_packet->hdr.msg_type = NVSP_MSG5_TYPE_SUBCHANNEL;
+- init_packet->msg.v5_msg.subchn_req.op = NVSP_SUBCHANNEL_ALLOCATE;
+- init_packet->msg.v5_msg.subchn_req.num_subchannels =
+- net_device->num_chn - 1;
+- ret = vmbus_sendpacket(dev->channel, init_packet,
+- sizeof(struct nvsp_message),
+- (unsigned long)init_packet,
+- VM_PKT_DATA_INBAND,
+- VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
+- if (ret)
+- goto out;
+-
+- wait_for_completion(&net_device->channel_init_wait);
+- if (init_packet->msg.v5_msg.subchn_comp.status != NVSP_STAT_SUCCESS) {
+- ret = -ENODEV;
+- goto out;
+- }
++ if (net_device->num_chn > 1)
++ schedule_work(&net_device->subchan_work);
+
+- net_device->num_chn = 1 +
+- init_packet->msg.v5_msg.subchn_comp.num_subchannels;
+-
+- /* wait for all sub channels to open */
+- wait_event(net_device->subchan_open,
+- atomic_read(&net_device->open_chn) == net_device->num_chn);
+-
+- /* ignore failues from setting rss parameters, still have channels */
+- rndis_filter_set_rss_param(rndis_device, netvsc_hash_key);
+ out:
++ /* if unavailable, just proceed with one queue */
+ if (ret) {
+ net_device->max_chn = 1;
+ net_device->num_chn = 1;
+@@ -1280,10 +1328,10 @@ void rndis_filter_device_remove(struct hv_device *dev,
+ /* Halt and release the rndis device */
+ rndis_filter_halt_device(rndis_dev);
+
+- kfree(rndis_dev);
+ net_dev->extension = NULL;
+
+ netvsc_device_remove(dev);
++ kfree(rndis_dev);
+ }
+
+ int rndis_filter_open(struct netvsc_device *nvdev)
diff --git a/patches.suse/msft-hv-1462-hv_netvsc-avoid-unnecessary-wakeups-on-subchannel-cr.patch b/patches.suse/msft-hv-1462-hv_netvsc-avoid-unnecessary-wakeups-on-subchannel-cr.patch
new file mode 100644
index 0000000000..fee840dcc0
--- /dev/null
+++ b/patches.suse/msft-hv-1462-hv_netvsc-avoid-unnecessary-wakeups-on-subchannel-cr.patch
@@ -0,0 +1,31 @@
+From: Stephen Hemminger <stephen@networkplumber.org>
+Date: Wed, 6 Sep 2017 13:53:06 -0700
+Patch-mainline: v4.14-rc1
+Subject: hv_netvsc: avoid unnecessary wakeups on subchannel creation
+Git-commit: 8f2bb1de73344dbedd4195016b782bee7bf3598f
+References: fate#323887
+
+Only need to wakeup the initiator after all sub-channels
+are opened.
+
+Signed-off-by: Stephen Hemminger <sthemmin@microsoft.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Acked-by: Olaf Hering <ohering@suse.de>
+---
+ drivers/net/hyperv/rndis_filter.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/hyperv/rndis_filter.c b/drivers/net/hyperv/rndis_filter.c
+--- a/drivers/net/hyperv/rndis_filter.c
++++ b/drivers/net/hyperv/rndis_filter.c
+@@ -1048,8 +1048,8 @@ static void netvsc_sc_open(struct vmbus_channel *new_sc)
+ else
+ netdev_notice(ndev, "sub channel open failed: %d\n", ret);
+
+- atomic_inc(&nvscdev->open_chn);
+- wake_up(&nvscdev->subchan_open);
++ if (atomic_inc_return(&nvscdev->open_chn) == nvscdev->num_chn)
++ wake_up(&nvscdev->subchan_open);
+ }
+
+ /* Open sub-channels after completing the handling of the device probe.
diff --git a/patches.suse/msft-hv-1464-x86-hyper-v-Remove-duplicated-HV_X64_EX_PROCESSOR_MA.patch b/patches.suse/msft-hv-1464-x86-hyper-v-Remove-duplicated-HV_X64_EX_PROCESSOR_MA.patch
new file mode 100644
index 0000000000..737334dc77
--- /dev/null
+++ b/patches.suse/msft-hv-1464-x86-hyper-v-Remove-duplicated-HV_X64_EX_PROCESSOR_MA.patch
@@ -0,0 +1,46 @@
+From: Vitaly Kuznetsov <vkuznets@redhat.com>
+Date: Mon, 11 Sep 2017 17:06:20 +0200
+Patch-mainline: v4.14-rc1
+Subject: x86/hyper-v: Remove duplicated HV_X64_EX_PROCESSOR_MASKS_RECOMMENDED definition
+Git-commit: 1278f58cdee63cfbb04e5624474a291c81a7a13b
+References: fate#323887
+
+Commits:
+
+ 7dcf90e9e032 ("PCI: hv: Use vPCI protocol version 1.2")
+ 628f54cc6451 ("x86/hyper-v: Support extended CPU ranges for TLB flush hypercalls")
+
+added the same definition and they came in through different trees.
+Fix the duplication.
+
+Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
+Cc: Haiyang Zhang <haiyangz@microsoft.com>
+Cc: K. Y. Srinivasan <kys@microsoft.com>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Stephen Hemminger <sthemmin@microsoft.com>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Cc: devel@linuxdriverproject.org
+Link: http://lkml.kernel.org/r/20170911150620.3998-1-vkuznets@redhat.com
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Acked-by: Olaf Hering <ohering@suse.de>
+---
+ arch/x86/include/uapi/asm/hyperv.h | 6 ------
+ 1 file changed, 6 deletions(-)
+
+diff --git a/arch/x86/include/uapi/asm/hyperv.h b/arch/x86/include/uapi/asm/hyperv.h
+--- a/arch/x86/include/uapi/asm/hyperv.h
++++ b/arch/x86/include/uapi/asm/hyperv.h
+@@ -152,12 +152,6 @@
+ /* Recommend using the newer ExProcessorMasks interface */
+ #define HV_X64_EX_PROCESSOR_MASKS_RECOMMENDED (1 << 11)
+
+-/*
+- * HV_VP_SET available
+- */
+-#define HV_X64_EX_PROCESSOR_MASKS_RECOMMENDED (1 << 11)
+-
+-
+ /*
+ * Crash notification flag.
+ */
diff --git a/patches.suse/msft-hv-1465-netvsc-increase-default-receive-buffer-size.patch b/patches.suse/msft-hv-1465-netvsc-increase-default-receive-buffer-size.patch
new file mode 100644
index 0000000000..ceb3205368
--- /dev/null
+++ b/patches.suse/msft-hv-1465-netvsc-increase-default-receive-buffer-size.patch
@@ -0,0 +1,32 @@
+From: Stephen Hemminger <stephen@networkplumber.org>
+Date: Thu, 14 Sep 2017 09:31:07 -0700
+Patch-mainline: v4.14-rc1
+Subject: netvsc: increase default receive buffer size
+Git-commit: 5023a6db73196695f4cc2db1a0eb37957ca27772
+References: fate#323887
+
+The default receive buffer size was reduced by recent change
+to a value which was appropriate for 10G and Windows Server 2016.
+But the value is too small for full performance with 40G on Azure.
+Increase the default back to maximum supported by host.
+
+Fixes: 8b5327975ae1 ("netvsc: allow controlling send/recv buffer size")
+Signed-off-by: Stephen Hemminger <sthemmin@microsoft.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Acked-by: Olaf Hering <ohering@suse.de>
+---
+ drivers/net/hyperv/netvsc_drv.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
+--- a/drivers/net/hyperv/netvsc_drv.c
++++ b/drivers/net/hyperv/netvsc_drv.c
+@@ -49,7 +49,7 @@
+ #define NETVSC_MIN_TX_SECTIONS 10
+ #define NETVSC_DEFAULT_TX 192 /* ~1M */
+ #define NETVSC_MIN_RX_SECTIONS 10 /* ~64K */
+-#define NETVSC_DEFAULT_RX 2048 /* ~4M */
++#define NETVSC_DEFAULT_RX 10485 /* Max ~16M */
+
+ #define LINKCHANGE_INT (2 * HZ)
+ #define VF_TAKEOVER_INT (HZ / 10)
diff --git a/patches.suse/msft-hv-1466-hv_netvsc-fix-send-buffer-failure-on-MTU-change.patch b/patches.suse/msft-hv-1466-hv_netvsc-fix-send-buffer-failure-on-MTU-change.patch
new file mode 100644
index 0000000000..d1c01d2699
--- /dev/null
+++ b/patches.suse/msft-hv-1466-hv_netvsc-fix-send-buffer-failure-on-MTU-change.patch
@@ -0,0 +1,122 @@
+From: Alex Ng <alexng@microsoft.com>
+Date: Wed, 20 Sep 2017 11:17:35 -0700
+Patch-mainline: v4.14-rc2
+Subject: hv_netvsc: fix send buffer failure on MTU change
+Git-commit: 0ab09befdbb7ca9b969d6206108629ddff43876e
+References: fate#323887
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+If MTU is changed the host would reject the send buffer change.
+This problem is result of recent change to allow changing send
+buffer size.
+
+Every time we change the MTU, we store the previous net_device section
+count before destroying the buffer, but we don’t store the previous
+section size. When we reinitialize the buffer, its size is calculated
+by multiplying the previous count and previous size. Since we
+continuously increase the MTU, the host returns us a decreasing count
+value while the section size is reinitialized to 1728 bytes every
+time.
+
+This eventually leads to a condition where the calculated buf_size is
+so small that the host rejects it.
+
+Fixes: 8b5327975ae1 ("netvsc: allow controlling send/recv buffer size")
+Signed-off-by: Alex Ng <alexng@microsoft.com>
+Signed-off-by: Stephen Hemminger <sthemmin@microsoft.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Acked-by: Olaf Hering <ohering@suse.de>
+---
+ drivers/net/hyperv/hyperv_net.h | 2 ++
+ drivers/net/hyperv/netvsc.c | 7 ++-----
+ drivers/net/hyperv/netvsc_drv.c | 8 ++++++++
+ 3 files changed, 12 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h
+--- a/drivers/net/hyperv/hyperv_net.h
++++ b/drivers/net/hyperv/hyperv_net.h
+@@ -150,6 +150,8 @@ struct netvsc_device_info {
+ u32 num_chn;
+ u32 send_sections;
+ u32 recv_sections;
++ u32 send_section_size;
++ u32 recv_section_size;
+ };
+
+ enum rndis_device_state {
+diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c
+--- a/drivers/net/hyperv/netvsc.c
++++ b/drivers/net/hyperv/netvsc.c
+@@ -76,9 +76,6 @@ static struct netvsc_device *alloc_net_device(void)
+ net_device->max_pkt = RNDIS_MAX_PKT_DEFAULT;
+ net_device->pkt_align = RNDIS_PKT_ALIGN_DEFAULT;
+
+- net_device->recv_section_size = NETVSC_RECV_SECTION_SIZE;
+- net_device->send_section_size = NETVSC_SEND_SECTION_SIZE;
+-
+ init_completion(&net_device->channel_init_wait);
+ init_waitqueue_head(&net_device->subchan_open);
+ INIT_WORK(&net_device->subchan_work, rndis_set_subchannel);
+@@ -262,7 +259,7 @@ static int netvsc_init_buf(struct hv_device *device,
+ int ret = 0;
+
+ /* Get receive buffer area. */
+- buf_size = device_info->recv_sections * net_device->recv_section_size;
++ buf_size = device_info->recv_sections * device_info->recv_section_size;
+ buf_size = roundup(buf_size, PAGE_SIZE);
+
+ net_device->recv_buf = vzalloc(buf_size);
+@@ -344,7 +341,7 @@ static int netvsc_init_buf(struct hv_device *device,
+ goto cleanup;
+
+ /* Now setup the send buffer. */
+- buf_size = device_info->send_sections * net_device->send_section_size;
++ buf_size = device_info->send_sections * device_info->send_section_size;
+ buf_size = round_up(buf_size, PAGE_SIZE);
+
+ net_device->send_buf = vzalloc(buf_size);
+diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
+--- a/drivers/net/hyperv/netvsc_drv.c
++++ b/drivers/net/hyperv/netvsc_drv.c
+@@ -848,7 +848,9 @@ static int netvsc_set_channels(struct net_device *net,
+ device_info.num_chn = count;
+ device_info.ring_size = ring_size;
+ device_info.send_sections = nvdev->send_section_cnt;
++ device_info.send_section_size = nvdev->send_section_size;
+ device_info.recv_sections = nvdev->recv_section_cnt;
++ device_info.recv_section_size = nvdev->recv_section_size;
+
+ rndis_filter_device_remove(dev, nvdev);
+
+@@ -963,7 +965,9 @@ static int netvsc_change_mtu(struct net_device *ndev, int mtu)
+ device_info.ring_size = ring_size;
+ device_info.num_chn = nvdev->num_chn;
+ device_info.send_sections = nvdev->send_section_cnt;
++ device_info.send_section_size = nvdev->send_section_size;
+ device_info.recv_sections = nvdev->recv_section_cnt;
++ device_info.recv_section_size = nvdev->recv_section_size;
+
+ rndis_filter_device_remove(hdev, nvdev);
+
+@@ -1485,7 +1489,9 @@ static int netvsc_set_ringparam(struct net_device *ndev,
+ device_info.num_chn = nvdev->num_chn;
+ device_info.ring_size = ring_size;
+ device_info.send_sections = new_tx;
++ device_info.send_section_size = nvdev->send_section_size;
+ device_info.recv_sections = new_rx;
++ device_info.recv_section_size = nvdev->recv_section_size;
+
+ netif_device_detach(ndev);
+ was_opened = rndis_filter_opened(nvdev);
+@@ -1934,7 +1940,9 @@ static int netvsc_probe(struct hv_device *dev,
+ device_info.ring_size = ring_size;
+ device_info.num_chn = VRSS_CHANNEL_DEFAULT;
+ device_info.send_sections = NETVSC_DEFAULT_TX;
++ device_info.send_section_size = NETVSC_SEND_SECTION_SIZE;
+ device_info.recv_sections = NETVSC_DEFAULT_RX;
++ device_info.recv_section_size = NETVSC_RECV_SECTION_SIZE;
+
+ nvdev = rndis_filter_device_add(dev, &device_info);
+ if (IS_ERR(nvdev)) {
diff --git a/patches.suse/msft-hv-1467-vmbus-don-t-acquire-the-mutex-in-vmbus_hvsock_device.patch b/patches.suse/msft-hv-1467-vmbus-don-t-acquire-the-mutex-in-vmbus_hvsock_device.patch
new file mode 100644
index 0000000000..9515e260cc
--- /dev/null
+++ b/patches.suse/msft-hv-1467-vmbus-don-t-acquire-the-mutex-in-vmbus_hvsock_device.patch
@@ -0,0 +1,45 @@
+From: Dexuan Cui <decui@microsoft.com>
+Date: Thu, 21 Sep 2017 23:41:47 -0700
+Patch-mainline: v4.14-rc4
+Subject: vmbus: don't acquire the mutex in vmbus_hvsock_device_unregister()
+Git-commit: 33c150c2ee4a65a59190a124b45d05b1abf9478e
+References: fate#323887
+
+Due to commit 54a66265d675 ("Drivers: hv: vmbus: Fix rescind handling"),
+we need this patch to resolve the below deadlock:
+
+after we get the mutex in vmbus_hvsock_device_unregister() and call
+vmbus_device_unregister() -> device_unregister() -> ... -> device_release()
+-> vmbus_device_release(), we'll get a deadlock, because
+vmbus_device_release() tries to get the same mutex.
+
+Signed-off-by: Dexuan Cui <decui@microsoft.com>
+Cc: K. Y. Srinivasan <kys@microsoft.com>
+Cc: Haiyang Zhang <haiyangz@microsoft.com>
+Cc: Stephen Hemminger <sthemmin@microsoft.com>
+Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
+Cc: stable@vger.kernel.org (4.13 and above)
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Acked-by: Olaf Hering <ohering@suse.de>
+---
+ drivers/hv/channel_mgmt.c | 4 ----
+ 1 file changed, 4 deletions(-)
+
+diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c
+--- a/drivers/hv/channel_mgmt.c
++++ b/drivers/hv/channel_mgmt.c
+@@ -936,14 +936,10 @@ static void vmbus_onoffer_rescind(struct vmbus_channel_message_header *hdr)
+
+ void vmbus_hvsock_device_unregister(struct vmbus_channel *channel)
+ {
+- mutex_lock(&vmbus_connection.channel_mutex);
+-
+ BUG_ON(!is_hvsock_channel(channel));
+
+ channel->rescind = true;
+ vmbus_device_unregister(channel->device_obj);
+-
+- mutex_unlock(&vmbus_connection.channel_mutex);
+ }
+ EXPORT_SYMBOL_GPL(vmbus_hvsock_device_unregister);
+
diff --git a/patches.suse/msft-hv-1468-Drivers-hv-fcopy-restore-correct-transfer-length.patch b/patches.suse/msft-hv-1468-Drivers-hv-fcopy-restore-correct-transfer-length.patch
new file mode 100644
index 0000000000..37be9e5ce0
--- /dev/null
+++ b/patches.suse/msft-hv-1468-Drivers-hv-fcopy-restore-correct-transfer-length.patch
@@ -0,0 +1,52 @@
+From: Olaf Hering <olaf@aepfle.de>
+Date: Thu, 21 Sep 2017 23:41:48 -0700
+Patch-mainline: v4.14-rc4
+Subject: Drivers: hv: fcopy: restore correct transfer length
+Git-commit: 549e658a0919e355a2b2144dc380b3729bef7f3e
+References: fate#323887
+
+Till recently the expected length of bytes read by the
+daemon did depend on the context. It was either hv_start_fcopy or
+hv_do_fcopy. The daemon had a buffer size of two pages, which was much
+larger than needed.
+
+Now the expected length of bytes read by the
+daemon changed slightly. For START_FILE_COPY it is still the size of
+hv_start_fcopy. But for WRITE_TO_FILE and the other operations it is as
+large as the buffer that arrived via vmbus. In case of WRITE_TO_FILE
+that is slightly larger than a struct hv_do_fcopy. Since the buffer in
+the daemon was still larger everything was fine.
+
+Currently, the daemon reads only what is actually needed.
+The new buffer layout is as large as a struct hv_do_fcopy, for the
+WRITE_TO_FILE operation. Since the kernel expects a slightly larger
+size, hvt_op_read will return -EINVAL because the daemon will read
+slightly less than expected. Address this by restoring the expected
+buffer size in case of WRITE_TO_FILE.
+
+Fixes: 'c7e490fc23eb ("Drivers: hv: fcopy: convert to hv_utils_transport")'
+Fixes: '3f2baa8a7d2e ("Tools: hv: update buffer handling in hv_fcopy_daemon")'
+
+Signed-off-by: Olaf Hering <olaf@aepfle.de>
+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: Olaf Hering <ohering@suse.de>
+---
+ drivers/hv/hv_fcopy.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/hv/hv_fcopy.c b/drivers/hv/hv_fcopy.c
+--- a/drivers/hv/hv_fcopy.c
++++ b/drivers/hv/hv_fcopy.c
+@@ -170,6 +170,10 @@ static void fcopy_send_data(struct work_struct *dummy)
+ out_src = smsg_out;
+ break;
+
++ case WRITE_TO_FILE:
++ out_src = fcopy_transaction.fcopy_msg;
++ out_len = sizeof(struct hv_do_fcopy);
++ break;
+ default:
+ out_src = fcopy_transaction.fcopy_msg;
+ out_len = fcopy_transaction.recv_len;
diff --git a/patches.suse/msft-hv-1470-Drivers-hv-vmbus-Fix-bugs-in-rescind-handling.patch b/patches.suse/msft-hv-1470-Drivers-hv-vmbus-Fix-bugs-in-rescind-handling.patch
new file mode 100644
index 0000000000..4ab7090d7f
--- /dev/null
+++ b/patches.suse/msft-hv-1470-Drivers-hv-vmbus-Fix-bugs-in-rescind-handling.patch
@@ -0,0 +1,196 @@
+From: "K. Y. Srinivasan" <kys@microsoft.com>
+Date: Fri, 29 Sep 2017 21:09:36 -0700
+Patch-mainline: v4.14-rc5
+Subject: Drivers: hv: vmbus: Fix bugs in rescind handling
+Git-commit: 192b2d78722ffea188e5ec6ae5d55010dce05a4b
+References: fate#323887
+
+This patch addresses the following bugs in the current rescind handling code:
+
+1. Fixes a race condition where we may be invoking hv_process_channel_removal()
+on an already freed channel.
+
+2. Prevents indefinite wait when rescinding sub-channels by correctly setting
+the probe_complete state.
+
+I would like to thank Dexuan for patiently reviewing earlier versions of this
+patch and identifying many of the issues fixed here.
+
+Greg, please apply this to 4.14-final.
+
+Fixes: '54a66265d675 ("Drivers: hv: vmbus: Fix rescind handling")'
+
+Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
+Reviewed-by: Dexuan Cui <decui@microsoft.com>
+Cc: stable@vger.kernel.org # (4.13 and above)
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Acked-by: Olaf Hering <ohering@suse.de>
+---
+ drivers/hv/channel.c | 6 +++---
+ drivers/hv/channel_mgmt.c | 37 ++++++++++++++++++-------------------
+ drivers/hv/vmbus_drv.c | 3 +--
+ include/linux/hyperv.h | 2 +-
+ 4 files changed, 23 insertions(+), 25 deletions(-)
+
+diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c
+--- a/drivers/hv/channel.c
++++ b/drivers/hv/channel.c
+@@ -640,6 +640,7 @@ void vmbus_close(struct vmbus_channel *channel)
+ */
+ return;
+ }
++ mutex_lock(&vmbus_connection.channel_mutex);
+ /*
+ * Close all the sub-channels first and then close the
+ * primary channel.
+@@ -648,16 +649,15 @@ void vmbus_close(struct vmbus_channel *channel)
+ cur_channel = list_entry(cur, struct vmbus_channel, sc_list);
+ vmbus_close_internal(cur_channel);
+ if (cur_channel->rescind) {
+- mutex_lock(&vmbus_connection.channel_mutex);
+- hv_process_channel_removal(cur_channel,
++ hv_process_channel_removal(
+ cur_channel->offermsg.child_relid);
+- mutex_unlock(&vmbus_connection.channel_mutex);
+ }
+ }
+ /*
+ * Now close the primary.
+ */
+ vmbus_close_internal(channel);
++ mutex_unlock(&vmbus_connection.channel_mutex);
+ }
+ EXPORT_SYMBOL_GPL(vmbus_close);
+
+diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c
+--- a/drivers/hv/channel_mgmt.c
++++ b/drivers/hv/channel_mgmt.c
+@@ -159,7 +159,7 @@ static void vmbus_rescind_cleanup(struct vmbus_channel *channel)
+
+
+ spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags);
+-
++ channel->rescind = true;
+ list_for_each_entry(msginfo, &vmbus_connection.chn_msg_list,
+ msglistentry) {
+
+@@ -381,14 +381,21 @@ static void vmbus_release_relid(u32 relid)
+ true);
+ }
+
+-void hv_process_channel_removal(struct vmbus_channel *channel, u32 relid)
++void hv_process_channel_removal(u32 relid)
+ {
+ unsigned long flags;
+- struct vmbus_channel *primary_channel;
++ struct vmbus_channel *primary_channel, *channel;
+
+- BUG_ON(!channel->rescind);
+ BUG_ON(!mutex_is_locked(&vmbus_connection.channel_mutex));
+
++ /*
++ * Make sure channel is valid as we may have raced.
++ */
++ channel = relid2channel(relid);
++ if (!channel)
++ return;
++
++ BUG_ON(!channel->rescind);
+ if (channel->target_cpu != get_cpu()) {
+ put_cpu();
+ smp_call_function_single(channel->target_cpu,
+@@ -515,6 +522,7 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel)
+ if (!fnew) {
+ if (channel->sc_creation_callback != NULL)
+ channel->sc_creation_callback(newchannel);
++ newchannel->probe_done = true;
+ return;
+ }
+
+@@ -834,7 +842,6 @@ 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 device *dev;
+
+ rescind = (struct vmbus_channel_rescind_offer *)hdr;
+@@ -873,16 +880,6 @@ static void vmbus_onoffer_rescind(struct vmbus_channel_message_header *hdr)
+ return;
+ }
+
+- spin_lock_irqsave(&channel->lock, flags);
+- channel->rescind = true;
+- spin_unlock_irqrestore(&channel->lock, flags);
+-
+- /*
+- * Now that we have posted the rescind state, perform
+- * rescind related cleanup.
+- */
+- vmbus_rescind_cleanup(channel);
+-
+ /*
+ * Now wait for offer handling to complete.
+ */
+@@ -901,6 +898,7 @@ static void vmbus_onoffer_rescind(struct vmbus_channel_message_header *hdr)
+ if (channel->device_obj) {
+ if (channel->chn_rescind_callback) {
+ channel->chn_rescind_callback(channel);
++ vmbus_rescind_cleanup(channel);
+ return;
+ }
+ /*
+@@ -909,6 +907,7 @@ static void vmbus_onoffer_rescind(struct vmbus_channel_message_header *hdr)
+ */
+ dev = get_device(&channel->device_obj->device);
+ if (dev) {
++ vmbus_rescind_cleanup(channel);
+ vmbus_device_unregister(channel->device_obj);
+ put_device(dev);
+ }
+@@ -921,16 +920,16 @@ static void vmbus_onoffer_rescind(struct vmbus_channel_message_header *hdr)
+ * 1. Close all sub-channels first
+ * 2. Then close the primary channel.
+ */
++ mutex_lock(&vmbus_connection.channel_mutex);
++ vmbus_rescind_cleanup(channel);
+ if (channel->state == CHANNEL_OPEN_STATE) {
+ /*
+ * The channel is currently not open;
+ * it is safe for us to cleanup the channel.
+ */
+- mutex_lock(&vmbus_connection.channel_mutex);
+- hv_process_channel_removal(channel,
+- channel->offermsg.child_relid);
+- mutex_unlock(&vmbus_connection.channel_mutex);
++ hv_process_channel_removal(rescind->child_relid);
+ }
++ mutex_unlock(&vmbus_connection.channel_mutex);
+ }
+ }
+
+diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
+--- a/drivers/hv/vmbus_drv.c
++++ b/drivers/hv/vmbus_drv.c
+@@ -768,8 +768,7 @@ static void vmbus_device_release(struct device *device)
+ struct vmbus_channel *channel = hv_dev->channel;
+
+ mutex_lock(&vmbus_connection.channel_mutex);
+- hv_process_channel_removal(channel,
+- channel->offermsg.child_relid);
++ hv_process_channel_removal(channel->offermsg.child_relid);
+ mutex_unlock(&vmbus_connection.channel_mutex);
+ kfree(hv_dev);
+
+diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
+--- a/include/linux/hyperv.h
++++ b/include/linux/hyperv.h
+@@ -1403,7 +1403,7 @@ extern bool vmbus_prep_negotiate_resp(struct icmsg_hdr *icmsghdrp, u8 *buf,
+ const int *srv_version, int srv_vercnt,
+ int *nego_fw_version, int *nego_srv_version);
+
+-void hv_process_channel_removal(struct vmbus_channel *channel, u32 relid);
++void hv_process_channel_removal(u32 relid);
+
+ void vmbus_setevent(struct vmbus_channel *channel);
+ /*
diff --git a/patches.suse/msft-hv-1471-x86-hyperv-Clear-vCPU-banks-between-calls-to-avoid-f.patch b/patches.suse/msft-hv-1471-x86-hyperv-Clear-vCPU-banks-between-calls-to-avoid-f.patch
new file mode 100644
index 0000000000..1e2bcd9454
--- /dev/null
+++ b/patches.suse/msft-hv-1471-x86-hyperv-Clear-vCPU-banks-between-calls-to-avoid-f.patch
@@ -0,0 +1,101 @@
+From: Vitaly Kuznetsov <vkuznets@redhat.com>
+Date: Fri, 6 Oct 2017 17:48:54 +0200
+Patch-mainline: v4.14-rc5
+Subject: x86/hyperv: Clear vCPU banks between calls to avoid flushing unneeded vCPUs
+Git-commit: a3b7424392924e778b608e30ee321f7b10cc94b8
+References: fate#323887
+
+hv_flush_pcpu_ex structures are not cleared between calls for performance
+reasons (they're variable size up to PAGE_SIZE each) but we must clear
+hv_vp_set.bank_contents part of it to avoid flushing unneeded vCPUs. The
+rest of the structure is formed correctly.
+
+To do the clearing in an efficient way stash the maximum possible vCPU
+number (this may differ from Linux CPU id).
+
+Reported-by: Jork Loeser <Jork.Loeser@microsoft.com>
+Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
+Cc: Dexuan Cui <decui@microsoft.com>
+Cc: Haiyang Zhang <haiyangz@microsoft.com>
+Cc: K. Y. Srinivasan <kys@microsoft.com>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Stephen Hemminger <sthemmin@microsoft.com>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Cc: devel@linuxdriverproject.org
+Link: http://lkml.kernel.org/r/20171006154854.18092-1-vkuznets@redhat.com
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Acked-by: Olaf Hering <ohering@suse.de>
+---
+ arch/x86/hyperv/hv_init.c | 5 +++++
+ arch/x86/hyperv/mmu.c | 17 ++++++++++++-----
+ arch/x86/include/asm/mshyperv.h | 1 +
+ 3 files changed, 18 insertions(+), 5 deletions(-)
+
+diff --git a/arch/x86/hyperv/hv_init.c b/arch/x86/hyperv/hv_init.c
+--- a/arch/x86/hyperv/hv_init.c
++++ b/arch/x86/hyperv/hv_init.c
+@@ -85,6 +85,8 @@ EXPORT_SYMBOL_GPL(hyperv_cs);
+ u32 *hv_vp_index;
+ EXPORT_SYMBOL_GPL(hv_vp_index);
+
++u32 hv_max_vp_index;
++
+ static int hv_cpu_init(unsigned int cpu)
+ {
+ u64 msr_vp_index;
+@@ -93,6 +95,9 @@ static int hv_cpu_init(unsigned int cpu)
+
+ hv_vp_index[smp_processor_id()] = msr_vp_index;
+
++ if (msr_vp_index > hv_max_vp_index)
++ hv_max_vp_index = msr_vp_index;
++
+ return 0;
+ }
+
+diff --git a/arch/x86/hyperv/mmu.c b/arch/x86/hyperv/mmu.c
+--- a/arch/x86/hyperv/mmu.c
++++ b/arch/x86/hyperv/mmu.c
+@@ -76,6 +76,18 @@ static inline int cpumask_to_vp_set(struct hv_flush_pcpu_ex *flush,
+ {
+ int cpu, vcpu, vcpu_bank, vcpu_offset, nr_bank = 1;
+
++ /* valid_bank_mask can represent up to 64 banks */
++ if (hv_max_vp_index / 64 >= 64)
++ return 0;
++
++ /*
++ * Clear all banks up to the maximum possible bank as hv_flush_pcpu_ex
++ * structs are not cleared between calls, we risk flushing unneeded
++ * vCPUs otherwise.
++ */
++ for (vcpu_bank = 0; vcpu_bank <= hv_max_vp_index / 64; vcpu_bank++)
++ flush->hv_vp_set.bank_contents[vcpu_bank] = 0;
++
+ /*
+ * Some banks may end up being empty but this is acceptable.
+ */
+@@ -83,11 +95,6 @@ static inline int cpumask_to_vp_set(struct hv_flush_pcpu_ex *flush,
+ vcpu = hv_cpu_number_to_vp_number(cpu);
+ vcpu_bank = vcpu / 64;
+ vcpu_offset = vcpu % 64;
+-
+- /* valid_bank_mask can represent up to 64 banks */
+- if (vcpu_bank >= 64)
+- return 0;
+-
+ __set_bit(vcpu_offset, (unsigned long *)
+ &flush->hv_vp_set.bank_contents[vcpu_bank]);
+ if (vcpu_bank >= nr_bank)
+diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h
+--- a/arch/x86/include/asm/mshyperv.h
++++ b/arch/x86/include/asm/mshyperv.h
+@@ -289,6 +289,7 @@ static inline u64 hv_do_rep_hypercall(u16 code, u16 rep_count, u16 varhead_size,
+ * to this information.
+ */
+ extern u32 *hv_vp_index;
++extern u32 hv_max_vp_index;
+
+ /**
+ * hv_cpu_number_to_vp_number() - Map CPU to VP.
diff --git a/patches.suse/msft-hv-1472-x86-hyperv-Don-t-use-percpu-areas-for-pcpu_flush-pcp.patch b/patches.suse/msft-hv-1472-x86-hyperv-Don-t-use-percpu-areas-for-pcpu_flush-pcp.patch
new file mode 100644
index 0000000000..2f7a9c1a18
--- /dev/null
+++ b/patches.suse/msft-hv-1472-x86-hyperv-Don-t-use-percpu-areas-for-pcpu_flush-pcp.patch
@@ -0,0 +1,115 @@
+From: Vitaly Kuznetsov <vkuznets@redhat.com>
+Date: Thu, 5 Oct 2017 13:39:24 +0200
+Patch-mainline: v4.14-rc5
+Subject: x86/hyperv: Don't use percpu areas for pcpu_flush/pcpu_flush_ex structures
+Git-commit: 60d73a7c96601434dfdb56d5b9167ff3b850d8d7
+References: fate#323887
+
+hv_do_hypercall() does virt_to_phys() translation and with some configs
+(CONFIG_SLAB) this doesn't work for percpu areas, we pass wrong memory to
+hypervisor and get #GP. We could use working slow_virt_to_phys() instead
+but doing so kills the performance.
+
+Move pcpu_flush/pcpu_flush_ex structures out of percpu areas and
+allocate memory on first call. The additional level of indirection gives
+us a small performance penalty, in future we may consider introducing
+hypercall functions which avoid virt_to_phys() conversion and cache
+physical addresses of pcpu_flush/pcpu_flush_ex structures somewhere.
+
+Reported-by: Simon Xiao <sixiao@microsoft.com>
+Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
+Cc: Dexuan Cui <decui@microsoft.com>
+Cc: Haiyang Zhang <haiyangz@microsoft.com>
+Cc: Jork Loeser <Jork.Loeser@microsoft.com>
+Cc: K. Y. Srinivasan <kys@microsoft.com>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Stephen Hemminger <sthemmin@microsoft.com>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Cc: devel@linuxdriverproject.org
+Link: http://lkml.kernel.org/r/20171005113924.28021-1-vkuznets@redhat.com
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Acked-by: Olaf Hering <ohering@suse.de>
+---
+ arch/x86/hyperv/mmu.c | 34 ++++++++++++++++++++++++++++------
+ 1 file changed, 28 insertions(+), 6 deletions(-)
+
+diff --git a/arch/x86/hyperv/mmu.c b/arch/x86/hyperv/mmu.c
+--- a/arch/x86/hyperv/mmu.c
++++ b/arch/x86/hyperv/mmu.c
+@@ -36,9 +36,9 @@ struct hv_flush_pcpu_ex {
+ /* Each gva in gva_list encodes up to 4096 pages to flush */
+ #define HV_TLB_FLUSH_UNIT (4096 * PAGE_SIZE)
+
+-static struct hv_flush_pcpu __percpu *pcpu_flush;
++static struct hv_flush_pcpu __percpu **pcpu_flush;
+
+-static struct hv_flush_pcpu_ex __percpu *pcpu_flush_ex;
++static struct hv_flush_pcpu_ex __percpu **pcpu_flush_ex;
+
+ /*
+ * Fills in gva_list starting from offset. Returns the number of items added.
+@@ -109,6 +109,7 @@ static void hyperv_flush_tlb_others(const struct cpumask *cpus,
+ struct mm_struct *mm, unsigned long start, unsigned long end)
+ {
+ int cpu, vcpu, gva_n, max_gvas;
++ struct hv_flush_pcpu **flush_pcpu;
+ struct hv_flush_pcpu *flush;
+ u64 status = U64_MAX;
+ unsigned long flags;
+@@ -123,7 +124,17 @@ static void hyperv_flush_tlb_others(const struct cpumask *cpus,
+
+ local_irq_save(flags);
+
+- flush = this_cpu_ptr(pcpu_flush);
++ flush_pcpu = this_cpu_ptr(pcpu_flush);
++
++ if (unlikely(!*flush_pcpu))
++ *flush_pcpu = page_address(alloc_page(GFP_ATOMIC));
++
++ flush = *flush_pcpu;
++
++ if (unlikely(!flush)) {
++ local_irq_restore(flags);
++ goto do_native;
++ }
+
+ if (mm) {
+ flush->address_space = virt_to_phys(mm->pgd);
+@@ -180,6 +191,7 @@ static void hyperv_flush_tlb_others_ex(const struct cpumask *cpus,
+ struct mm_struct *mm, unsigned long start, unsigned long end)
+ {
+ int nr_bank = 0, max_gvas, gva_n;
++ struct hv_flush_pcpu_ex **flush_pcpu;
+ struct hv_flush_pcpu_ex *flush;
+ u64 status = U64_MAX;
+ unsigned long flags;
+@@ -194,7 +206,17 @@ static void hyperv_flush_tlb_others_ex(const struct cpumask *cpus,
+
+ local_irq_save(flags);
+
+- flush = this_cpu_ptr(pcpu_flush_ex);
++ flush_pcpu = this_cpu_ptr(pcpu_flush_ex);
++
++ if (unlikely(!*flush_pcpu))
++ *flush_pcpu = page_address(alloc_page(GFP_ATOMIC));
++
++ flush = *flush_pcpu;
++
++ if (unlikely(!flush)) {
++ local_irq_restore(flags);
++ goto do_native;
++ }
+
+ if (mm) {
+ flush->address_space = virt_to_phys(mm->pgd);
+@@ -273,7 +295,7 @@ void hyper_alloc_mmu(void)
+ return;
+
+ if (!(ms_hyperv.hints & HV_X64_EX_PROCESSOR_MASKS_RECOMMENDED))
+- pcpu_flush = __alloc_percpu(PAGE_SIZE, PAGE_SIZE);
++ pcpu_flush = alloc_percpu(struct hv_flush_pcpu *);
+ else
+- pcpu_flush_ex = __alloc_percpu(PAGE_SIZE, PAGE_SIZE);
++ pcpu_flush_ex = alloc_percpu(struct hv_flush_pcpu_ex *);
+ }
diff --git a/patches.suse/msft-hv-1473-x86-hyperv-Fix-hypercalls-with-extended-CPU-ranges-f.patch b/patches.suse/msft-hv-1473-x86-hyperv-Fix-hypercalls-with-extended-CPU-ranges-f.patch
new file mode 100644
index 0000000000..890e96008c
--- /dev/null
+++ b/patches.suse/msft-hv-1473-x86-hyperv-Fix-hypercalls-with-extended-CPU-ranges-f.patch
@@ -0,0 +1,66 @@
+From: Marcelo Henrique Cerri <marcelo.cerri@canonical.com>
+Date: Thu, 5 Oct 2017 10:34:29 -0300
+Patch-mainline: v4.14-rc5
+Subject: x86/hyperv: Fix hypercalls with extended CPU ranges for TLB flushing
+Git-commit: ab7ff471aa5db670197070760f022622793da7e5
+References: fate#323887
+
+Do not consider the fixed size of hv_vp_set when passing the variable
+header size to hv_do_rep_hypercall().
+
+The Hyper-V hypervisor specification states that for a hypercall with a
+variable header only the size of the variable portion should be supplied
+via the input control.
+
+For HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE_EX/LIST_EX calls that means the
+fixed portion of hv_vp_set should not be considered.
+
+That fixes random failures of some applications that are unexpectedly
+killed with SIGBUS or SIGSEGV.
+
+Signed-off-by: Marcelo Henrique Cerri <marcelo.cerri@canonical.com>
+Cc: Dexuan Cui <decui@microsoft.com>
+Cc: Haiyang Zhang <haiyangz@microsoft.com>
+Cc: Jork Loeser <Jork.Loeser@microsoft.com>
+Cc: Josh Poulson <jopoulso@microsoft.com>
+Cc: K. Y. Srinivasan <kys@microsoft.com>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Simon Xiao <sixiao@microsoft.com>
+Cc: Stephen Hemminger <sthemmin@microsoft.com>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Cc: Vitaly Kuznetsov <vkuznets@redhat.com>
+Cc: devel@linuxdriverproject.org
+Fixes: 628f54cc6451 ("x86/hyper-v: Support extended CPU ranges for TLB flush hypercalls")
+Link: http://lkml.kernel.org/r/1507210469-29065-1-git-send-email-marcelo.cerri@canonical.com
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Acked-by: Olaf Hering <ohering@suse.de>
+---
+ arch/x86/hyperv/mmu.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/arch/x86/hyperv/mmu.c b/arch/x86/hyperv/mmu.c
+--- a/arch/x86/hyperv/mmu.c
++++ b/arch/x86/hyperv/mmu.c
+@@ -251,18 +251,18 @@ static void hyperv_flush_tlb_others_ex(const struct cpumask *cpus,
+ flush->flags |= HV_FLUSH_NON_GLOBAL_MAPPINGS_ONLY;
+ status = hv_do_rep_hypercall(
+ HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE_EX,
+- 0, nr_bank + 2, flush, NULL);
++ 0, nr_bank, flush, NULL);
+ } else if (end &&
+ ((end - start)/HV_TLB_FLUSH_UNIT) > max_gvas) {
+ status = hv_do_rep_hypercall(
+ HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE_EX,
+- 0, nr_bank + 2, flush, NULL);
++ 0, nr_bank, flush, NULL);
+ } else {
+ gva_n = fill_gva_list(flush->gva_list, nr_bank,
+ start, end);
+ status = hv_do_rep_hypercall(
+ HVCALL_FLUSH_VIRTUAL_ADDRESS_LIST_EX,
+- gva_n, nr_bank + 2, flush, NULL);
++ gva_n, nr_bank, flush, NULL);
+ }
+
+ local_irq_restore(flags);
diff --git a/patches.suse/suse-hv-guest-os-id.patch b/patches.suse/suse-hv-guest-os-id.patch
index 9bb4986d7b..dfd2a000eb 100644
--- a/patches.suse/suse-hv-guest-os-id.patch
+++ b/patches.suse/suse-hv-guest-os-id.patch
@@ -32,4 +32,4 @@ Acked-by: Olaf Hering <ohering@suse.de>
+ guest_id = generate_guest_id(d1, LINUX_VERSION_CODE, d2);
wrmsrl(HV_X64_MSR_GUEST_OS_ID, guest_id);
- hypercall_pg = __vmalloc(PAGE_SIZE, GFP_KERNEL, PAGE_KERNEL_RX);
+ hv_hypercall_pg = __vmalloc(PAGE_SIZE, GFP_KERNEL, PAGE_KERNEL_RX);
diff --git a/series.conf b/series.conf
index ff3eec1f84..68205ade04 100644
--- a/series.conf
+++ b/series.conf
@@ -1629,7 +1629,16 @@
patches.suse/msft-hv-1373-PCI-hv-Temporary-own-CPU-number-to-vCPU-number-infra.patch
patches.suse/msft-hv-1374-PCI-hv-Add-vPCI-version-protocol-negotiation.patch
patches.suse/msft-hv-1375-PCI-hv-Use-vPCI-protocol-version-1.2.patch
+ patches.suse/msft-hv-1376-tools-hv-ignore-a-NIC-if-it-has-been-configured.patch
patches.suse/msft-hv-1377-Revert-netvsc-optimize-calculation-of-number-of-slot.patch
+ patches.suse/msft-hv-1378-vmbus-simplify-hv_ringbuffer_read.patch
+ patches.suse/msft-hv-1379-vmbus-drop-unused-ring_buffer_info-elements.patch
+ patches.suse/msft-hv-1380-vmbus-refactor-hv_signal_on_read.patch
+ patches.suse/msft-hv-1381-vmbus-eliminate-duplicate-cached-index.patch
+ patches.suse/msft-hv-1382-vmbus-more-host-signalling-avoidance.patch
+ patches.suse/msft-hv-1383-vmbus-add-prefetch-to-ring-buffer-iterator.patch
+ patches.suse/msft-hv-1384-x86-hyper-v-include-hyperv-only-when-CONFIG_HYPERV-i.patch
+ patches.suse/msft-hv-1385-x86-hyper-v-stash-the-max-number-of-virtual-logical-.patch
patches.suse/msft-hv-1386-netvsc-force-link-update-after-MTU-change.patch
patches.suse/msft-hv-1387-netvsc-add-some-rtnl_dereference-annotations.patch
patches.suse/msft-hv-1388-netvsc-change-order-of-steps-in-setting-queues.patch
@@ -1638,6 +1647,7 @@
patches.suse/msft-hv-1391-netvsc-need-rcu_derefence-when-accessing-internal-de.patch
patches.suse/msft-hv-1392-netvsc-save-pointer-to-parent-netvsc_device-in-chann.patch
patches.suse/msft-hv-1393-netvsc-add-rtnl-annotations-in-rndis.patch
+ patches.suse/msft-hv-1394-Revert-x86-hyper-v-include-hyperv-only-when-CONFIG_H.patch
patches.suse/msft-hv-1395-netvsc-fix-ptr_ret.cocci-warnings.patch
patches.suse/msft-hv-1396-netvsc-remove-bogus-rtnl_unlock.patch
patches.suse/msft-hv-1397-netvsc-Remove-redundant-use-of-ipv6_hdr.patch
@@ -1652,10 +1662,66 @@
patches.suse/msft-hv-1407-netvsc-optimize-receive-completions.patch
patches.suse/msft-hv-1408-netvsc-fix-error-unwind-on-device-setup-failure.patch
patches.suse/msft-hv-1409-netvsc-signal-host-if-receive-ring-is-emptied.patch
+ patches.suse/msft-hv-1410-netvsc-Initialize-64-bit-stats-seqcount.patch
patches.suse/msft-hv-1411-hyperv-netvsc-Neaten-netvsc_send_pkt-by-using-a-temp.patch
patches.suse/msft-hv-1412-netvsc-transparent-VF-management.patch
+ patches.suse/msft-hv-1413-netvsc-remove-bonding-setup-script.patch
+ patches.suse/msft-hv-1414-PCI-hv-Do-not-sleep-in-compose_msi_msg.patch
+ patches.suse/msft-hv-1415-netvsc-fix-race-on-sub-channel-creation.patch
patches.suse/msft-hv-1416-netvsc-fix-rtnl-deadlock-on-unregister-of-vf.patch
patches.suse/msft-hv-1417-netvsc-make-sure-and-unregister-datapath.patch
+ patches.suse/msft-hv-1418-x86-hyper-v-Include-hyperv-only-when-CONFIG_HYPERV-i.patch
+ patches.suse/msft-hv-1419-x86-hyper-v-Make-hv_do_hypercall-inline.patch
+ patches.suse/msft-hv-1420-x86-hyper-v-Introduce-fast-hypercall-implementation.patch
+ patches.suse/msft-hv-1421-hyper-v-Use-fast-hypercall-for-HVCALL_SIGNAL_EVENT.patch
+ patches.suse/msft-hv-1422-x86-hyper-v-Implement-rep-hypercalls.patch
+ patches.suse/msft-hv-1423-hyper-v-Globalize-vp_index.patch
+ patches.suse/msft-hv-1424-x86-hyper-v-Use-hypercall-for-remote-TLB-flush.patch
+ patches.suse/msft-hv-1425-netvsc-delay-setup-of-VF-device.patch
+ patches.suse/msft-hv-1426-netvsc-don-t-signal-host-twice-if-empty.patch
+ patches.suse/msft-hv-1427-netvsc-propagate-MAC-address-change-to-VF-slave.patch
+ patches.suse/msft-hv-1428-netvsc-check-error-return-when-restoring-channels-an.patch
+ patches.suse/msft-hv-1429-netvsc-no-need-to-allocate-send-receive-on-numa-node.patch
+ patches.suse/msft-hv-1430-netvsc-whitespace-cleanup.patch
+ patches.suse/msft-hv-1431-netvsc-remove-unnecessary-cast-of-void-pointer.patch
+ patches.suse/msft-hv-1432-netvsc-remove-unnecessary-check-for-NULL-hdr.patch
+ patches.suse/msft-hv-1433-netvsc-allow-controlling-send-recv-buffer-size.patch
+ patches.suse/msft-hv-1434-netvsc-keep-track-of-some-non-fatal-overload-conditi.patch
+ patches.suse/msft-hv-1435-Tools-hv-vss-Skip-freezing-filesystems-backed-by-loo.patch
+ patches.suse/msft-hv-1436-Drivers-hv-balloon-Correctly-update-onlined-page-cou.patch
+ patches.suse/msft-hv-1437-Drivers-hv-balloon-Show-the-max-dynamic-memory-assig.patch
+ patches.suse/msft-hv-1438-Drivers-hv-balloon-Initialize-last_post_time-on-star.patch
+ patches.suse/msft-hv-1439-Drivers-hv-kvp-Use-MAX_ADAPTER_ID_SIZE-for-translati.patch
+ patches.suse/msft-hv-1440-Tools-hv-fix-snprintf-warning-in-kvp_daemon.patch
+ patches.suse/msft-hv-1441-Tools-hv-update-buffer-handling-in-hv_fcopy_daemon.patch
+ patches.suse/msft-hv-1442-Drivers-hv-vmbus-Fix-rescind-handling-issues.patch
+ patches.suse/msft-hv-1443-vmbus-remove-unused-vmbus_sendpacket_multipagebuffer.patch
+ patches.suse/msft-hv-1444-vmbus-remove-unused-vmubs_sendpacket_pagebuffer_ctl.patch
+ patches.suse/msft-hv-1445-vmbus-remove-unused-vmbus_sendpacket_ctl.patch
+ patches.suse/msft-hv-1446-hv_netvsc-Clean-up-unused-parameter-from-netvsc_get_.patch
+ patches.suse/msft-hv-1447-hv_netvsc-Clean-up-unused-parameter-from-netvsc_get_.patch
+ patches.suse/msft-hv-1448-hv_netvsc-Add-ethtool-handler-to-set-and-get-UDP-has.patch
+ patches.suse/msft-hv-1449-hv_netvsc-Fix-rndis_filter_close-error-during-netvsc.patch
+ patches.suse/msft-hv-1452-scsi-storvsc-fix-memory-leak-on-ring-buffer-busy.patch
+ patches.suse/msft-hv-1453-x86-hyper-v-Support-extended-CPU-ranges-for-TLB-flus.patch
+ patches.suse/msft-hv-1454-tracing-hyper-v-Trace-hyperv_mmu_flush_tlb_others.patch
+ patches.suse/msft-hv-1455-netvsc-cleanup-datapath-switch.patch
+ patches.suse/msft-hv-1456-netvsc-allow-driver-to-be-removed-even-if-VF-is-pres.patch
+ patches.suse/msft-hv-1457-hv_netvsc-Clean-up-an-unused-parameter-in-rndis_filt.patch
+ patches.suse/msft-hv-1458-hv_netvsc-Simplify-num_chn-checking-in-rndis_filter_.patch
+ patches.suse/msft-hv-1459-hv_netvsc-Simplify-the-limit-check-in-netvsc_set_cha.patch
+ patches.suse/msft-hv-1460-hv_netvsc-Fix-the-channel-limit-in-netvsc_set_rxfh.patch
+ patches.suse/msft-hv-1461-hv_netvsc-fix-deadlock-on-hotplug.patch
+ patches.suse/msft-hv-1462-hv_netvsc-avoid-unnecessary-wakeups-on-subchannel-cr.patch
+ patches.suse/msft-hv-1464-x86-hyper-v-Remove-duplicated-HV_X64_EX_PROCESSOR_MA.patch
+ patches.suse/msft-hv-1465-netvsc-increase-default-receive-buffer-size.patch
+ patches.suse/msft-hv-1466-hv_netvsc-fix-send-buffer-failure-on-MTU-change.patch
+ patches.suse/msft-hv-1467-vmbus-don-t-acquire-the-mutex-in-vmbus_hvsock_device.patch
+ patches.suse/msft-hv-1468-Drivers-hv-fcopy-restore-correct-transfer-length.patch
+ patches.suse/msft-hv-1470-Drivers-hv-vmbus-Fix-bugs-in-rescind-handling.patch
+ patches.suse/msft-hv-1471-x86-hyperv-Clear-vCPU-banks-between-calls-to-avoid-f.patch
+ patches.suse/msft-hv-1472-x86-hyperv-Don-t-use-percpu-areas-for-pcpu_flush-pcp.patch
+ patches.suse/msft-hv-1473-x86-hyperv-Fix-hypercalls-with-extended-CPU-ranges-f.patch
patches.suse/suse-hv-guest-os-id.patch
patches.suse/suse-hv-kvp_on_msg.dbg.patch