--- /dev/null
+From 85572c2c4a45a541e880e087b5b17a48198b2416 Mon Sep 17 00:00:00 2001
+From: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com>
+Date: Wed, 11 Dec 2019 11:28:41 +0100
+Subject: cpufreq: Avoid leaving stale IRQ work items during CPU offline
+
+From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+
+commit 85572c2c4a45a541e880e087b5b17a48198b2416 upstream.
+
+The scheduler code calling cpufreq_update_util() may run during CPU
+offline on the target CPU after the IRQ work lists have been flushed
+for it, so the target CPU should be prevented from running code that
+may queue up an IRQ work item on it at that point.
+
+Unfortunately, that may not be the case if dvfs_possible_from_any_cpu
+is set for at least one cpufreq policy in the system, because that
+allows the CPU going offline to run the utilization update callback
+of the cpufreq governor on behalf of another (online) CPU in some
+cases.
+
+If that happens, the cpufreq governor callback may queue up an IRQ
+work on the CPU running it, which is going offline, and the IRQ work
+may not be flushed after that point. Moreover, that IRQ work cannot
+be flushed until the "offlining" CPU goes back online, so if any
+other CPU calls irq_work_sync() to wait for the completion of that
+IRQ work, it will have to wait until the "offlining" CPU is back
+online and that may not happen forever. In particular, a system-wide
+deadlock may occur during CPU online as a result of that.
+
+The failing scenario is as follows. CPU0 is the boot CPU, so it
+creates a cpufreq policy and becomes the "leader" of it
+(policy->cpu). It cannot go offline, because it is the boot CPU.
+Next, other CPUs join the cpufreq policy as they go online and they
+leave it when they go offline. The last CPU to go offline, say CPU3,
+may queue up an IRQ work while running the governor callback on
+behalf of CPU0 after leaving the cpufreq policy because of the
+dvfs_possible_from_any_cpu effect described above. Then, CPU0 is
+the only online CPU in the system and the stale IRQ work is still
+queued on CPU3. When, say, CPU1 goes back online, it will run
+irq_work_sync() to wait for that IRQ work to complete and so it
+will wait for CPU3 to go back online (which may never happen even
+in principle), but (worse yet) CPU0 is waiting for CPU1 at that
+point too and a system-wide deadlock occurs.
+
+To address this problem notice that CPUs which cannot run cpufreq
+utilization update code for themselves (for example, because they
+have left the cpufreq policies that they belonged to), should also
+be prevented from running that code on behalf of the other CPUs that
+belong to a cpufreq policy with dvfs_possible_from_any_cpu set and so
+in that case the cpufreq_update_util_data pointer of the CPU running
+the code must not be NULL as well as for the CPU which is the target
+of the cpufreq utilization update in progress.
+
+Accordingly, change cpufreq_this_cpu_can_update() into a regular
+function in kernel/sched/cpufreq.c (instead of a static inline in a
+header file) and make it check the cpufreq_update_util_data pointer
+of the local CPU if dvfs_possible_from_any_cpu is set for the target
+cpufreq policy.
+
+Also update the schedutil governor to do the
+cpufreq_this_cpu_can_update() check in the non-fast-switch
+case too to avoid the stale IRQ work issues.
+
+Fixes: 99d14d0e16fa ("cpufreq: Process remote callbacks from any CPU if the platform permits")
+Link: https://lore.kernel.org/linux-pm/20191121093557.bycvdo4xyinbc5cb@vireshk-i7/
+Reported-by: Anson Huang <anson.huang@nxp.com>
+Tested-by: Anson Huang <anson.huang@nxp.com>
+Cc: 4.14+ <stable@vger.kernel.org> # 4.14+
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
+Tested-by: Peng Fan <peng.fan@nxp.com> (i.MX8QXP-MEK)
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ include/linux/cpufreq.h | 11 -----------
+ include/linux/sched/cpufreq.h | 3 +++
+ kernel/sched/cpufreq.c | 18 ++++++++++++++++++
+ kernel/sched/cpufreq_schedutil.c | 8 +++-----
+ 4 files changed, 24 insertions(+), 16 deletions(-)
+
+--- a/include/linux/cpufreq.h
++++ b/include/linux/cpufreq.h
+@@ -595,17 +595,6 @@ struct governor_attr {
+ size_t count);
+ };
+
+-static inline bool cpufreq_this_cpu_can_update(struct cpufreq_policy *policy)
+-{
+- /*
+- * Allow remote callbacks if:
+- * - dvfs_possible_from_any_cpu flag is set
+- * - the local and remote CPUs share cpufreq policy
+- */
+- return policy->dvfs_possible_from_any_cpu ||
+- cpumask_test_cpu(smp_processor_id(), policy->cpus);
+-}
+-
+ /*********************************************************************
+ * FREQUENCY TABLE HELPERS *
+ *********************************************************************/
+--- a/include/linux/sched/cpufreq.h
++++ b/include/linux/sched/cpufreq.h
+@@ -12,6 +12,8 @@
+ #define SCHED_CPUFREQ_MIGRATION (1U << 1)
+
+ #ifdef CONFIG_CPU_FREQ
++struct cpufreq_policy;
++
+ struct update_util_data {
+ void (*func)(struct update_util_data *data, u64 time, unsigned int flags);
+ };
+@@ -20,6 +22,7 @@ void cpufreq_add_update_util_hook(int cp
+ void (*func)(struct update_util_data *data, u64 time,
+ unsigned int flags));
+ void cpufreq_remove_update_util_hook(int cpu);
++bool cpufreq_this_cpu_can_update(struct cpufreq_policy *policy);
+
+ static inline unsigned long map_util_freq(unsigned long util,
+ unsigned long freq, unsigned long cap)
+--- a/kernel/sched/cpufreq.c
++++ b/kernel/sched/cpufreq.c
+@@ -5,6 +5,8 @@
+ * Copyright (C) 2016, Intel Corporation
+ * Author: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+ */
++#include <linux/cpufreq.h>
++
+ #include "sched.h"
+
+ DEFINE_PER_CPU(struct update_util_data __rcu *, cpufreq_update_util_data);
+@@ -57,3 +59,19 @@ void cpufreq_remove_update_util_hook(int
+ rcu_assign_pointer(per_cpu(cpufreq_update_util_data, cpu), NULL);
+ }
+ EXPORT_SYMBOL_GPL(cpufreq_remove_update_util_hook);
++
++/**
++ * cpufreq_this_cpu_can_update - Check if cpufreq policy can be updated.
++ * @policy: cpufreq policy to check.
++ *
++ * Return 'true' if:
++ * - the local and remote CPUs share @policy,
++ * - dvfs_possible_from_any_cpu is set in @policy and the local CPU is not going
++ * offline (in which case it is not expected to run cpufreq updates any more).
++ */
++bool cpufreq_this_cpu_can_update(struct cpufreq_policy *policy)
++{
++ return cpumask_test_cpu(smp_processor_id(), policy->cpus) ||
++ (policy->dvfs_possible_from_any_cpu &&
++ rcu_dereference_sched(*this_cpu_ptr(&cpufreq_update_util_data)));
++}
+--- a/kernel/sched/cpufreq_schedutil.c
++++ b/kernel/sched/cpufreq_schedutil.c
+@@ -82,12 +82,10 @@ static bool sugov_should_update_freq(str
+ * by the hardware, as calculating the frequency is pointless if
+ * we cannot in fact act on it.
+ *
+- * For the slow switching platforms, the kthread is always scheduled on
+- * the right set of CPUs and any CPU can find the next frequency and
+- * schedule the kthread.
++ * This is needed on the slow switching platforms too to prevent CPUs
++ * going offline from leaving stale IRQ work items behind.
+ */
+- if (sg_policy->policy->fast_switch_enabled &&
+- !cpufreq_this_cpu_can_update(sg_policy->policy))
++ if (!cpufreq_this_cpu_can_update(sg_policy->policy))
+ return false;
+
+ if (unlikely(sg_policy->limits_changed)) {
--- /dev/null
+From ab0eb16205b43ece4c78e2259e681ff3d645ea66 Mon Sep 17 00:00:00 2001
+From: Ard Biesheuvel <ardb@kernel.org>
+Date: Fri, 6 Dec 2019 16:55:37 +0000
+Subject: efi/memreserve: Register reservations as 'reserved' in /proc/iomem
+
+From: Ard Biesheuvel <ardb@kernel.org>
+
+commit ab0eb16205b43ece4c78e2259e681ff3d645ea66 upstream.
+
+Memory regions that are reserved using efi_mem_reserve_persistent()
+are recorded in a special EFI config table which survives kexec,
+allowing the incoming kernel to honour them as well. However,
+such reservations are not visible in /proc/iomem, and so the kexec
+tools that load the incoming kernel and its initrd into memory may
+overwrite these reserved regions before the incoming kernel has a
+chance to reserve them from further use.
+
+Address this problem by adding these reservations to /proc/iomem as
+they are created. Note that reservations that are inherited from a
+previous kernel are memblock_reserve()'d early on, so they are already
+visible in /proc/iomem.
+
+Tested-by: Masayoshi Mizuma <m.mizuma@jp.fujitsu.com>
+Tested-by: Bhupesh Sharma <bhsharma@redhat.com>
+Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
+Reviewed-by: Bhupesh Sharma <bhsharma@redhat.com>
+Cc: <stable@vger.kernel.org> # v5.4+
+Cc: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Cc: Arvind Sankar <nivedita@alum.mit.edu>
+Cc: linux-efi@vger.kernel.org
+Link: https://lkml.kernel.org/r/20191206165542.31469-2-ardb@kernel.org
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/firmware/efi/efi.c | 28 ++++++++++++++++++++++++++--
+ 1 file changed, 26 insertions(+), 2 deletions(-)
+
+--- a/drivers/firmware/efi/efi.c
++++ b/drivers/firmware/efi/efi.c
+@@ -970,6 +970,24 @@ static int __init efi_memreserve_map_roo
+ return 0;
+ }
+
++static int efi_mem_reserve_iomem(phys_addr_t addr, u64 size)
++{
++ struct resource *res, *parent;
++
++ res = kzalloc(sizeof(struct resource), GFP_ATOMIC);
++ if (!res)
++ return -ENOMEM;
++
++ res->name = "reserved";
++ res->flags = IORESOURCE_MEM;
++ res->start = addr;
++ res->end = addr + size - 1;
++
++ /* we expect a conflict with a 'System RAM' region */
++ parent = request_resource_conflict(&iomem_resource, res);
++ return parent ? request_resource(parent, res) : 0;
++}
++
+ int __ref efi_mem_reserve_persistent(phys_addr_t addr, u64 size)
+ {
+ struct linux_efi_memreserve *rsv;
+@@ -994,7 +1012,7 @@ int __ref efi_mem_reserve_persistent(phy
+ rsv->entry[index].size = size;
+
+ memunmap(rsv);
+- return 0;
++ return efi_mem_reserve_iomem(addr, size);
+ }
+ memunmap(rsv);
+ }
+@@ -1004,6 +1022,12 @@ int __ref efi_mem_reserve_persistent(phy
+ if (!rsv)
+ return -ENOMEM;
+
++ rc = efi_mem_reserve_iomem(__pa(rsv), SZ_4K);
++ if (rc) {
++ free_page((unsigned long)rsv);
++ return rc;
++ }
++
+ /*
+ * The memremap() call above assumes that a linux_efi_memreserve entry
+ * never crosses a page boundary, so let's ensure that this remains true
+@@ -1020,7 +1044,7 @@ int __ref efi_mem_reserve_persistent(phy
+ efi_memreserve_root->next = __pa(rsv);
+ spin_unlock(&efi_mem_reserve_persistent_lock);
+
+- return 0;
++ return efi_mem_reserve_iomem(addr, size);
+ }
+
+ static int __init efi_memreserve_root_init(void)
--- /dev/null
+From ab832e38e4f0f45b16c3633714d868b7ec6b33b4 Mon Sep 17 00:00:00 2001
+From: Alexander Shishkin <alexander.shishkin@linux.intel.com>
+Date: Tue, 17 Dec 2019 13:55:26 +0200
+Subject: intel_th: Fix freeing IRQs
+
+From: Alexander Shishkin <alexander.shishkin@linux.intel.com>
+
+commit ab832e38e4f0f45b16c3633714d868b7ec6b33b4 upstream.
+
+Commit aac8da65174a ("intel_th: msu: Start handling IRQs") implicitly
+relies on the use of devm_request_irq() to subsequently free the irqs on
+device removal, but in case of the pci_free_irq_vectors() API, the
+handlers need to be freed before it is called. Therefore, at the moment
+the driver's remove path trips a BUG_ON(irq_has_action()):
+
+> kernel BUG at drivers/pci/msi.c:375!
+> invalid opcode: 0000 1 SMP
+> CPU: 2 PID: 818 Comm: rmmod Not tainted 5.5.0-rc1+ #1
+> RIP: 0010:free_msi_irqs+0x67/0x1c0
+> pci_disable_msi+0x116/0x150
+> pci_free_irq_vectors+0x1b/0x20
+> intel_th_pci_remove+0x22/0x30 [intel_th_pci]
+> pci_device_remove+0x3e/0xb0
+> device_release_driver_internal+0xf0/0x1c0
+> driver_detach+0x4c/0x8f
+> bus_remove_driver+0x5c/0xd0
+> driver_unregister+0x31/0x50
+> pci_unregister_driver+0x40/0x90
+> intel_th_pci_driver_exit+0x10/0xad6 [intel_th_pci]
+> __x64_sys_delete_module+0x147/0x290
+> ? exit_to_usermode_loop+0xd7/0x120
+> do_syscall_64+0x57/0x1b0
+> entry_SYSCALL_64_after_hwframe+0x44/0xa9
+
+Fix this by explicitly freeing irqs before freeing the vectors. We keep
+using the devm_* variants because they are still useful in early error
+paths.
+
+Signed-off-by: Alexander Shishkin <alexander.shishkin@linux.intel.com>
+Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Fixes: aac8da65174a ("intel_th: msu: Start handling IRQs")
+Reported-by: Ammy Yi <ammy.yi@intel.com>
+Tested-by: Ammy Yi <ammy.yi@intel.com>
+Cc: stable@vger.kernel.org # v5.2+
+Link: https://lore.kernel.org/r/20191217115527.74383-4-alexander.shishkin@linux.intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/hwtracing/intel_th/core.c | 7 ++++---
+ drivers/hwtracing/intel_th/intel_th.h | 2 ++
+ 2 files changed, 6 insertions(+), 3 deletions(-)
+
+--- a/drivers/hwtracing/intel_th/core.c
++++ b/drivers/hwtracing/intel_th/core.c
+@@ -834,9 +834,6 @@ static irqreturn_t intel_th_irq(int irq,
+ ret |= d->irq(th->thdev[i]);
+ }
+
+- if (ret == IRQ_NONE)
+- pr_warn_ratelimited("nobody cared for irq\n");
+-
+ return ret;
+ }
+
+@@ -887,6 +884,7 @@ intel_th_alloc(struct device *dev, struc
+
+ if (th->irq == -1)
+ th->irq = devres[r].start;
++ th->num_irqs++;
+ break;
+ default:
+ dev_warn(dev, "Unknown resource type %lx\n",
+@@ -940,6 +938,9 @@ void intel_th_free(struct intel_th *th)
+
+ th->num_thdevs = 0;
+
++ for (i = 0; i < th->num_irqs; i++)
++ devm_free_irq(th->dev, th->irq + i, th);
++
+ pm_runtime_get_sync(th->dev);
+ pm_runtime_forbid(th->dev);
+
+--- a/drivers/hwtracing/intel_th/intel_th.h
++++ b/drivers/hwtracing/intel_th/intel_th.h
+@@ -261,6 +261,7 @@ enum th_mmio_idx {
+ * @num_thdevs: number of devices in the @thdev array
+ * @num_resources: number of resources in the @resource array
+ * @irq: irq number
++ * @num_irqs: number of IRQs is use
+ * @id: this Intel TH controller's device ID in the system
+ * @major: device node major for output devices
+ */
+@@ -277,6 +278,7 @@ struct intel_th {
+ unsigned int num_thdevs;
+ unsigned int num_resources;
+ int irq;
++ int num_irqs;
+
+ int id;
+ int major;
--- /dev/null
+From 05b686b573cfb35a227c30787083a6631ff0f0c9 Mon Sep 17 00:00:00 2001
+From: Alexander Shishkin <alexander.shishkin@linux.intel.com>
+Date: Tue, 17 Dec 2019 13:55:27 +0200
+Subject: intel_th: msu: Fix window switching without windows
+
+From: Alexander Shishkin <alexander.shishkin@linux.intel.com>
+
+commit 05b686b573cfb35a227c30787083a6631ff0f0c9 upstream.
+
+Commit 6cac7866c2741 ("intel_th: msu: Add a sysfs attribute to trigger
+window switch") adds a NULL pointer dereference in the case when there are
+no windows allocated:
+
+> BUG: kernel NULL pointer dereference, address: 0000000000000000
+> #PF: supervisor read access in kernel mode
+> #PF: error_code(0x0000) - not-present page
+> PGD 0 P4D 0
+> Oops: 0000 1 SMP
+> CPU: 5 PID: 1110 Comm: bash Not tainted 5.5.0-rc1+ #1
+> RIP: 0010:msc_win_switch+0xa/0x80 [intel_th_msu]
+> Call Trace:
+> ? win_switch_store+0x9b/0xc0 [intel_th_msu]
+> dev_attr_store+0x17/0x30
+> sysfs_kf_write+0x3e/0x50
+> kernfs_fop_write+0xda/0x1b0
+> __vfs_write+0x1b/0x40
+> vfs_write+0xb9/0x1a0
+> ksys_write+0x67/0xe0
+> __x64_sys_write+0x1a/0x20
+> do_syscall_64+0x57/0x1d0
+> entry_SYSCALL_64_after_hwframe+0x44/0xa9
+
+Fix that by disallowing window switching with multiwindow buffers without
+windows.
+
+Signed-off-by: Alexander Shishkin <alexander.shishkin@linux.intel.com>
+Fixes: 6cac7866c274 ("intel_th: msu: Add a sysfs attribute to trigger window switch")
+Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Reported-by: Ammy Yi <ammy.yi@intel.com>
+Tested-by: Ammy Yi <ammy.yi@intel.com>
+Cc: stable@vger.kernel.org # v5.2+
+Link: https://lore.kernel.org/r/20191217115527.74383-5-alexander.shishkin@linux.intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/hwtracing/intel_th/msu.c | 14 +++++++++-----
+ 1 file changed, 9 insertions(+), 5 deletions(-)
+
+--- a/drivers/hwtracing/intel_th/msu.c
++++ b/drivers/hwtracing/intel_th/msu.c
+@@ -1676,10 +1676,13 @@ static int intel_th_msc_init(struct msc
+ return 0;
+ }
+
+-static void msc_win_switch(struct msc *msc)
++static int msc_win_switch(struct msc *msc)
+ {
+ struct msc_window *first;
+
++ if (list_empty(&msc->win_list))
++ return -EINVAL;
++
+ first = list_first_entry(&msc->win_list, struct msc_window, entry);
+
+ if (msc_is_last_win(msc->cur_win))
+@@ -1691,6 +1694,8 @@ static void msc_win_switch(struct msc *m
+ msc->base_addr = msc_win_base_dma(msc->cur_win);
+
+ intel_th_trace_switch(msc->thdev);
++
++ return 0;
+ }
+
+ /**
+@@ -2025,16 +2030,15 @@ win_switch_store(struct device *dev, str
+ if (val != 1)
+ return -EINVAL;
+
++ ret = -EINVAL;
+ mutex_lock(&msc->buf_mutex);
+ /*
+ * Window switch can only happen in the "multi" mode.
+ * If a external buffer is engaged, they have the full
+ * control over window switching.
+ */
+- if (msc->mode != MSC_MODE_MULTI || msc->mbuf)
+- ret = -ENOTSUPP;
+- else
+- msc_win_switch(msc);
++ if (msc->mode == MSC_MODE_MULTI && !msc->mbuf)
++ ret = msc_win_switch(msc);
+ mutex_unlock(&msc->buf_mutex);
+
+ return ret ? ret : size;
--- /dev/null
+From e4de2a5d51f97a6e720a1c0911f93e2d8c2f1c08 Mon Sep 17 00:00:00 2001
+From: Alexander Shishkin <alexander.shishkin@linux.intel.com>
+Date: Tue, 17 Dec 2019 13:55:24 +0200
+Subject: intel_th: pci: Add Comet Lake PCH-V support
+
+From: Alexander Shishkin <alexander.shishkin@linux.intel.com>
+
+commit e4de2a5d51f97a6e720a1c0911f93e2d8c2f1c08 upstream.
+
+This adds Intel(R) Trace Hub PCI ID for Comet Lake PCH-V.
+
+Signed-off-by: Alexander Shishkin <alexander.shishkin@linux.intel.com>
+Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Cc: <stable@vger.kernel.org>
+Link: https://lore.kernel.org/r/20191217115527.74383-2-alexander.shishkin@linux.intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/hwtracing/intel_th/pci.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+--- a/drivers/hwtracing/intel_th/pci.c
++++ b/drivers/hwtracing/intel_th/pci.c
+@@ -205,6 +205,11 @@ static const struct pci_device_id intel_
+ .driver_data = (kernel_ulong_t)&intel_th_2x,
+ },
+ {
++ /* Comet Lake PCH-V */
++ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xa3a6),
++ .driver_data = (kernel_ulong_t)&intel_th_2x,
++ },
++ {
+ /* Ice Lake NNPI */
+ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x45c5),
+ .driver_data = (kernel_ulong_t)&intel_th_2x,
--- /dev/null
+From 88385866bab8d5e18c7f45d1023052c783572e03 Mon Sep 17 00:00:00 2001
+From: Alexander Shishkin <alexander.shishkin@linux.intel.com>
+Date: Tue, 17 Dec 2019 13:55:25 +0200
+Subject: intel_th: pci: Add Elkhart Lake SOC support
+
+From: Alexander Shishkin <alexander.shishkin@linux.intel.com>
+
+commit 88385866bab8d5e18c7f45d1023052c783572e03 upstream.
+
+This adds support for Intel Trace Hub in Elkhart Lake.
+
+Signed-off-by: Alexander Shishkin <alexander.shishkin@linux.intel.com>
+Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Cc: stable@vger.kernel.org
+Link: https://lore.kernel.org/r/20191217115527.74383-3-alexander.shishkin@linux.intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/hwtracing/intel_th/pci.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+--- a/drivers/hwtracing/intel_th/pci.c
++++ b/drivers/hwtracing/intel_th/pci.c
+@@ -234,6 +234,11 @@ static const struct pci_device_id intel_
+ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x4da6),
+ .driver_data = (kernel_ulong_t)&intel_th_2x,
+ },
++ {
++ /* Elkhart Lake */
++ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x4b26),
++ .driver_data = (kernel_ulong_t)&intel_th_2x,
++ },
+ { 0 },
+ };
+
--- /dev/null
+From bea37414453eb08d4ceffeb60a9d490dbc930cea Mon Sep 17 00:00:00 2001
+From: Eric Biggers <ebiggers@google.com>
+Date: Wed, 9 Oct 2019 16:03:49 -0700
+Subject: KEYS: asymmetric: return ENOMEM if akcipher_request_alloc() fails
+
+From: Eric Biggers <ebiggers@google.com>
+
+commit bea37414453eb08d4ceffeb60a9d490dbc930cea upstream.
+
+No error code was being set on this error path.
+
+Cc: stable@vger.kernel.org
+Fixes: ad4b1eb5fb33 ("KEYS: asym_tpm: Implement encryption operation [ver #2]")
+Fixes: c08fed737126 ("KEYS: Implement encrypt, decrypt and sign for software asymmetric key [ver #2]")
+Reviewed-by: James Morris <jamorris@linux.microsoft.com>
+Signed-off-by: Eric Biggers <ebiggers@google.com>
+Reviewed-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
+Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ crypto/asymmetric_keys/asym_tpm.c | 1 +
+ crypto/asymmetric_keys/public_key.c | 1 +
+ 2 files changed, 2 insertions(+)
+
+--- a/crypto/asymmetric_keys/asym_tpm.c
++++ b/crypto/asymmetric_keys/asym_tpm.c
+@@ -486,6 +486,7 @@ static int tpm_key_encrypt(struct tpm_ke
+ if (ret < 0)
+ goto error_free_tfm;
+
++ ret = -ENOMEM;
+ req = akcipher_request_alloc(tfm, GFP_KERNEL);
+ if (!req)
+ goto error_free_tfm;
+--- a/crypto/asymmetric_keys/public_key.c
++++ b/crypto/asymmetric_keys/public_key.c
+@@ -184,6 +184,7 @@ static int software_key_eds_op(struct ke
+ if (IS_ERR(tfm))
+ return PTR_ERR(tfm);
+
++ ret = -ENOMEM;
+ req = akcipher_request_alloc(tfm, GFP_KERNEL);
+ if (!req)
+ goto error_free_tfm;
--- /dev/null
+From 42a9a53bb394a1de2247ef78f0b802ae86798122 Mon Sep 17 00:00:00 2001
+From: Yang Shi <yang.shi@linux.alibaba.com>
+Date: Tue, 17 Dec 2019 20:51:52 -0800
+Subject: mm: vmscan: protect shrinker idr replace with CONFIG_MEMCG
+
+From: Yang Shi <yang.shi@linux.alibaba.com>
+
+commit 42a9a53bb394a1de2247ef78f0b802ae86798122 upstream.
+
+Since commit 0a432dcbeb32 ("mm: shrinker: make shrinker not depend on
+memcg kmem"), shrinkers' idr is protected by CONFIG_MEMCG instead of
+CONFIG_MEMCG_KMEM, so it makes no sense to protect shrinker idr replace
+with CONFIG_MEMCG_KMEM.
+
+And in the CONFIG_MEMCG && CONFIG_SLOB case, shrinker_idr contains only
+shrinker, and it is deferred_split_shrinker. But it is never actually
+called, since idr_replace() is never compiled due to the wrong #ifdef.
+The deferred_split_shrinker all the time is staying in half-registered
+state, and it's never called for subordinate mem cgroups.
+
+Link: http://lkml.kernel.org/r/1575486978-45249-1-git-send-email-yang.shi@linux.alibaba.com
+Fixes: 0a432dcbeb32 ("mm: shrinker: make shrinker not depend on memcg kmem")
+Signed-off-by: Yang Shi <yang.shi@linux.alibaba.com>
+Reviewed-by: Kirill Tkhai <ktkhai@virtuozzo.com>
+Acked-by: Michal Hocko <mhocko@suse.com>
+Cc: Johannes Weiner <hannes@cmpxchg.org>
+Cc: Shakeel Butt <shakeelb@google.com>
+Cc: Roman Gushchin <guro@fb.com>
+Cc: <stable@vger.kernel.org> [5.4+]
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ mm/vmscan.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/mm/vmscan.c
++++ b/mm/vmscan.c
+@@ -422,7 +422,7 @@ void register_shrinker_prepared(struct s
+ {
+ down_write(&shrinker_rwsem);
+ list_add_tail(&shrinker->list, &shrinker_list);
+-#ifdef CONFIG_MEMCG_KMEM
++#ifdef CONFIG_MEMCG
+ if (shrinker->flags & SHRINKER_MEMCG_AWARE)
+ idr_replace(&shrinker_idr, shrinker, shrinker->id);
+ #endif
--- /dev/null
+From 133b2acee3871ae6bf123b8fe34be14464aa3d2c Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede@redhat.com>
+Date: Tue, 17 Dec 2019 20:06:04 +0100
+Subject: platform/x86: hp-wmi: Make buffer for HPWMI_FEATURE2_QUERY 128 bytes
+
+From: Hans de Goede <hdegoede@redhat.com>
+
+commit 133b2acee3871ae6bf123b8fe34be14464aa3d2c upstream.
+
+At least on the HP Envy x360 15-cp0xxx model the WMI interface
+for HPWMI_FEATURE2_QUERY requires an outsize of at least 128 bytes,
+otherwise it fails with an error code 5 (HPWMI_RET_INVALID_PARAMETERS):
+
+Dec 06 00:59:38 kernel: hp_wmi: query 0xd returned error 0x5
+
+We do not care about the contents of the buffer, we just want to know
+if the HPWMI_FEATURE2_QUERY command is supported.
+
+This commits bumps the buffer size, fixing the error.
+
+Fixes: 8a1513b4932 ("hp-wmi: limit hotkey enable")
+Cc: stable@vger.kernel.org
+BugLink: https://bugzilla.redhat.com/show_bug.cgi?id=1520703
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/platform/x86/hp-wmi.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/platform/x86/hp-wmi.c
++++ b/drivers/platform/x86/hp-wmi.c
+@@ -300,7 +300,7 @@ static int __init hp_wmi_bios_2008_later
+
+ static int __init hp_wmi_bios_2009_later(void)
+ {
+- int state = 0;
++ u8 state[128];
+ int ret = hp_wmi_perform_query(HPWMI_FEATURE2_QUERY, HPWMI_READ, &state,
+ sizeof(state), sizeof(state));
+ if (!ret)
s390-ftrace-fix-endless-recursion-in-function_graph-.patch
arm-dts-fix-vcsi-regulator-to-be-always-on-for-droid.patch
can-flexcan-add-low-power-enter-exit-acknowledgment-.patch
+usbip-fix-receive-error-in-vhci-hcd-when-using-scatter-gather.patch
+usbip-fix-error-path-of-vhci_recv_ret_submit.patch
+spi-fsl-don-t-map-irq-during-probe.patch
+spi-fsl-use-platform_get_irq-instead-of-of_irq_to_resource.patch
+efi-memreserve-register-reservations-as-reserved-in-proc-iomem.patch
+cpufreq-avoid-leaving-stale-irq-work-items-during-cpu-offline.patch
+keys-asymmetric-return-enomem-if-akcipher_request_alloc-fails.patch
+mm-vmscan-protect-shrinker-idr-replace-with-config_memcg.patch
+usb-ehci-do-not-return-epipe-when-hub-is-disconnected.patch
+intel_th-pci-add-comet-lake-pch-v-support.patch
+intel_th-pci-add-elkhart-lake-soc-support.patch
+intel_th-fix-freeing-irqs.patch
+intel_th-msu-fix-window-switching-without-windows.patch
+platform-x86-hp-wmi-make-buffer-for-hpwmi_feature2_query-128-bytes.patch
+staging-comedi-gsc_hpdi-check-dma_alloc_coherent-return-value.patch
--- /dev/null
+From 3194d2533efffae8b815d84729ecc58b6a9000ab Mon Sep 17 00:00:00 2001
+From: Christophe Leroy <christophe.leroy@c-s.fr>
+Date: Mon, 9 Dec 2019 15:27:27 +0000
+Subject: spi: fsl: don't map irq during probe
+
+From: Christophe Leroy <christophe.leroy@c-s.fr>
+
+commit 3194d2533efffae8b815d84729ecc58b6a9000ab upstream.
+
+With lastest kernel, the following warning is observed at startup:
+
+[ 1.500609] ------------[ cut here ]------------
+[ 1.505225] remove_proc_entry: removing non-empty directory 'irq/22', leaking at least 'fsl_spi'
+[ 1.514234] WARNING: CPU: 0 PID: 1 at fs/proc/generic.c:682 remove_proc_entry+0x198/0x1c0
+[ 1.522403] CPU: 0 PID: 1 Comm: swapper Not tainted 5.4.0-s3k-dev-02248-g93532430a4ff #2564
+[ 1.530724] NIP: c0197694 LR: c0197694 CTR: c0050d80
+[ 1.535762] REGS: df4a5af0 TRAP: 0700 Not tainted (5.4.0-02248-g93532430a4ff)
+[ 1.543818] MSR: 00029032 <EE,ME,IR,DR,RI> CR: 22028222 XER: 00000000
+[ 1.550524]
+[ 1.550524] GPR00: c0197694 df4a5ba8 df4a0000 00000054 00000000 00000000 00004a38 00000010
+[ 1.550524] GPR08: c07c5a30 00000800 00000000 00001032 22000208 00000000 c0004b14 00000000
+[ 1.550524] GPR16: 00000000 00000000 00000000 00000000 00000000 00000000 c0830000 c07fc078
+[ 1.550524] GPR24: c08e8ca0 df665d10 df60ea98 c07c9db8 00000001 df5d5ae3 df5d5a80 df43f8e3
+[ 1.585327] NIP [c0197694] remove_proc_entry+0x198/0x1c0
+[ 1.590628] LR [c0197694] remove_proc_entry+0x198/0x1c0
+[ 1.595829] Call Trace:
+[ 1.598280] [df4a5ba8] [c0197694] remove_proc_entry+0x198/0x1c0 (unreliable)
+[ 1.605321] [df4a5bd8] [c0067acc] unregister_irq_proc+0x5c/0x70
+[ 1.611238] [df4a5bf8] [c005fbc4] free_desc+0x3c/0x80
+[ 1.616286] [df4a5c18] [c005fe2c] irq_free_descs+0x70/0xa8
+[ 1.621778] [df4a5c38] [c033d3fc] of_fsl_spi_probe+0xdc/0x3cc
+[ 1.627525] [df4a5c88] [c02f0f64] platform_drv_probe+0x44/0xa4
+[ 1.633350] [df4a5c98] [c02eee44] really_probe+0x1ac/0x418
+[ 1.638829] [df4a5cc8] [c02ed3e8] bus_for_each_drv+0x64/0xb0
+[ 1.644481] [df4a5cf8] [c02ef950] __device_attach+0xd4/0x128
+[ 1.650132] [df4a5d28] [c02ed61c] bus_probe_device+0xa0/0xbc
+[ 1.655783] [df4a5d48] [c02ebbe8] device_add+0x544/0x74c
+[ 1.661096] [df4a5d88] [c0382b78] of_platform_device_create_pdata+0xa4/0x100
+[ 1.668131] [df4a5da8] [c0382cf4] of_platform_bus_create+0x120/0x20c
+[ 1.674474] [df4a5df8] [c0382d50] of_platform_bus_create+0x17c/0x20c
+[ 1.680818] [df4a5e48] [c0382e88] of_platform_bus_probe+0x9c/0xf0
+[ 1.686907] [df4a5e68] [c0751404] __machine_initcall_cmpcpro_cmpcpro_declare_of_platform_devices+0x74/0x1a4
+[ 1.696629] [df4a5e98] [c072a4cc] do_one_initcall+0x8c/0x1d4
+[ 1.702282] [df4a5ef8] [c072a768] kernel_init_freeable+0x154/0x204
+[ 1.708455] [df4a5f28] [c0004b2c] kernel_init+0x18/0x110
+[ 1.713769] [df4a5f38] [c00122ac] ret_from_kernel_thread+0x14/0x1c
+[ 1.719926] Instruction dump:
+[ 1.722889] 2c030000 4182004c 3863ffb0 3c80c05f 80e3005c 388436a0 3c60c06d 7fa6eb78
+[ 1.730630] 7fe5fb78 38840280 38634178 4be8c611 <0fe00000> 4bffff6c 3c60c071 7fe4fb78
+[ 1.738556] ---[ end trace 05d0720bf2e352e2 ]---
+
+The problem comes from the error path which calls
+irq_dispose_mapping() while the IRQ has been requested with
+devm_request_irq().
+
+IRQ doesn't need to be mapped with irq_of_parse_and_map(). The only
+need is to get the IRQ virtual number. For that, use
+of_irq_to_resource() instead of the
+irq_of_parse_and_map()/irq_dispose_mapping() pair.
+
+Fixes: 500a32abaf81 ("spi: fsl: Call irq_dispose_mapping in err path")
+Cc: stable@vger.kernel.org
+Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
+Link: https://lore.kernel.org/r/518cfb83347d5372748e7fe72f94e2e9443d0d4a.1575905123.git.christophe.leroy@c-s.fr
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/spi/spi-fsl-spi.c | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+--- a/drivers/spi/spi-fsl-spi.c
++++ b/drivers/spi/spi-fsl-spi.c
+@@ -736,8 +736,8 @@ static int of_fsl_spi_probe(struct platf
+ if (ret)
+ goto err;
+
+- irq = irq_of_parse_and_map(np, 0);
+- if (!irq) {
++ irq = of_irq_to_resource(np, 0, NULL);
++ if (irq <= 0) {
+ ret = -EINVAL;
+ goto err;
+ }
+@@ -751,7 +751,6 @@ static int of_fsl_spi_probe(struct platf
+ return 0;
+
+ err:
+- irq_dispose_mapping(irq);
+ return ret;
+ }
+
--- /dev/null
+From 63aa6a692595d47a0785297b481072086b9272d2 Mon Sep 17 00:00:00 2001
+From: Christophe Leroy <christophe.leroy@c-s.fr>
+Date: Thu, 12 Dec 2019 17:47:24 +0000
+Subject: spi: fsl: use platform_get_irq() instead of of_irq_to_resource()
+
+From: Christophe Leroy <christophe.leroy@c-s.fr>
+
+commit 63aa6a692595d47a0785297b481072086b9272d2 upstream.
+
+Unlike irq_of_parse_and_map() which has a dummy definition on SPARC,
+of_irq_to_resource() hasn't.
+
+But as platform_get_irq() can be used instead and is generic, use it.
+
+Reported-by: kbuild test robot <lkp@intel.com>
+Suggested-by: Mark Brown <broonie@kernel.org>
+Fixes: 3194d2533eff ("spi: fsl: don't map irq during probe")
+Cc: stable@vger.kernel.org
+Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
+Link: https://lore.kernel.org/r/091a277fd0b3356dca1e29858c1c96983fc9cb25.1576172743.git.christophe.leroy@c-s.fr
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/spi/spi-fsl-spi.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- a/drivers/spi/spi-fsl-spi.c
++++ b/drivers/spi/spi-fsl-spi.c
+@@ -736,9 +736,9 @@ static int of_fsl_spi_probe(struct platf
+ if (ret)
+ goto err;
+
+- irq = of_irq_to_resource(np, 0, NULL);
+- if (irq <= 0) {
+- ret = -EINVAL;
++ irq = platform_get_irq(ofdev, 0);
++ if (irq < 0) {
++ ret = irq;
+ goto err;
+ }
+
--- /dev/null
+From ab42b48f32d4c766420c3499ee9c0289b7028182 Mon Sep 17 00:00:00 2001
+From: Ian Abbott <abbotti@mev.co.uk>
+Date: Mon, 16 Dec 2019 11:08:23 +0000
+Subject: staging: comedi: gsc_hpdi: check dma_alloc_coherent() return value
+
+From: Ian Abbott <abbotti@mev.co.uk>
+
+commit ab42b48f32d4c766420c3499ee9c0289b7028182 upstream.
+
+The "auto-attach" handler function `gsc_hpdi_auto_attach()` calls
+`dma_alloc_coherent()` in a loop to allocate some DMA data buffers, and
+also calls it to allocate a buffer for a DMA descriptor chain. However,
+it does not check the return value of any of these calls. Change
+`gsc_hpdi_auto_attach()` to return `-ENOMEM` if any of these
+`dma_alloc_coherent()` calls fail. This will result in the comedi core
+calling the "detach" handler `gsc_hpdi_detach()` as part of the
+clean-up, which will call `gsc_hpdi_free_dma()` to free any allocated
+DMA coherent memory buffers.
+
+Cc: <stable@vger.kernel.org> #4.6+
+Signed-off-by: Ian Abbott <abbotti@mev.co.uk>
+Link: https://lore.kernel.org/r/20191216110823.216237-1-abbotti@mev.co.uk
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/staging/comedi/drivers/gsc_hpdi.c | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+--- a/drivers/staging/comedi/drivers/gsc_hpdi.c
++++ b/drivers/staging/comedi/drivers/gsc_hpdi.c
+@@ -623,6 +623,11 @@ static int gsc_hpdi_auto_attach(struct c
+ dma_alloc_coherent(&pcidev->dev, DMA_BUFFER_SIZE,
+ &devpriv->dio_buffer_phys_addr[i],
+ GFP_KERNEL);
++ if (!devpriv->dio_buffer[i]) {
++ dev_warn(dev->class_dev,
++ "failed to allocate DMA buffer\n");
++ return -ENOMEM;
++ }
+ }
+ /* allocate dma descriptors */
+ devpriv->dma_desc = dma_alloc_coherent(&pcidev->dev,
+@@ -630,6 +635,11 @@ static int gsc_hpdi_auto_attach(struct c
+ NUM_DMA_DESCRIPTORS,
+ &devpriv->dma_desc_phys_addr,
+ GFP_KERNEL);
++ if (!devpriv->dma_desc) {
++ dev_warn(dev->class_dev,
++ "failed to allocate DMA descriptors\n");
++ return -ENOMEM;
++ }
+ if (devpriv->dma_desc_phys_addr & 0xf) {
+ dev_warn(dev->class_dev,
+ " dma descriptors not quad-word aligned (bug)\n");
--- /dev/null
+From 64cc3f12d1c7dd054a215bc1ff9cc2abcfe35832 Mon Sep 17 00:00:00 2001
+From: Erkka Talvitie <erkka.talvitie@vincit.fi>
+Date: Wed, 11 Dec 2019 10:08:39 +0200
+Subject: USB: EHCI: Do not return -EPIPE when hub is disconnected
+
+From: Erkka Talvitie <erkka.talvitie@vincit.fi>
+
+commit 64cc3f12d1c7dd054a215bc1ff9cc2abcfe35832 upstream.
+
+When disconnecting a USB hub that has some child device(s) connected to it
+(such as a USB mouse), then the stack tries to clear halt and
+reset device(s) which are _already_ physically disconnected.
+
+The issue has been reproduced with:
+
+CPU: IMX6D5EYM10AD or MCIMX6D5EYM10AE.
+SW: U-Boot 2019.07 and kernel 4.19.40.
+
+CPU: HP Proliant Microserver Gen8.
+SW: Linux version 4.2.3-300.fc23.x86_64
+
+In this situation there will be error bit for MMF active yet the
+CERR equals EHCI_TUNE_CERR + halt. Existing implementation
+interprets this as a stall [1] (chapter 8.4.5).
+
+The possible conditions when the MMF will be active + halt
+can be found from [2] (Table 4-13).
+
+Fix for the issue is to check whether MMF is active and PID Code is
+IN before checking for the stall. If these conditions are true then
+it is not a stall.
+
+What happens after the fix is that when disconnecting a hub with
+attached device(s) the situation is not interpret as a stall.
+
+[1] [https://www.usb.org/document-library/usb-20-specification, usb_20.pdf]
+[2] [https://www.intel.com/content/dam/www/public/us/en/documents/
+ technical-specifications/ehci-specification-for-usb.pdf]
+
+Signed-off-by: Erkka Talvitie <erkka.talvitie@vincit.fi>
+Reviewed-by: Alan Stern <stern@rowland.harvard.edu>
+Cc: stable <stable@vger.kernel.org>
+Link: https://lore.kernel.org/r/ef70941d5f349767f19c0ed26b0dd9eed8ad81bb.1576050523.git.erkka.talvitie@vincit.fi
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/host/ehci-q.c | 13 ++++++++++++-
+ 1 file changed, 12 insertions(+), 1 deletion(-)
+
+--- a/drivers/usb/host/ehci-q.c
++++ b/drivers/usb/host/ehci-q.c
+@@ -27,6 +27,10 @@
+
+ /*-------------------------------------------------------------------------*/
+
++/* PID Codes that are used here, from EHCI specification, Table 3-16. */
++#define PID_CODE_IN 1
++#define PID_CODE_SETUP 2
++
+ /* fill a qtd, returning how much of the buffer we were able to queue up */
+
+ static int
+@@ -190,7 +194,7 @@ static int qtd_copy_status (
+ int status = -EINPROGRESS;
+
+ /* count IN/OUT bytes, not SETUP (even short packets) */
+- if (likely (QTD_PID (token) != 2))
++ if (likely(QTD_PID(token) != PID_CODE_SETUP))
+ urb->actual_length += length - QTD_LENGTH (token);
+
+ /* don't modify error codes */
+@@ -206,6 +210,13 @@ static int qtd_copy_status (
+ if (token & QTD_STS_BABBLE) {
+ /* FIXME "must" disable babbling device's port too */
+ status = -EOVERFLOW;
++ /*
++ * When MMF is active and PID Code is IN, queue is halted.
++ * EHCI Specification, Table 4-13.
++ */
++ } else if ((token & QTD_STS_MMF) &&
++ (QTD_PID(token) == PID_CODE_IN)) {
++ status = -EPROTO;
+ /* CERR nonzero + halt --> stall */
+ } else if (QTD_CERR(token)) {
+ status = -EPIPE;
--- /dev/null
+From aabb5b833872524eaf28f52187e5987984982264 Mon Sep 17 00:00:00 2001
+From: Suwan Kim <suwan.kim027@gmail.com>
+Date: Fri, 13 Dec 2019 11:30:55 +0900
+Subject: usbip: Fix error path of vhci_recv_ret_submit()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Suwan Kim <suwan.kim027@gmail.com>
+
+commit aabb5b833872524eaf28f52187e5987984982264 upstream.
+
+If a transaction error happens in vhci_recv_ret_submit(), event
+handler closes connection and changes port status to kick hub_event.
+Then hub tries to flush the endpoint URBs, but that causes infinite
+loop between usb_hub_flush_endpoint() and vhci_urb_dequeue() because
+"vhci_priv" in vhci_urb_dequeue() was already released by
+vhci_recv_ret_submit() before a transmission error occurred. Thus,
+vhci_urb_dequeue() terminates early and usb_hub_flush_endpoint()
+continuously calls vhci_urb_dequeue().
+
+The root cause of this issue is that vhci_recv_ret_submit()
+terminates early without giving back URB when transaction error
+occurs in vhci_recv_ret_submit(). That causes the error URB to still
+be linked at endpoint list without “vhci_priv".
+
+So, in the case of transaction error in vhci_recv_ret_submit(),
+unlink URB from the endpoint, insert proper error code in
+urb->status and give back URB.
+
+Reported-by: Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com>
+Tested-by: Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com>
+Signed-off-by: Suwan Kim <suwan.kim027@gmail.com>
+Cc: stable <stable@vger.kernel.org>
+Acked-by: Shuah Khan <skhan@linuxfoundation.org>
+Link: https://lore.kernel.org/r/20191213023055.19933-3-suwan.kim027@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/usbip/vhci_rx.c | 13 +++++++++----
+ 1 file changed, 9 insertions(+), 4 deletions(-)
+
+--- a/drivers/usb/usbip/vhci_rx.c
++++ b/drivers/usb/usbip/vhci_rx.c
+@@ -77,16 +77,21 @@ static void vhci_recv_ret_submit(struct
+ usbip_pack_pdu(pdu, urb, USBIP_RET_SUBMIT, 0);
+
+ /* recv transfer buffer */
+- if (usbip_recv_xbuff(ud, urb) < 0)
+- return;
++ if (usbip_recv_xbuff(ud, urb) < 0) {
++ urb->status = -EPROTO;
++ goto error;
++ }
+
+ /* recv iso_packet_descriptor */
+- if (usbip_recv_iso(ud, urb) < 0)
+- return;
++ if (usbip_recv_iso(ud, urb) < 0) {
++ urb->status = -EPROTO;
++ goto error;
++ }
+
+ /* restore the padding in iso packets */
+ usbip_pad_iso(ud, urb);
+
++error:
+ if (usbip_dbg_flag_vhci_rx)
+ usbip_dump_urb(urb);
+
--- /dev/null
+From d986294ee55d719562b20aabe15a39bf8f863415 Mon Sep 17 00:00:00 2001
+From: Suwan Kim <suwan.kim027@gmail.com>
+Date: Fri, 13 Dec 2019 11:30:54 +0900
+Subject: usbip: Fix receive error in vhci-hcd when using scatter-gather
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Suwan Kim <suwan.kim027@gmail.com>
+
+commit d986294ee55d719562b20aabe15a39bf8f863415 upstream.
+
+When vhci uses SG and receives data whose size is smaller than SG
+buffer size, it tries to receive more data even if it acutally
+receives all the data from the server. If then, it erroneously adds
+error event and triggers connection shutdown.
+
+vhci-hcd should check if it received all the data even if there are
+more SG entries left. So, check if it receivces all the data from
+the server in for_each_sg() loop.
+
+Fixes: ea44d190764b ("usbip: Implement SG support to vhci-hcd and stub driver")
+Reported-by: Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com>
+Tested-by: Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com>
+Signed-off-by: Suwan Kim <suwan.kim027@gmail.com>
+Acked-by: Shuah Khan <skhan@linuxfoundation.org>
+Cc: stable <stable@vger.kernel.org>
+Link: https://lore.kernel.org/r/20191213023055.19933-2-suwan.kim027@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/usbip/usbip_common.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/drivers/usb/usbip/usbip_common.c
++++ b/drivers/usb/usbip/usbip_common.c
+@@ -727,6 +727,9 @@ int usbip_recv_xbuff(struct usbip_device
+
+ copy -= recv;
+ ret += recv;
++
++ if (!copy)
++ break;
+ }
+
+ if (ret != size)