]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.19-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 29 Dec 2019 14:53:30 +0000 (15:53 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 29 Dec 2019 14:53:30 +0000 (15:53 +0100)
added patches:
cpufreq-avoid-leaving-stale-irq-work-items-during-cpu-offline.patch
intel_th-pci-add-comet-lake-pch-v-support.patch
intel_th-pci-add-elkhart-lake-soc-support.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
usb-ehci-do-not-return-epipe-when-hub-is-disconnected.patch
usbip-fix-error-path-of-vhci_recv_ret_submit.patch
usbip-fix-receive-error-in-vhci-hcd-when-using-scatter-gather.patch

queue-4.19/cpufreq-avoid-leaving-stale-irq-work-items-during-cpu-offline.patch [new file with mode: 0644]
queue-4.19/intel_th-pci-add-comet-lake-pch-v-support.patch [new file with mode: 0644]
queue-4.19/intel_th-pci-add-elkhart-lake-soc-support.patch [new file with mode: 0644]
queue-4.19/platform-x86-hp-wmi-make-buffer-for-hpwmi_feature2_query-128-bytes.patch [new file with mode: 0644]
queue-4.19/series
queue-4.19/staging-comedi-gsc_hpdi-check-dma_alloc_coherent-return-value.patch [new file with mode: 0644]
queue-4.19/usb-ehci-do-not-return-epipe-when-hub-is-disconnected.patch [new file with mode: 0644]
queue-4.19/usbip-fix-error-path-of-vhci_recv_ret_submit.patch [new file with mode: 0644]
queue-4.19/usbip-fix-receive-error-in-vhci-hcd-when-using-scatter-gather.patch [new file with mode: 0644]

diff --git a/queue-4.19/cpufreq-avoid-leaving-stale-irq-work-items-during-cpu-offline.patch b/queue-4.19/cpufreq-avoid-leaving-stale-irq-work-items-during-cpu-offline.patch
new file mode 100644 (file)
index 0000000..fb77ea8
--- /dev/null
@@ -0,0 +1,169 @@
+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
+@@ -563,17 +563,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);
+ #endif /* CONFIG_CPU_FREQ */
+ #endif /* _LINUX_SCHED_CPUFREQ_H */
+--- a/kernel/sched/cpufreq.c
++++ b/kernel/sched/cpufreq.c
+@@ -8,6 +8,8 @@
+  * it under the terms of the GNU General Public License version 2 as
+  * published by the Free Software Foundation.
+  */
++#include <linux/cpufreq.h>
++
+ #include "sched.h"
+ DEFINE_PER_CPU(struct update_util_data *, cpufreq_update_util_data);
+@@ -60,3 +62,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
+@@ -83,12 +83,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)) {
diff --git a/queue-4.19/intel_th-pci-add-comet-lake-pch-v-support.patch b/queue-4.19/intel_th-pci-add-comet-lake-pch-v-support.patch
new file mode 100644 (file)
index 0000000..2e43ef9
--- /dev/null
@@ -0,0 +1,35 @@
+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
+@@ -181,6 +181,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,
diff --git a/queue-4.19/intel_th-pci-add-elkhart-lake-soc-support.patch b/queue-4.19/intel_th-pci-add-elkhart-lake-soc-support.patch
new file mode 100644 (file)
index 0000000..63f101b
--- /dev/null
@@ -0,0 +1,35 @@
+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
+@@ -210,6 +210,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 },
+ };
diff --git a/queue-4.19/platform-x86-hp-wmi-make-buffer-for-hpwmi_feature2_query-128-bytes.patch b/queue-4.19/platform-x86-hp-wmi-make-buffer-for-hpwmi_feature2_query-128-bytes.patch
new file mode 100644 (file)
index 0000000..6885b64
--- /dev/null
@@ -0,0 +1,42 @@
+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
+@@ -313,7 +313,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)
index f388d083f67a306b3a7b9c78187f406109dba5b5..51e08795d3e157ea537b4faa430f64dc926352b5 100644 (file)
@@ -197,3 +197,11 @@ usb-xhci-fix-build-warning-seen-with-config_pm-n.patch
 drm-amdgpu-fix-uninitialized-variable-pasid_mapping_.patch
 s390-ftrace-fix-endless-recursion-in-function_graph-.patch
 btrfs-return-error-pointer-from-alloc_test_extent_bu.patch
+usbip-fix-receive-error-in-vhci-hcd-when-using-scatter-gather.patch
+usbip-fix-error-path-of-vhci_recv_ret_submit.patch
+cpufreq-avoid-leaving-stale-irq-work-items-during-cpu-offline.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
+platform-x86-hp-wmi-make-buffer-for-hpwmi_feature2_query-128-bytes.patch
+staging-comedi-gsc_hpdi-check-dma_alloc_coherent-return-value.patch
diff --git a/queue-4.19/staging-comedi-gsc_hpdi-check-dma_alloc_coherent-return-value.patch b/queue-4.19/staging-comedi-gsc_hpdi-check-dma_alloc_coherent-return-value.patch
new file mode 100644 (file)
index 0000000..50aacfe
--- /dev/null
@@ -0,0 +1,54 @@
+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");
diff --git a/queue-4.19/usb-ehci-do-not-return-epipe-when-hub-is-disconnected.patch b/queue-4.19/usb-ehci-do-not-return-epipe-when-hub-is-disconnected.patch
new file mode 100644 (file)
index 0000000..ffcdd2b
--- /dev/null
@@ -0,0 +1,85 @@
+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;
diff --git a/queue-4.19/usbip-fix-error-path-of-vhci_recv_ret_submit.patch b/queue-4.19/usbip-fix-error-path-of-vhci_recv_ret_submit.patch
new file mode 100644 (file)
index 0000000..57f99c8
--- /dev/null
@@ -0,0 +1,70 @@
+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);
diff --git a/queue-4.19/usbip-fix-receive-error-in-vhci-hcd-when-using-scatter-gather.patch b/queue-4.19/usbip-fix-receive-error-in-vhci-hcd-when-using-scatter-gather.patch
new file mode 100644 (file)
index 0000000..947e9f2
--- /dev/null
@@ -0,0 +1,46 @@
+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)