--- /dev/null
+From b46b4a8a57c377b72a98c7930a9f6969d2d4784e Mon Sep 17 00:00:00 2001
+From: Vineeth Pillai <viremana@linux.microsoft.com>
+Date: Fri, 21 Aug 2020 15:28:49 +0000
+Subject: hv_utils: drain the timesync packets on onchannelcallback
+
+From: Vineeth Pillai <viremana@linux.microsoft.com>
+
+commit b46b4a8a57c377b72a98c7930a9f6969d2d4784e upstream.
+
+There could be instances where a system stall prevents the timesync
+packets to be consumed. And this might lead to more than one packet
+pending in the ring buffer. Current code empties one packet per callback
+and it might be a stale one. So drain all the packets from ring buffer
+on each callback.
+
+Signed-off-by: Vineeth Pillai <viremana@linux.microsoft.com>
+Reviewed-by: Michael Kelley <mikelley@microsoft.com>
+Link: https://lore.kernel.org/r/20200821152849.99517-1-viremana@linux.microsoft.com
+Signed-off-by: Wei Liu <wei.liu@kernel.org>
+[ The upstream commit uses HV_HYP_PAGE_SIZE, which is not defined in 4.19.y.
+ Fixed this manually for 4.19.y by using PAGE_SIZE instead.
+
+ If there are multiple messages in the host-to-guest ringbuffer of the TimeSync
+ device, 4.19.y only handles 1 message, and later the host puts new messages
+ into the ringbuffer without signaling the guest because the ringbuffer is not
+ empty, causing a "hung" ringbuffer. Backported the mainline fix for this issue. ]
+Signed-off-by: Dexuan Cui <decui@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/hv/hv_util.c | 19 ++++++++++++++++---
+ 1 file changed, 16 insertions(+), 3 deletions(-)
+
+--- a/drivers/hv/hv_util.c
++++ b/drivers/hv/hv_util.c
+@@ -294,10 +294,23 @@ static void timesync_onchannelcallback(v
+ struct ictimesync_ref_data *refdata;
+ u8 *time_txf_buf = util_timesynch.recv_buffer;
+
+- vmbus_recvpacket(channel, time_txf_buf,
+- PAGE_SIZE, &recvlen, &requestid);
++ /*
++ * Drain the ring buffer and use the last packet to update
++ * host_ts
++ */
++ while (1) {
++ int ret = vmbus_recvpacket(channel, time_txf_buf,
++ PAGE_SIZE, &recvlen,
++ &requestid);
++ if (ret) {
++ pr_warn_once("TimeSync IC pkt recv failed (Err: %d)\n",
++ ret);
++ break;
++ }
++
++ if (!recvlen)
++ break;
+
+- if (recvlen > 0) {
+ icmsghdrp = (struct icmsg_hdr *)&time_txf_buf[
+ sizeof(struct vmbuspipe_hdr)];
+