--- /dev/null
+From 4dbfc2e68004c60edab7e8fd26784383dd3ee9bc Mon Sep 17 00:00:00 2001
+From: Vitaly Kuznetsov <vkuznets@redhat.com>
+Date: Sat, 30 Apr 2016 19:21:33 -0700
+Subject: Drivers: hv: kvp: fix IP Failover
+
+From: Vitaly Kuznetsov <vkuznets@redhat.com>
+
+commit 4dbfc2e68004c60edab7e8fd26784383dd3ee9bc upstream.
+
+Hyper-V VMs can be replicated to another hosts and there is a feature to
+set different IP for replicas, it is called 'Failover TCP/IP'. When
+such guest starts Hyper-V host sends it KVP_OP_SET_IP_INFO message as soon
+as we finish negotiation procedure. The problem is that it can happen (and
+it actually happens) before userspace daemon connects and we reply with
+HV_E_FAIL to the message. As there are no repetitions we fail to set the
+requested IP.
+
+Solve the issue by postponing our reply to the negotiation message till
+userspace daemon is connected. We can't wait too long as there is a
+host-side timeout (cca. 75 seconds) and if we fail to reply in this time
+frame the whole KVP service will become inactive. The solution is not
+ideal - if it takes userspace daemon more than 60 seconds to connect
+IP Failover will still fail but I don't see a solution with our current
+separation between kernel and userspace parts.
+
+Other two modules (VSS and FCOPY) don't require such delay, leave them
+untouched.
+
+Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
+Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
+Signed-off-by: Dexuan Cui <decui@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/hv/hv_kvp.c | 31 +++++++++++++++++++++++++++++++
+ drivers/hv/hyperv_vmbus.h | 5 +++++
+ 2 files changed, 36 insertions(+)
+
+--- a/drivers/hv/hv_kvp.c
++++ b/drivers/hv/hv_kvp.c
+@@ -78,9 +78,11 @@ static void kvp_send_key(struct work_str
+
+ static void kvp_respond_to_host(struct hv_kvp_msg *msg, int error);
+ static void kvp_timeout_func(struct work_struct *dummy);
++static void kvp_host_handshake_func(struct work_struct *dummy);
+ static void kvp_register(int);
+
+ static DECLARE_DELAYED_WORK(kvp_timeout_work, kvp_timeout_func);
++static DECLARE_DELAYED_WORK(kvp_host_handshake_work, kvp_host_handshake_func);
+ static DECLARE_WORK(kvp_sendkey_work, kvp_send_key);
+
+ static const char kvp_devname[] = "vmbus/hv_kvp";
+@@ -131,6 +133,11 @@ static void kvp_timeout_func(struct work
+ hv_poll_channel(kvp_transaction.recv_channel, kvp_poll_wrapper);
+ }
+
++static void kvp_host_handshake_func(struct work_struct *dummy)
++{
++ hv_poll_channel(kvp_transaction.recv_channel, hv_kvp_onchannelcallback);
++}
++
+ static int kvp_handle_handshake(struct hv_kvp_msg *msg)
+ {
+ switch (msg->kvp_hdr.operation) {
+@@ -155,6 +162,12 @@ static int kvp_handle_handshake(struct h
+ pr_debug("KVP: userspace daemon ver. %d registered\n",
+ KVP_OP_REGISTER);
+ kvp_register(dm_reg_value);
++
++ /*
++ * If we're still negotiating with the host cancel the timeout
++ * work to not poll the channel twice.
++ */
++ cancel_delayed_work_sync(&kvp_host_handshake_work);
+ hv_poll_channel(kvp_transaction.recv_channel, kvp_poll_wrapper);
+
+ return 0;
+@@ -595,7 +608,22 @@ void hv_kvp_onchannelcallback(void *cont
+ struct icmsg_negotiate *negop = NULL;
+ int util_fw_version;
+ int kvp_srv_version;
++ static enum {NEGO_NOT_STARTED,
++ NEGO_IN_PROGRESS,
++ NEGO_FINISHED} host_negotiatied = NEGO_NOT_STARTED;
+
++ if (host_negotiatied == NEGO_NOT_STARTED &&
++ kvp_transaction.state < HVUTIL_READY) {
++ /*
++ * If userspace daemon is not connected and host is asking
++ * us to negotiate we need to delay to not lose messages.
++ * This is important for Failover IP setting.
++ */
++ host_negotiatied = NEGO_IN_PROGRESS;
++ schedule_delayed_work(&kvp_host_handshake_work,
++ HV_UTIL_NEGO_TIMEOUT * HZ);
++ return;
++ }
+ if (kvp_transaction.state > HVUTIL_READY)
+ return;
+
+@@ -673,6 +701,8 @@ void hv_kvp_onchannelcallback(void *cont
+ vmbus_sendpacket(channel, recv_buffer,
+ recvlen, requestid,
+ VM_PKT_DATA_INBAND, 0);
++
++ host_negotiatied = NEGO_FINISHED;
+ }
+
+ }
+@@ -711,6 +741,7 @@ hv_kvp_init(struct hv_util_service *srv)
+ void hv_kvp_deinit(void)
+ {
+ kvp_transaction.state = HVUTIL_DEVICE_DYING;
++ cancel_delayed_work_sync(&kvp_host_handshake_work);
+ cancel_delayed_work_sync(&kvp_timeout_work);
+ cancel_work_sync(&kvp_sendkey_work);
+ hvutil_transport_destroy(hvt);
+--- a/drivers/hv/hyperv_vmbus.h
++++ b/drivers/hv/hyperv_vmbus.h
+@@ -36,6 +36,11 @@
+ #define HV_UTIL_TIMEOUT 30
+
+ /*
++ * Timeout for guest-host handshake for services.
++ */
++#define HV_UTIL_NEGO_TIMEOUT 60
++
++/*
+ * The below CPUID leaves are present if VersionAndFeatures.HypervisorPresent
+ * is set by CPUID(HVCPUID_VERSION_FEATURES).
+ */
--- /dev/null
+From b9830d120cbe155863399f25eaef6aa8353e767f Mon Sep 17 00:00:00 2001
+From: "K. Y. Srinivasan" <kys@microsoft.com>
+Date: Fri, 26 Feb 2016 15:13:19 -0800
+Subject: Drivers: hv: util: Pass the channel information during the init call
+
+From: K. Y. Srinivasan <kys@microsoft.com>
+
+commit b9830d120cbe155863399f25eaef6aa8353e767f upstream.
+
+Pass the channel information to the util drivers that need to defer
+reading the channel while they are processing a request. This would address
+the following issue reported by Vitaly:
+
+Commit 3cace4a61610 ("Drivers: hv: utils: run polling callback always in
+interrupt context") removed direct *_transaction.state = HVUTIL_READY
+assignments from *_handle_handshake() functions introducing the following
+race: if a userspace daemon connects before we get first non-negotiation
+request from the server hv_poll_channel() won't set transaction state to
+HVUTIL_READY as (!channel) condition will fail, we set it to non-NULL on
+the first real request from the server.
+
+Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
+Reported-by: Vitaly Kuznetsov <vkuznets@redhat.com>
+Signed-off-by: Dexuan Cui <decui@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/hv/hv_fcopy.c | 2 +-
+ drivers/hv/hv_kvp.c | 2 +-
+ drivers/hv/hv_snapshot.c | 2 +-
+ drivers/hv/hv_util.c | 1 +
+ include/linux/hyperv.h | 1 +
+ 5 files changed, 5 insertions(+), 3 deletions(-)
+
+--- a/drivers/hv/hv_fcopy.c
++++ b/drivers/hv/hv_fcopy.c
+@@ -256,7 +256,6 @@ void hv_fcopy_onchannelcallback(void *co
+ */
+
+ fcopy_transaction.recv_len = recvlen;
+- fcopy_transaction.recv_channel = channel;
+ fcopy_transaction.recv_req_id = requestid;
+ fcopy_transaction.fcopy_msg = fcopy_msg;
+
+@@ -323,6 +322,7 @@ static void fcopy_on_reset(void)
+ int hv_fcopy_init(struct hv_util_service *srv)
+ {
+ recv_buffer = srv->recv_buffer;
++ fcopy_transaction.recv_channel = srv->channel;
+
+ init_completion(&release_event);
+ /*
+--- a/drivers/hv/hv_kvp.c
++++ b/drivers/hv/hv_kvp.c
+@@ -640,7 +640,6 @@ void hv_kvp_onchannelcallback(void *cont
+ */
+
+ kvp_transaction.recv_len = recvlen;
+- kvp_transaction.recv_channel = channel;
+ kvp_transaction.recv_req_id = requestid;
+ kvp_transaction.kvp_msg = kvp_msg;
+
+@@ -690,6 +689,7 @@ int
+ hv_kvp_init(struct hv_util_service *srv)
+ {
+ recv_buffer = srv->recv_buffer;
++ kvp_transaction.recv_channel = srv->channel;
+
+ init_completion(&release_event);
+ /*
+--- a/drivers/hv/hv_snapshot.c
++++ b/drivers/hv/hv_snapshot.c
+@@ -264,7 +264,6 @@ void hv_vss_onchannelcallback(void *cont
+ */
+
+ vss_transaction.recv_len = recvlen;
+- vss_transaction.recv_channel = channel;
+ vss_transaction.recv_req_id = requestid;
+ vss_transaction.msg = (struct hv_vss_msg *)vss_msg;
+
+@@ -340,6 +339,7 @@ hv_vss_init(struct hv_util_service *srv)
+ return -ENOTSUPP;
+ }
+ recv_buffer = srv->recv_buffer;
++ vss_transaction.recv_channel = srv->channel;
+
+ /*
+ * When this driver loads, the user level daemon that
+--- a/drivers/hv/hv_util.c
++++ b/drivers/hv/hv_util.c
+@@ -326,6 +326,7 @@ static int util_probe(struct hv_device *
+ srv->recv_buffer = kmalloc(PAGE_SIZE * 4, GFP_KERNEL);
+ if (!srv->recv_buffer)
+ return -ENOMEM;
++ srv->channel = dev->channel;
+ if (srv->util_init) {
+ ret = srv->util_init(srv);
+ if (ret) {
+--- a/include/linux/hyperv.h
++++ b/include/linux/hyperv.h
+@@ -1179,6 +1179,7 @@ int vmbus_allocate_mmio(struct resource
+
+ struct hv_util_service {
+ u8 *recv_buffer;
++ void *channel;
+ void (*util_cb)(void *);
+ int (*util_init)(struct hv_util_service *);
+ void (*util_deinit)(void);
--- /dev/null
+From 2d0c3b5ad739697a68dc8a444f5b9f4817cf8f8f Mon Sep 17 00:00:00 2001
+From: "K. Y. Srinivasan" <kys@microsoft.com>
+Date: Mon, 14 Dec 2015 16:01:57 -0800
+Subject: Drivers: hv: utils: Invoke the poll function after handshake
+
+From: K. Y. Srinivasan <kys@microsoft.com>
+
+commit 2d0c3b5ad739697a68dc8a444f5b9f4817cf8f8f upstream.
+
+When the handshake with daemon is complete, we should poll the channel since
+during the handshake, we will not be processing any messages. This is a
+potential bug if the host is waiting for a response from the guest.
+I would like to thank Dexuan for pointing this out.
+
+Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
+Signed-off-by: Dexuan Cui <decui@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/hv/hv_kvp.c | 2 +-
+ drivers/hv/hv_snapshot.c | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/hv/hv_kvp.c
++++ b/drivers/hv/hv_kvp.c
+@@ -155,7 +155,7 @@ static int kvp_handle_handshake(struct h
+ pr_debug("KVP: userspace daemon ver. %d registered\n",
+ KVP_OP_REGISTER);
+ kvp_register(dm_reg_value);
+- kvp_transaction.state = HVUTIL_READY;
++ hv_poll_channel(kvp_transaction.recv_channel, kvp_poll_wrapper);
+
+ return 0;
+ }
+--- a/drivers/hv/hv_snapshot.c
++++ b/drivers/hv/hv_snapshot.c
+@@ -114,7 +114,7 @@ static int vss_handle_handshake(struct h
+ default:
+ return -EINVAL;
+ }
+- vss_transaction.state = HVUTIL_READY;
++ hv_poll_channel(vss_transaction.recv_channel, vss_poll_wrapper);
+ pr_debug("VSS: userspace daemon ver. %d registered\n", dm_reg_value);
+ return 0;
+ }
--- /dev/null
+From a3ade8cc474d848676278660e65f5af1e9e094d9 Mon Sep 17 00:00:00 2001
+From: Long Li <longli@microsoft.com>
+Date: Sun, 30 Apr 2017 16:21:19 -0700
+Subject: HV: properly delay KVP packets when negotiation is in progress
+
+From: Long Li <longli@microsoft.com>
+
+commit a3ade8cc474d848676278660e65f5af1e9e094d9 upstream.
+
+The host may send multiple negotiation packets
+(due to timeout) before the KVP user-mode daemon
+is connected. KVP user-mode daemon is connected.
+We need to defer processing those packets
+until the daemon is negotiated and connected.
+It's okay for guest to respond
+to all negotiation packets.
+
+In addition, the host may send multiple staged
+KVP requests as soon as negotiation is done.
+We need to properly process those packets using one
+tasklet for exclusive access to ring buffer.
+
+This patch is based on the work of
+Nick Meier <Nick.Meier@microsoft.com>.
+
+The above is the original changelog of
+a3ade8cc474d ("HV: properly delay KVP packets when negotiation is in progress"
+
+Here I re-worked the original patch because the mainline version
+can't work for the linux-4.4.y branch, on which channel->callback_event
+doesn't exist yet. In the mainline, channel->callback_event was added by:
+631e63a9f346 ("vmbus: change to per channel tasklet"). Here we don't want
+to backport it to v4.4, as it requires extra supporting changes and fixes,
+which are unnecessary as to the KVP bug we're trying to resolve.
+
+NOTE: before this patch is used, we should cherry-pick the other related
+3 patches from the mainline first:
+
+The background of this backport request is that: recently Wang Jian reported
+some KVP issues: https://github.com/LIS/lis-next/issues/593:
+e.g. the /var/lib/hyperv/.kvp_pool_* files can not be updated, and sometimes
+if the hv_kvp_daemon doesn't timely start, the host may not be able to query
+the VM's IP address via KVP.
+
+Reported-by: Wang Jian <jianjian.wang1@gmail.com>
+Tested-by: Wang Jian <jianjian.wang1@gmail.com>
+Signed-off-by: Dexuan Cui <decui@microsoft.com>
+Signed-off-by: Long Li <longli@microsoft.com>
+Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/hv/hv_kvp.c | 13 ++++++++-----
+ 1 file changed, 8 insertions(+), 5 deletions(-)
+
+--- a/drivers/hv/hv_kvp.c
++++ b/drivers/hv/hv_kvp.c
+@@ -612,21 +612,22 @@ void hv_kvp_onchannelcallback(void *cont
+ NEGO_IN_PROGRESS,
+ NEGO_FINISHED} host_negotiatied = NEGO_NOT_STARTED;
+
+- if (host_negotiatied == NEGO_NOT_STARTED &&
+- kvp_transaction.state < HVUTIL_READY) {
++ if (kvp_transaction.state < HVUTIL_READY) {
+ /*
+ * If userspace daemon is not connected and host is asking
+ * us to negotiate we need to delay to not lose messages.
+ * This is important for Failover IP setting.
+ */
+- host_negotiatied = NEGO_IN_PROGRESS;
+- schedule_delayed_work(&kvp_host_handshake_work,
++ if (host_negotiatied == NEGO_NOT_STARTED) {
++ host_negotiatied = NEGO_IN_PROGRESS;
++ schedule_delayed_work(&kvp_host_handshake_work,
+ HV_UTIL_NEGO_TIMEOUT * HZ);
++ }
+ return;
+ }
+ if (kvp_transaction.state > HVUTIL_READY)
+ return;
+-
++recheck:
+ vmbus_recvpacket(channel, recv_buffer, PAGE_SIZE * 4, &recvlen,
+ &requestid);
+
+@@ -703,6 +704,8 @@ void hv_kvp_onchannelcallback(void *cont
+ VM_PKT_DATA_INBAND, 0);
+
+ host_negotiatied = NEGO_FINISHED;
++
++ goto recheck;
+ }
+
+ }
powerpc-tm-avoid-possible-userspace-r1-corruption-on-reclaim.patch
arc-build-get-rid-of-toolchain-check.patch
usb-gadget-serial-fix-oops-when-data-rx-d-after-close.patch
+drivers-hv-utils-invoke-the-poll-function-after-handshake.patch
+drivers-hv-util-pass-the-channel-information-during-the-init-call.patch
+drivers-hv-kvp-fix-ip-failover.patch
+hv-properly-delay-kvp-packets-when-negotiation-is-in-progress.patch