]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.8-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 31 Aug 2020 12:31:56 +0000 (14:31 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 31 Aug 2020 12:31:56 +0000 (14:31 +0200)
added patches:
usb-also-match-device-drivers-using-the-match-vfunc.patch
usb-cdc-acm-rework-notification_buffer-resizing.patch
usb-dwc3-gadget-don-t-setup-more-than-requested.patch
usb-dwc3-gadget-fix-handling-zlp.patch
usb-dwc3-gadget-handle-zlp-for-sg-requests.patch
usb-fix-device-driver-race.patch
usb-gadget-f_ncm-add-bounds-checks-to-ncm_unwrap_ntb.patch
usb-gadget-u_f-add-overflow-checks-to-vla-macros.patch
usb-gadget-u_f-unbreak-offset-calculation-in-vlas.patch
usb-host-ohci-exynos-fix-error-handling-in-exynos_ohci_probe.patch
usb-ignore-uas-for-jmicron-jms567-ata-atapi-bridge.patch
usb-quirks-add-no-lpm-quirk-for-another-raydium-touchscreen.patch
usb-quirks-ignore-duplicate-endpoint-on-sound-devices-mixpre-d.patch
usb-storage-add-unusual_uas-entry-for-sony-psz-drives.patch
usb-typec-tcpm-fix-fix-source-hard-reset-response-for-tda-2.3.1.1-and-tda-2.3.1.2-failures.patch
usb-typec-ucsi-fix-2-unlocked-ucsi_run_command-calls.patch
usb-typec-ucsi-fix-ab-ba-lock-inversion.patch
usb-typec-ucsi-hold-con-lock-for-the-entire-duration-of-ucsi_register_port.patch
usb-typec-ucsi-rework-ppm_lock-handling.patch
usb-uas-add-quirk-for-pny-pro-elite.patch
usb-yurex-fix-bad-gfp-argument.patch

22 files changed:
queue-5.8/series
queue-5.8/usb-also-match-device-drivers-using-the-match-vfunc.patch [new file with mode: 0644]
queue-5.8/usb-cdc-acm-rework-notification_buffer-resizing.patch [new file with mode: 0644]
queue-5.8/usb-dwc3-gadget-don-t-setup-more-than-requested.patch [new file with mode: 0644]
queue-5.8/usb-dwc3-gadget-fix-handling-zlp.patch [new file with mode: 0644]
queue-5.8/usb-dwc3-gadget-handle-zlp-for-sg-requests.patch [new file with mode: 0644]
queue-5.8/usb-fix-device-driver-race.patch [new file with mode: 0644]
queue-5.8/usb-gadget-f_ncm-add-bounds-checks-to-ncm_unwrap_ntb.patch [new file with mode: 0644]
queue-5.8/usb-gadget-u_f-add-overflow-checks-to-vla-macros.patch [new file with mode: 0644]
queue-5.8/usb-gadget-u_f-unbreak-offset-calculation-in-vlas.patch [new file with mode: 0644]
queue-5.8/usb-host-ohci-exynos-fix-error-handling-in-exynos_ohci_probe.patch [new file with mode: 0644]
queue-5.8/usb-ignore-uas-for-jmicron-jms567-ata-atapi-bridge.patch [new file with mode: 0644]
queue-5.8/usb-quirks-add-no-lpm-quirk-for-another-raydium-touchscreen.patch [new file with mode: 0644]
queue-5.8/usb-quirks-ignore-duplicate-endpoint-on-sound-devices-mixpre-d.patch [new file with mode: 0644]
queue-5.8/usb-storage-add-unusual_uas-entry-for-sony-psz-drives.patch [new file with mode: 0644]
queue-5.8/usb-typec-tcpm-fix-fix-source-hard-reset-response-for-tda-2.3.1.1-and-tda-2.3.1.2-failures.patch [new file with mode: 0644]
queue-5.8/usb-typec-ucsi-fix-2-unlocked-ucsi_run_command-calls.patch [new file with mode: 0644]
queue-5.8/usb-typec-ucsi-fix-ab-ba-lock-inversion.patch [new file with mode: 0644]
queue-5.8/usb-typec-ucsi-hold-con-lock-for-the-entire-duration-of-ucsi_register_port.patch [new file with mode: 0644]
queue-5.8/usb-typec-ucsi-rework-ppm_lock-handling.patch [new file with mode: 0644]
queue-5.8/usb-uas-add-quirk-for-pny-pro-elite.patch [new file with mode: 0644]
queue-5.8/usb-yurex-fix-bad-gfp-argument.patch [new file with mode: 0644]

index 41a56284471b52e86dcb213812deb0ebebb36714..a0998eb8f045a306b67a1a981813602a53b990d3 100644 (file)
@@ -219,3 +219,24 @@ drm-amd-pm-correct-vega10-swctf-limit-setting.patch
 drm-amd-pm-correct-vega12-swctf-limit-setting.patch
 drm-amd-pm-correct-vega20-swctf-limit-setting.patch
 drm-amd-pm-correct-the-thermal-alert-temperature-limit-settings.patch
+usb-yurex-fix-bad-gfp-argument.patch
+usb-uas-add-quirk-for-pny-pro-elite.patch
+usb-quirks-add-no-lpm-quirk-for-another-raydium-touchscreen.patch
+usb-quirks-ignore-duplicate-endpoint-on-sound-devices-mixpre-d.patch
+usb-ignore-uas-for-jmicron-jms567-ata-atapi-bridge.patch
+usb-host-ohci-exynos-fix-error-handling-in-exynos_ohci_probe.patch
+usb-gadget-u_f-add-overflow-checks-to-vla-macros.patch
+usb-gadget-f_ncm-add-bounds-checks-to-ncm_unwrap_ntb.patch
+usb-gadget-u_f-unbreak-offset-calculation-in-vlas.patch
+usb-dwc3-gadget-don-t-setup-more-than-requested.patch
+usb-dwc3-gadget-fix-handling-zlp.patch
+usb-dwc3-gadget-handle-zlp-for-sg-requests.patch
+usb-cdc-acm-rework-notification_buffer-resizing.patch
+usb-storage-add-unusual_uas-entry-for-sony-psz-drives.patch
+usb-also-match-device-drivers-using-the-match-vfunc.patch
+usb-fix-device-driver-race.patch
+usb-typec-ucsi-fix-ab-ba-lock-inversion.patch
+usb-typec-ucsi-fix-2-unlocked-ucsi_run_command-calls.patch
+usb-typec-ucsi-rework-ppm_lock-handling.patch
+usb-typec-ucsi-hold-con-lock-for-the-entire-duration-of-ucsi_register_port.patch
+usb-typec-tcpm-fix-fix-source-hard-reset-response-for-tda-2.3.1.1-and-tda-2.3.1.2-failures.patch
diff --git a/queue-5.8/usb-also-match-device-drivers-using-the-match-vfunc.patch b/queue-5.8/usb-also-match-device-drivers-using-the-match-vfunc.patch
new file mode 100644 (file)
index 0000000..abc7ac2
--- /dev/null
@@ -0,0 +1,37 @@
+From adb6e6ac20eedcf1dce19dc75b224e63c0828ea1 Mon Sep 17 00:00:00 2001
+From: Bastien Nocera <hadess@hadess.net>
+Date: Tue, 18 Aug 2020 13:04:43 +0200
+Subject: USB: Also match device drivers using the ->match vfunc
+
+From: Bastien Nocera <hadess@hadess.net>
+
+commit adb6e6ac20eedcf1dce19dc75b224e63c0828ea1 upstream.
+
+We only ever used the ID table matching before, but we should also support
+open-coded match functions.
+
+Fixes: 88b7381a939de ("USB: Select better matching USB drivers when available")
+Signed-off-by: Bastien Nocera <hadess@hadess.net>
+Cc: stable <stable@vger.kernel.org>
+Acked-by: Alan Stern <stern@rowland.harvard.edu>
+Link: https://lore.kernel.org/r/20200818110445.509668-1-hadess@hadess.net
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/core/generic.c |    5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+--- a/drivers/usb/core/generic.c
++++ b/drivers/usb/core/generic.c
+@@ -207,8 +207,9 @@ static int __check_usb_generic(struct de
+               return 0;
+       if (!udrv->id_table)
+               return 0;
+-
+-      return usb_device_match_id(udev, udrv->id_table) != NULL;
++      if (usb_device_match_id(udev, udrv->id_table) != NULL)
++              return 1;
++      return (udrv->match && udrv->match(udev));
+ }
+ static bool usb_generic_driver_match(struct usb_device *udev)
diff --git a/queue-5.8/usb-cdc-acm-rework-notification_buffer-resizing.patch b/queue-5.8/usb-cdc-acm-rework-notification_buffer-resizing.patch
new file mode 100644 (file)
index 0000000..d4a40ef
--- /dev/null
@@ -0,0 +1,99 @@
+From f4b9d8a582f738c24ebeabce5cc15f4b8159d74e Mon Sep 17 00:00:00 2001
+From: Tom Rix <trix@redhat.com>
+Date: Sat, 1 Aug 2020 08:21:54 -0700
+Subject: USB: cdc-acm: rework notification_buffer resizing
+
+From: Tom Rix <trix@redhat.com>
+
+commit f4b9d8a582f738c24ebeabce5cc15f4b8159d74e upstream.
+
+Clang static analysis reports this error
+
+cdc-acm.c:409:3: warning: Use of memory after it is freed
+        acm_process_notification(acm, (unsigned char *)dr);
+
+There are three problems, the first one is that dr is not reset
+
+The variable dr is set with
+
+if (acm->nb_index)
+       dr = (struct usb_cdc_notification *)acm->notification_buffer;
+
+But if the notification_buffer is too small it is resized with
+
+               if (acm->nb_size) {
+                       kfree(acm->notification_buffer);
+                       acm->nb_size = 0;
+               }
+               alloc_size = roundup_pow_of_two(expected_size);
+               /*
+                * kmalloc ensures a valid notification_buffer after a
+                * use of kfree in case the previous allocation was too
+                * small. Final freeing is done on disconnect.
+                */
+               acm->notification_buffer =
+                       kmalloc(alloc_size, GFP_ATOMIC);
+
+dr should point to the new acm->notification_buffer.
+
+The second problem is any data in the notification_buffer is lost
+when the pointer is freed.  In the normal case, the current data
+is accumulated in the notification_buffer here.
+
+       memcpy(&acm->notification_buffer[acm->nb_index],
+              urb->transfer_buffer, copy_size);
+
+When a resize happens, anything before
+notification_buffer[acm->nb_index] is garbage.
+
+The third problem is the acm->nb_index is not reset on a
+resizing buffer error.
+
+So switch resizing to using krealloc and reassign dr and
+reset nb_index.
+
+Fixes: ea2583529cd1 ("cdc-acm: reassemble fragmented notifications")
+Signed-off-by: Tom Rix <trix@redhat.com>
+Cc: stable <stable@vger.kernel.org>
+Acked-by: Oliver Neukum <oneukum@suse.com>
+Link: https://lore.kernel.org/r/20200801152154.20683-1-trix@redhat.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/class/cdc-acm.c |   22 ++++++++++------------
+ 1 file changed, 10 insertions(+), 12 deletions(-)
+
+--- a/drivers/usb/class/cdc-acm.c
++++ b/drivers/usb/class/cdc-acm.c
+@@ -378,21 +378,19 @@ static void acm_ctrl_irq(struct urb *urb
+       if (current_size < expected_size) {
+               /* notification is transmitted fragmented, reassemble */
+               if (acm->nb_size < expected_size) {
+-                      if (acm->nb_size) {
+-                              kfree(acm->notification_buffer);
+-                              acm->nb_size = 0;
+-                      }
++                      u8 *new_buffer;
+                       alloc_size = roundup_pow_of_two(expected_size);
+-                      /*
+-                       * kmalloc ensures a valid notification_buffer after a
+-                       * use of kfree in case the previous allocation was too
+-                       * small. Final freeing is done on disconnect.
+-                       */
+-                      acm->notification_buffer =
+-                              kmalloc(alloc_size, GFP_ATOMIC);
+-                      if (!acm->notification_buffer)
++                      /* Final freeing is done on disconnect. */
++                      new_buffer = krealloc(acm->notification_buffer,
++                                            alloc_size, GFP_ATOMIC);
++                      if (!new_buffer) {
++                              acm->nb_index = 0;
+                               goto exit;
++                      }
++
++                      acm->notification_buffer = new_buffer;
+                       acm->nb_size = alloc_size;
++                      dr = (struct usb_cdc_notification *)acm->notification_buffer;
+               }
+               copy_size = min(current_size,
diff --git a/queue-5.8/usb-dwc3-gadget-don-t-setup-more-than-requested.patch b/queue-5.8/usb-dwc3-gadget-don-t-setup-more-than-requested.patch
new file mode 100644 (file)
index 0000000..3a36028
--- /dev/null
@@ -0,0 +1,171 @@
+From 5d187c0454ef4c5e046a81af36882d4d515922ec Mon Sep 17 00:00:00 2001
+From: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
+Date: Thu, 6 Aug 2020 19:46:23 -0700
+Subject: usb: dwc3: gadget: Don't setup more than requested
+
+From: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
+
+commit 5d187c0454ef4c5e046a81af36882d4d515922ec upstream.
+
+The SG list may be set up with entry size more than the requested
+length. Check the usb_request->length and make sure that we don't setup
+the TRBs to send/receive more than requested. This case may occur when
+the SG entry is allocated up to a certain minimum size, but the request
+length is less than that. It can also occur when the request is reused
+for a different request length.
+
+Cc: <stable@vger.kernel.org> # v4.18+
+Fixes: a31e63b608ff ("usb: dwc3: gadget: Correct handling of scattergather lists")
+Signed-off-by: Thinh Nguyen <thinhn@synopsys.com>
+Signed-off-by: Felipe Balbi <balbi@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/dwc3/gadget.c |   51 +++++++++++++++++++++++++++++++---------------
+ 1 file changed, 35 insertions(+), 16 deletions(-)
+
+--- a/drivers/usb/dwc3/gadget.c
++++ b/drivers/usb/dwc3/gadget.c
+@@ -1054,27 +1054,25 @@ static void __dwc3_prepare_one_trb(struc
+  * dwc3_prepare_one_trb - setup one TRB from one request
+  * @dep: endpoint for which this request is prepared
+  * @req: dwc3_request pointer
++ * @trb_length: buffer size of the TRB
+  * @chain: should this TRB be chained to the next?
+  * @node: only for isochronous endpoints. First TRB needs different type.
+  */
+ static void dwc3_prepare_one_trb(struct dwc3_ep *dep,
+-              struct dwc3_request *req, unsigned chain, unsigned node)
++              struct dwc3_request *req, unsigned int trb_length,
++              unsigned chain, unsigned node)
+ {
+       struct dwc3_trb         *trb;
+-      unsigned int            length;
+       dma_addr_t              dma;
+       unsigned                stream_id = req->request.stream_id;
+       unsigned                short_not_ok = req->request.short_not_ok;
+       unsigned                no_interrupt = req->request.no_interrupt;
+       unsigned                is_last = req->request.is_last;
+-      if (req->request.num_sgs > 0) {
+-              length = sg_dma_len(req->start_sg);
++      if (req->request.num_sgs > 0)
+               dma = sg_dma_address(req->start_sg);
+-      } else {
+-              length = req->request.length;
++      else
+               dma = req->request.dma;
+-      }
+       trb = &dep->trb_pool[dep->trb_enqueue];
+@@ -1086,7 +1084,7 @@ static void dwc3_prepare_one_trb(struct
+       req->num_trbs++;
+-      __dwc3_prepare_one_trb(dep, trb, dma, length, chain, node,
++      __dwc3_prepare_one_trb(dep, trb, dma, trb_length, chain, node,
+                       stream_id, short_not_ok, no_interrupt, is_last);
+ }
+@@ -1096,16 +1094,27 @@ static void dwc3_prepare_one_trb_sg(stru
+       struct scatterlist *sg = req->start_sg;
+       struct scatterlist *s;
+       int             i;
+-
++      unsigned int length = req->request.length;
+       unsigned int remaining = req->request.num_mapped_sgs
+               - req->num_queued_sgs;
++      /*
++       * If we resume preparing the request, then get the remaining length of
++       * the request and resume where we left off.
++       */
++      for_each_sg(req->request.sg, s, req->num_queued_sgs, i)
++              length -= sg_dma_len(s);
++
+       for_each_sg(sg, s, remaining, i) {
+-              unsigned int length = req->request.length;
+               unsigned int maxp = usb_endpoint_maxp(dep->endpoint.desc);
+               unsigned int rem = length % maxp;
++              unsigned int trb_length;
+               unsigned chain = true;
++              trb_length = min_t(unsigned int, length, sg_dma_len(s));
++
++              length -= trb_length;
++
+               /*
+                * IOMMU driver is coalescing the list of sgs which shares a
+                * page boundary into one and giving it to USB driver. With
+@@ -1113,7 +1122,7 @@ static void dwc3_prepare_one_trb_sg(stru
+                * sgs passed. So mark the chain bit to false if it isthe last
+                * mapped sg.
+                */
+-              if (i == remaining - 1)
++              if ((i == remaining - 1) || !length)
+                       chain = false;
+               if (rem && usb_endpoint_dir_out(dep->endpoint.desc) && !chain) {
+@@ -1123,7 +1132,7 @@ static void dwc3_prepare_one_trb_sg(stru
+                       req->needs_extra_trb = true;
+                       /* prepare normal TRB */
+-                      dwc3_prepare_one_trb(dep, req, true, i);
++                      dwc3_prepare_one_trb(dep, req, trb_length, true, i);
+                       /* Now prepare one extra TRB to align transfer size */
+                       trb = &dep->trb_pool[dep->trb_enqueue];
+@@ -1135,7 +1144,7 @@ static void dwc3_prepare_one_trb_sg(stru
+                                       req->request.no_interrupt,
+                                       req->request.is_last);
+               } else {
+-                      dwc3_prepare_one_trb(dep, req, chain, i);
++                      dwc3_prepare_one_trb(dep, req, trb_length, chain, i);
+               }
+               /*
+@@ -1150,6 +1159,16 @@ static void dwc3_prepare_one_trb_sg(stru
+               req->num_queued_sgs++;
++              /*
++               * The number of pending SG entries may not correspond to the
++               * number of mapped SG entries. If all the data are queued, then
++               * don't include unused SG entries.
++               */
++              if (length == 0) {
++                      req->num_pending_sgs -= req->request.num_mapped_sgs - req->num_queued_sgs;
++                      break;
++              }
++
+               if (!dwc3_calc_trbs_left(dep))
+                       break;
+       }
+@@ -1169,7 +1188,7 @@ static void dwc3_prepare_one_trb_linear(
+               req->needs_extra_trb = true;
+               /* prepare normal TRB */
+-              dwc3_prepare_one_trb(dep, req, true, 0);
++              dwc3_prepare_one_trb(dep, req, length, true, 0);
+               /* Now prepare one extra TRB to align transfer size */
+               trb = &dep->trb_pool[dep->trb_enqueue];
+@@ -1187,7 +1206,7 @@ static void dwc3_prepare_one_trb_linear(
+               req->needs_extra_trb = true;
+               /* prepare normal TRB */
+-              dwc3_prepare_one_trb(dep, req, true, 0);
++              dwc3_prepare_one_trb(dep, req, length, true, 0);
+               /* Now prepare one extra TRB to handle ZLP */
+               trb = &dep->trb_pool[dep->trb_enqueue];
+@@ -1198,7 +1217,7 @@ static void dwc3_prepare_one_trb_linear(
+                               req->request.no_interrupt,
+                               req->request.is_last);
+       } else {
+-              dwc3_prepare_one_trb(dep, req, false, 0);
++              dwc3_prepare_one_trb(dep, req, length, false, 0);
+       }
+ }
diff --git a/queue-5.8/usb-dwc3-gadget-fix-handling-zlp.patch b/queue-5.8/usb-dwc3-gadget-fix-handling-zlp.patch
new file mode 100644 (file)
index 0000000..d0731a6
--- /dev/null
@@ -0,0 +1,81 @@
+From d2ee3ff79e6a3d4105e684021017d100524dc560 Mon Sep 17 00:00:00 2001
+From: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
+Date: Thu, 6 Aug 2020 19:46:29 -0700
+Subject: usb: dwc3: gadget: Fix handling ZLP
+
+From: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
+
+commit d2ee3ff79e6a3d4105e684021017d100524dc560 upstream.
+
+The usb_request->zero doesn't apply for isoc. Also, if we prepare a
+0-length (ZLP) TRB for the OUT direction, we need to prepare an extra
+TRB to pad up to the MPS alignment. Use the same bounce buffer for the
+ZLP TRB and the extra pad TRB.
+
+Cc: <stable@vger.kernel.org> # v4.5+
+Fixes: d6e5a549cc4d ("usb: dwc3: simplify ZLP handling")
+Fixes: 04c03d10e507 ("usb: dwc3: gadget: handle request->zero")
+Signed-off-by: Thinh Nguyen <thinhn@synopsys.com>
+Signed-off-by: Felipe Balbi <balbi@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/dwc3/gadget.c |   25 +++++++++++++++++++++++--
+ 1 file changed, 23 insertions(+), 2 deletions(-)
+
+--- a/drivers/usb/dwc3/gadget.c
++++ b/drivers/usb/dwc3/gadget.c
+@@ -1199,6 +1199,7 @@ static void dwc3_prepare_one_trb_linear(
+                               req->request.no_interrupt,
+                               req->request.is_last);
+       } else if (req->request.zero && req->request.length &&
++                 !usb_endpoint_xfer_isoc(dep->endpoint.desc) &&
+                  (IS_ALIGNED(req->request.length, maxp))) {
+               struct dwc3     *dwc = dep->dwc;
+               struct dwc3_trb *trb;
+@@ -1208,14 +1209,25 @@ static void dwc3_prepare_one_trb_linear(
+               /* prepare normal TRB */
+               dwc3_prepare_one_trb(dep, req, length, true, 0);
+-              /* Now prepare one extra TRB to handle ZLP */
++              /* Prepare one extra TRB to handle ZLP */
+               trb = &dep->trb_pool[dep->trb_enqueue];
+               req->num_trbs++;
+               __dwc3_prepare_one_trb(dep, trb, dwc->bounce_addr, 0,
+-                              false, 1, req->request.stream_id,
++                              !req->direction, 1, req->request.stream_id,
+                               req->request.short_not_ok,
+                               req->request.no_interrupt,
+                               req->request.is_last);
++
++              /* Prepare one more TRB to handle MPS alignment for OUT */
++              if (!req->direction) {
++                      trb = &dep->trb_pool[dep->trb_enqueue];
++                      req->num_trbs++;
++                      __dwc3_prepare_one_trb(dep, trb, dwc->bounce_addr, maxp,
++                                             false, 1, req->request.stream_id,
++                                             req->request.short_not_ok,
++                                             req->request.no_interrupt,
++                                             req->request.is_last);
++              }
+       } else {
+               dwc3_prepare_one_trb(dep, req, length, false, 0);
+       }
+@@ -2668,8 +2680,17 @@ static int dwc3_gadget_ep_cleanup_comple
+                               status);
+       if (req->needs_extra_trb) {
++              unsigned int maxp = usb_endpoint_maxp(dep->endpoint.desc);
++
+               ret = dwc3_gadget_ep_reclaim_trb_linear(dep, req, event,
+                               status);
++
++              /* Reclaim MPS padding TRB for ZLP */
++              if (!req->direction && req->request.zero && req->request.length &&
++                  !usb_endpoint_xfer_isoc(dep->endpoint.desc) &&
++                  (IS_ALIGNED(req->request.length, maxp)))
++                      ret = dwc3_gadget_ep_reclaim_trb_linear(dep, req, event, status);
++
+               req->needs_extra_trb = false;
+       }
diff --git a/queue-5.8/usb-dwc3-gadget-handle-zlp-for-sg-requests.patch b/queue-5.8/usb-dwc3-gadget-handle-zlp-for-sg-requests.patch
new file mode 100644 (file)
index 0000000..1a36235
--- /dev/null
@@ -0,0 +1,62 @@
+From bc9a2e226ea95e1699f7590845554de095308b75 Mon Sep 17 00:00:00 2001
+From: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
+Date: Thu, 6 Aug 2020 19:46:35 -0700
+Subject: usb: dwc3: gadget: Handle ZLP for sg requests
+
+From: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
+
+commit bc9a2e226ea95e1699f7590845554de095308b75 upstream.
+
+Currently dwc3 doesn't handle usb_request->zero for SG requests. This
+change checks and prepares extra TRBs for the ZLP for SG requests.
+
+Cc: <stable@vger.kernel.org> # v4.5+
+Fixes: 04c03d10e507 ("usb: dwc3: gadget: handle request->zero")
+Signed-off-by: Thinh Nguyen <thinhn@synopsys.com>
+Signed-off-by: Felipe Balbi <balbi@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/dwc3/gadget.c |   31 +++++++++++++++++++++++++++++++
+ 1 file changed, 31 insertions(+)
+
+--- a/drivers/usb/dwc3/gadget.c
++++ b/drivers/usb/dwc3/gadget.c
+@@ -1143,6 +1143,37 @@ static void dwc3_prepare_one_trb_sg(stru
+                                       req->request.short_not_ok,
+                                       req->request.no_interrupt,
+                                       req->request.is_last);
++              } else if (req->request.zero && req->request.length &&
++                         !usb_endpoint_xfer_isoc(dep->endpoint.desc) &&
++                         !rem && !chain) {
++                      struct dwc3     *dwc = dep->dwc;
++                      struct dwc3_trb *trb;
++
++                      req->needs_extra_trb = true;
++
++                      /* Prepare normal TRB */
++                      dwc3_prepare_one_trb(dep, req, trb_length, true, i);
++
++                      /* Prepare one extra TRB to handle ZLP */
++                      trb = &dep->trb_pool[dep->trb_enqueue];
++                      req->num_trbs++;
++                      __dwc3_prepare_one_trb(dep, trb, dwc->bounce_addr, 0,
++                                             !req->direction, 1,
++                                             req->request.stream_id,
++                                             req->request.short_not_ok,
++                                             req->request.no_interrupt,
++                                             req->request.is_last);
++
++                      /* Prepare one more TRB to handle MPS alignment */
++                      if (!req->direction) {
++                              trb = &dep->trb_pool[dep->trb_enqueue];
++                              req->num_trbs++;
++                              __dwc3_prepare_one_trb(dep, trb, dwc->bounce_addr, maxp,
++                                                     false, 1, req->request.stream_id,
++                                                     req->request.short_not_ok,
++                                                     req->request.no_interrupt,
++                                                     req->request.is_last);
++                      }
+               } else {
+                       dwc3_prepare_one_trb(dep, req, trb_length, chain, i);
+               }
diff --git a/queue-5.8/usb-fix-device-driver-race.patch b/queue-5.8/usb-fix-device-driver-race.patch
new file mode 100644 (file)
index 0000000..1fd0491
--- /dev/null
@@ -0,0 +1,91 @@
+From d5643d2249b279077427b2c2b2ffae9b70c95b0b Mon Sep 17 00:00:00 2001
+From: Bastien Nocera <hadess@hadess.net>
+Date: Tue, 18 Aug 2020 13:04:45 +0200
+Subject: USB: Fix device driver race
+
+From: Bastien Nocera <hadess@hadess.net>
+
+commit d5643d2249b279077427b2c2b2ffae9b70c95b0b upstream.
+
+When a new device with a specialised device driver is plugged in, the
+new driver will be modprobe()'d but the driver core will attach the
+"generic" driver to the device.
+
+After that, nothing will trigger a reprobe when the modprobe()'d device
+driver has finished initialising, as the device has the "generic"
+driver attached to it.
+
+Trigger a reprobe ourselves when new specialised drivers get registered.
+
+Fixes: 88b7381a939d ("USB: Select better matching USB drivers when available")
+Signed-off-by: Bastien Nocera <hadess@hadess.net>
+Cc: stable <stable@vger.kernel.org>
+Acked-by: Alan Stern <stern@rowland.harvard.edu>
+Link: https://lore.kernel.org/r/20200818110445.509668-3-hadess@hadess.net
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/core/driver.c |   40 ++++++++++++++++++++++++++++++++++++++--
+ 1 file changed, 38 insertions(+), 2 deletions(-)
+
+--- a/drivers/usb/core/driver.c
++++ b/drivers/usb/core/driver.c
+@@ -905,6 +905,35 @@ static int usb_uevent(struct device *dev
+       return 0;
+ }
++static bool is_dev_usb_generic_driver(struct device *dev)
++{
++      struct usb_device_driver *udd = dev->driver ?
++              to_usb_device_driver(dev->driver) : NULL;
++
++      return udd == &usb_generic_driver;
++}
++
++static int __usb_bus_reprobe_drivers(struct device *dev, void *data)
++{
++      struct usb_device_driver *new_udriver = data;
++      struct usb_device *udev;
++      int ret;
++
++      if (!is_dev_usb_generic_driver(dev))
++              return 0;
++
++      udev = to_usb_device(dev);
++      if (usb_device_match_id(udev, new_udriver->id_table) == NULL &&
++          (!new_udriver->match || new_udriver->match(udev) != 0))
++              return 0;
++
++      ret = device_reprobe(dev);
++      if (ret && ret != -EPROBE_DEFER)
++              dev_err(dev, "Failed to reprobe device (error %d)\n", ret);
++
++      return 0;
++}
++
+ /**
+  * usb_register_device_driver - register a USB device (not interface) driver
+  * @new_udriver: USB operations for the device driver
+@@ -934,13 +963,20 @@ int usb_register_device_driver(struct us
+       retval = driver_register(&new_udriver->drvwrap.driver);
+-      if (!retval)
++      if (!retval) {
+               pr_info("%s: registered new device driver %s\n",
+                       usbcore_name, new_udriver->name);
+-      else
++              /*
++               * Check whether any device could be better served with
++               * this new driver
++               */
++              bus_for_each_dev(&usb_bus_type, NULL, new_udriver,
++                               __usb_bus_reprobe_drivers);
++      } else {
+               printk(KERN_ERR "%s: error %d registering device "
+                       "       driver %s\n",
+                       usbcore_name, retval, new_udriver->name);
++      }
+       return retval;
+ }
diff --git a/queue-5.8/usb-gadget-f_ncm-add-bounds-checks-to-ncm_unwrap_ntb.patch b/queue-5.8/usb-gadget-f_ncm-add-bounds-checks-to-ncm_unwrap_ntb.patch
new file mode 100644 (file)
index 0000000..3a4a481
--- /dev/null
@@ -0,0 +1,178 @@
+From 2b74b0a04d3e9f9f08ff026e5663dce88ff94e52 Mon Sep 17 00:00:00 2001
+From: Brooke Basile <brookebasile@gmail.com>
+Date: Tue, 25 Aug 2020 09:07:27 -0400
+Subject: USB: gadget: f_ncm: add bounds checks to ncm_unwrap_ntb()
+
+From: Brooke Basile <brookebasile@gmail.com>
+
+commit 2b74b0a04d3e9f9f08ff026e5663dce88ff94e52 upstream.
+
+Some values extracted by ncm_unwrap_ntb() could possibly lead to several
+different out of bounds reads of memory.  Specifically the values passed
+to netdev_alloc_skb_ip_align() need to be checked so that memory is not
+overflowed.
+
+Resolve this by applying bounds checking to a number of different
+indexes and lengths of the structure parsing logic.
+
+Reported-by: Ilja Van Sprundel <ivansprundel@ioactive.com>
+Signed-off-by: Brooke Basile <brookebasile@gmail.com>
+Acked-by: Felipe Balbi <balbi@kernel.org>
+Cc: stable <stable@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/gadget/function/f_ncm.c |   81 ++++++++++++++++++++++++++++++------
+ 1 file changed, 69 insertions(+), 12 deletions(-)
+
+--- a/drivers/usb/gadget/function/f_ncm.c
++++ b/drivers/usb/gadget/function/f_ncm.c
+@@ -1181,12 +1181,15 @@ static int ncm_unwrap_ntb(struct gether
+       int             ndp_index;
+       unsigned        dg_len, dg_len2;
+       unsigned        ndp_len;
++      unsigned        block_len;
+       struct sk_buff  *skb2;
+       int             ret = -EINVAL;
+-      unsigned        max_size = le32_to_cpu(ntb_parameters.dwNtbOutMaxSize);
++      unsigned        ntb_max = le32_to_cpu(ntb_parameters.dwNtbOutMaxSize);
++      unsigned        frame_max = le16_to_cpu(ecm_desc.wMaxSegmentSize);
+       const struct ndp_parser_opts *opts = ncm->parser_opts;
+       unsigned        crc_len = ncm->is_crc ? sizeof(uint32_t) : 0;
+       int             dgram_counter;
++      bool            ndp_after_header;
+       /* dwSignature */
+       if (get_unaligned_le32(tmp) != opts->nth_sign) {
+@@ -1205,25 +1208,37 @@ static int ncm_unwrap_ntb(struct gether
+       }
+       tmp++; /* skip wSequence */
++      block_len = get_ncm(&tmp, opts->block_length);
+       /* (d)wBlockLength */
+-      if (get_ncm(&tmp, opts->block_length) > max_size) {
++      if (block_len > ntb_max) {
+               INFO(port->func.config->cdev, "OUT size exceeded\n");
+               goto err;
+       }
+       ndp_index = get_ncm(&tmp, opts->ndp_index);
++      ndp_after_header = false;
+       /* Run through all the NDP's in the NTB */
+       do {
+-              /* NCM 3.2 */
+-              if (((ndp_index % 4) != 0) &&
+-                              (ndp_index < opts->nth_size)) {
++              /*
++               * NCM 3.2
++               * dwNdpIndex
++               */
++              if (((ndp_index % 4) != 0) ||
++                              (ndp_index < opts->nth_size) ||
++                              (ndp_index > (block_len -
++                                            opts->ndp_size))) {
+                       INFO(port->func.config->cdev, "Bad index: %#X\n",
+                            ndp_index);
+                       goto err;
+               }
++              if (ndp_index == opts->nth_size)
++                      ndp_after_header = true;
+-              /* walk through NDP */
++              /*
++               * walk through NDP
++               * dwSignature
++               */
+               tmp = (void *)(skb->data + ndp_index);
+               if (get_unaligned_le32(tmp) != ncm->ndp_sign) {
+                       INFO(port->func.config->cdev, "Wrong NDP SIGN\n");
+@@ -1234,14 +1249,15 @@ static int ncm_unwrap_ntb(struct gether
+               ndp_len = get_unaligned_le16(tmp++);
+               /*
+                * NCM 3.3.1
++               * wLength
+                * entry is 2 items
+                * item size is 16/32 bits, opts->dgram_item_len * 2 bytes
+                * minimal: struct usb_cdc_ncm_ndpX + normal entry + zero entry
+                * Each entry is a dgram index and a dgram length.
+                */
+               if ((ndp_len < opts->ndp_size
+-                              + 2 * 2 * (opts->dgram_item_len * 2))
+-                              || (ndp_len % opts->ndplen_align != 0)) {
++                              + 2 * 2 * (opts->dgram_item_len * 2)) ||
++                              (ndp_len % opts->ndplen_align != 0)) {
+                       INFO(port->func.config->cdev, "Bad NDP length: %#X\n",
+                            ndp_len);
+                       goto err;
+@@ -1258,8 +1274,21 @@ static int ncm_unwrap_ntb(struct gether
+               do {
+                       index = index2;
++                      /* wDatagramIndex[0] */
++                      if ((index < opts->nth_size) ||
++                                      (index > block_len - opts->dpe_size)) {
++                              INFO(port->func.config->cdev,
++                                   "Bad index: %#X\n", index);
++                              goto err;
++                      }
++
+                       dg_len = dg_len2;
+-                      if (dg_len < 14 + crc_len) { /* ethernet hdr + crc */
++                      /*
++                       * wDatagramLength[0]
++                       * ethernet hdr + crc or larger than max frame size
++                       */
++                      if ((dg_len < 14 + crc_len) ||
++                                      (dg_len > frame_max)) {
+                               INFO(port->func.config->cdev,
+                                    "Bad dgram length: %#X\n", dg_len);
+                               goto err;
+@@ -1283,6 +1312,37 @@ static int ncm_unwrap_ntb(struct gether
+                       index2 = get_ncm(&tmp, opts->dgram_item_len);
+                       dg_len2 = get_ncm(&tmp, opts->dgram_item_len);
++                      if (index2 == 0 || dg_len2 == 0)
++                              break;
++
++                      /* wDatagramIndex[1] */
++                      if (ndp_after_header) {
++                              if (index2 < opts->nth_size + opts->ndp_size) {
++                                      INFO(port->func.config->cdev,
++                                           "Bad index: %#X\n", index2);
++                                      goto err;
++                              }
++                      } else {
++                              if (index2 < opts->nth_size + opts->dpe_size) {
++                                      INFO(port->func.config->cdev,
++                                           "Bad index: %#X\n", index2);
++                                      goto err;
++                              }
++                      }
++                      if (index2 > block_len - opts->dpe_size) {
++                              INFO(port->func.config->cdev,
++                                   "Bad index: %#X\n", index2);
++                              goto err;
++                      }
++
++                      /* wDatagramLength[1] */
++                      if ((dg_len2 < 14 + crc_len) ||
++                                      (dg_len2 > frame_max)) {
++                              INFO(port->func.config->cdev,
++                                   "Bad dgram length: %#X\n", dg_len);
++                              goto err;
++                      }
++
+                       /*
+                        * Copy the data into a new skb.
+                        * This ensures the truesize is correct
+@@ -1299,9 +1359,6 @@ static int ncm_unwrap_ntb(struct gether
+                       ndp_len -= 2 * (opts->dgram_item_len * 2);
+                       dgram_counter++;
+-
+-                      if (index2 == 0 || dg_len2 == 0)
+-                              break;
+               } while (ndp_len > 2 * (opts->dgram_item_len * 2));
+       } while (ndp_index);
diff --git a/queue-5.8/usb-gadget-u_f-add-overflow-checks-to-vla-macros.patch b/queue-5.8/usb-gadget-u_f-add-overflow-checks-to-vla-macros.patch
new file mode 100644 (file)
index 0000000..66b2843
--- /dev/null
@@ -0,0 +1,85 @@
+From b1cd1b65afba95971fa457dfdb2c941c60d38c5b Mon Sep 17 00:00:00 2001
+From: Brooke Basile <brookebasile@gmail.com>
+Date: Tue, 25 Aug 2020 09:05:08 -0400
+Subject: USB: gadget: u_f: add overflow checks to VLA macros
+
+From: Brooke Basile <brookebasile@gmail.com>
+
+commit b1cd1b65afba95971fa457dfdb2c941c60d38c5b upstream.
+
+size can potentially hold an overflowed value if its assigned expression
+is left unchecked, leading to a smaller than needed allocation when
+vla_group_size() is used by callers to allocate memory.
+To fix this, add a test for saturation before declaring variables and an
+overflow check to (n) * sizeof(type).
+If the expression results in overflow, vla_group_size() will return SIZE_MAX.
+
+Reported-by: Ilja Van Sprundel <ivansprundel@ioactive.com>
+Suggested-by: Kees Cook <keescook@chromium.org>
+Signed-off-by: Brooke Basile <brookebasile@gmail.com>
+Acked-by: Felipe Balbi <balbi@kernel.org>
+Cc: stable <stable@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/gadget/u_f.h |   38 +++++++++++++++++++++++++++-----------
+ 1 file changed, 27 insertions(+), 11 deletions(-)
+
+--- a/drivers/usb/gadget/u_f.h
++++ b/drivers/usb/gadget/u_f.h
+@@ -14,6 +14,7 @@
+ #define __U_F_H__
+ #include <linux/usb/gadget.h>
++#include <linux/overflow.h>
+ /* Variable Length Array Macros **********************************************/
+ #define vla_group(groupname) size_t groupname##__next = 0
+@@ -21,21 +22,36 @@
+ #define vla_item(groupname, type, name, n) \
+       size_t groupname##_##name##__offset = ({                               \
+-              size_t align_mask = __alignof__(type) - 1;                     \
+-              size_t offset = (groupname##__next + align_mask) & ~align_mask;\
+-              size_t size = (n) * sizeof(type);                              \
+-              groupname##__next = offset + size;                             \
++              size_t offset = 0;                                             \
++              if (groupname##__next != SIZE_MAX) {                           \
++                      size_t align_mask = __alignof__(type) - 1;             \
++                      size_t offset = (groupname##__next + align_mask)       \
++                                       & ~align_mask;                        \
++                      size_t size = array_size(n, sizeof(type));             \
++                      if (check_add_overflow(offset, size,                   \
++                                             &groupname##__next)) {          \
++                              groupname##__next = SIZE_MAX;                  \
++                              offset = 0;                                    \
++                      }                                                      \
++              }                                                              \
+               offset;                                                        \
+       })
+ #define vla_item_with_sz(groupname, type, name, n) \
+-      size_t groupname##_##name##__sz = (n) * sizeof(type);                  \
+-      size_t groupname##_##name##__offset = ({                               \
+-              size_t align_mask = __alignof__(type) - 1;                     \
+-              size_t offset = (groupname##__next + align_mask) & ~align_mask;\
+-              size_t size = groupname##_##name##__sz;                        \
+-              groupname##__next = offset + size;                             \
+-              offset;                                                        \
++      size_t groupname##_##name##__sz = array_size(n, sizeof(type));          \
++      size_t groupname##_##name##__offset = ({                                \
++              size_t offset = 0;                                              \
++              if (groupname##__next != SIZE_MAX) {                            \
++                      size_t align_mask = __alignof__(type) - 1;              \
++                      size_t offset = (groupname##__next + align_mask)        \
++                                       & ~align_mask;                         \
++                      if (check_add_overflow(offset, groupname##_##name##__sz,\
++                                                      &groupname##__next)) {  \
++                              groupname##__next = SIZE_MAX;                   \
++                              offset = 0;                                     \
++                      }                                                       \
++              }                                                               \
++              offset;                                                         \
+       })
+ #define vla_ptr(ptr, groupname, name) \
diff --git a/queue-5.8/usb-gadget-u_f-unbreak-offset-calculation-in-vlas.patch b/queue-5.8/usb-gadget-u_f-unbreak-offset-calculation-in-vlas.patch
new file mode 100644 (file)
index 0000000..4fc8806
--- /dev/null
@@ -0,0 +1,51 @@
+From bfd08d06d978d0304eb6f7855b548aa2cd1c5486 Mon Sep 17 00:00:00 2001
+From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Date: Wed, 26 Aug 2020 22:21:19 +0300
+Subject: USB: gadget: u_f: Unbreak offset calculation in VLAs
+
+From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+
+commit bfd08d06d978d0304eb6f7855b548aa2cd1c5486 upstream.
+
+Inadvertently the commit b1cd1b65afba ("USB: gadget: u_f: add overflow checks
+to VLA macros") makes VLA macros to always return 0 due to different scope of
+two variables of the same name. Obviously we need to have only one.
+
+Fixes: b1cd1b65afba ("USB: gadget: u_f: add overflow checks to VLA macros")
+Reported-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Tested-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Cc: Brooke Basile <brookebasile@gmail.com>
+Cc: stable <stable@kernel.org>
+Link: https://lore.kernel.org/r/20200826192119.56450-1-andriy.shevchenko@linux.intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/gadget/u_f.h |    8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+--- a/drivers/usb/gadget/u_f.h
++++ b/drivers/usb/gadget/u_f.h
+@@ -25,9 +25,9 @@
+               size_t offset = 0;                                             \
+               if (groupname##__next != SIZE_MAX) {                           \
+                       size_t align_mask = __alignof__(type) - 1;             \
+-                      size_t offset = (groupname##__next + align_mask)       \
+-                                       & ~align_mask;                        \
+                       size_t size = array_size(n, sizeof(type));             \
++                      offset = (groupname##__next + align_mask) &            \
++                                ~align_mask;                                 \
+                       if (check_add_overflow(offset, size,                   \
+                                              &groupname##__next)) {          \
+                               groupname##__next = SIZE_MAX;                  \
+@@ -43,8 +43,8 @@
+               size_t offset = 0;                                              \
+               if (groupname##__next != SIZE_MAX) {                            \
+                       size_t align_mask = __alignof__(type) - 1;              \
+-                      size_t offset = (groupname##__next + align_mask)        \
+-                                       & ~align_mask;                         \
++                      offset = (groupname##__next + align_mask) &             \
++                                ~align_mask;                                  \
+                       if (check_add_overflow(offset, groupname##_##name##__sz,\
+                                                       &groupname##__next)) {  \
+                               groupname##__next = SIZE_MAX;                   \
diff --git a/queue-5.8/usb-host-ohci-exynos-fix-error-handling-in-exynos_ohci_probe.patch b/queue-5.8/usb-host-ohci-exynos-fix-error-handling-in-exynos_ohci_probe.patch
new file mode 100644 (file)
index 0000000..9008119
--- /dev/null
@@ -0,0 +1,41 @@
+From 1d4169834628d18b2392a2da92b7fbf5e8e2ce89 Mon Sep 17 00:00:00 2001
+From: Tang Bin <tangbin@cmss.chinamobile.com>
+Date: Wed, 26 Aug 2020 22:49:31 +0800
+Subject: usb: host: ohci-exynos: Fix error handling in exynos_ohci_probe()
+
+From: Tang Bin <tangbin@cmss.chinamobile.com>
+
+commit 1d4169834628d18b2392a2da92b7fbf5e8e2ce89 upstream.
+
+If the function platform_get_irq() failed, the negative value
+returned will not be detected here. So fix error handling in
+exynos_ohci_probe(). And when get irq failed, the function
+platform_get_irq() logs an error message, so remove redundant
+message here.
+
+Fixes: 62194244cf87 ("USB: Add Samsung Exynos OHCI diver")
+Signed-off-by: Zhang Shengju <zhangshengju@cmss.chinamobile.com>
+Cc: stable <stable@vger.kernel.org>
+Signed-off-by: Tang Bin <tangbin@cmss.chinamobile.com>
+Reviewed-by: Krzysztof Kozlowski <krzk@kernel.org>
+Link: https://lore.kernel.org/r/20200826144931.1828-1-tangbin@cmss.chinamobile.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/host/ohci-exynos.c |    5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+--- a/drivers/usb/host/ohci-exynos.c
++++ b/drivers/usb/host/ohci-exynos.c
+@@ -171,9 +171,8 @@ static int exynos_ohci_probe(struct plat
+       hcd->rsrc_len = resource_size(res);
+       irq = platform_get_irq(pdev, 0);
+-      if (!irq) {
+-              dev_err(&pdev->dev, "Failed to get IRQ\n");
+-              err = -ENODEV;
++      if (irq < 0) {
++              err = irq;
+               goto fail_io;
+       }
diff --git a/queue-5.8/usb-ignore-uas-for-jmicron-jms567-ata-atapi-bridge.patch b/queue-5.8/usb-ignore-uas-for-jmicron-jms567-ata-atapi-bridge.patch
new file mode 100644 (file)
index 0000000..946547e
--- /dev/null
@@ -0,0 +1,37 @@
+From 9aa37788e7ebb3f489fb4b71ce07adadd444264a Mon Sep 17 00:00:00 2001
+From: Cyril Roelandt <tipecaml@gmail.com>
+Date: Tue, 25 Aug 2020 23:22:31 +0200
+Subject: USB: Ignore UAS for JMicron JMS567 ATA/ATAPI Bridge
+
+From: Cyril Roelandt <tipecaml@gmail.com>
+
+commit 9aa37788e7ebb3f489fb4b71ce07adadd444264a upstream.
+
+This device does not support UAS properly and a similar entry already
+exists in drivers/usb/storage/unusual_uas.h. Without this patch,
+storage_probe() defers the handling of this device to UAS, which cannot
+handle it either.
+
+Tested-by: Brice Goglin <brice.goglin@gmail.com>
+Fixes: bc3bdb12bbb3 ("usb-storage: Disable UAS on JMicron SATA enclosure")
+Acked-by: Alan Stern <stern@rowland.harvard.edu>
+CC: <stable@vger.kernel.org>
+Signed-off-by: Cyril Roelandt <tipecaml@gmail.com>
+Link: https://lore.kernel.org/r/20200825212231.46309-1-tipecaml@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/storage/unusual_devs.h |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/usb/storage/unusual_devs.h
++++ b/drivers/usb/storage/unusual_devs.h
+@@ -2328,7 +2328,7 @@ UNUSUAL_DEV(  0x357d, 0x7788, 0x0114, 0x
+               "JMicron",
+               "USB to ATA/ATAPI Bridge",
+               USB_SC_DEVICE, USB_PR_DEVICE, NULL,
+-              US_FL_BROKEN_FUA ),
++              US_FL_BROKEN_FUA | US_FL_IGNORE_UAS ),
+ /* Reported by Andrey Rahmatullin <wrar@altlinux.org> */
+ UNUSUAL_DEV(  0x4102, 0x1020, 0x0100,  0x0100,
diff --git a/queue-5.8/usb-quirks-add-no-lpm-quirk-for-another-raydium-touchscreen.patch b/queue-5.8/usb-quirks-add-no-lpm-quirk-for-another-raydium-touchscreen.patch
new file mode 100644 (file)
index 0000000..80194e9
--- /dev/null
@@ -0,0 +1,38 @@
+From 5967116e8358899ebaa22702d09b0af57fef23e1 Mon Sep 17 00:00:00 2001
+From: Kai-Heng Feng <kai.heng.feng@canonical.com>
+Date: Fri, 31 Jul 2020 13:16:20 +0800
+Subject: USB: quirks: Add no-lpm quirk for another Raydium touchscreen
+
+From: Kai-Heng Feng <kai.heng.feng@canonical.com>
+
+commit 5967116e8358899ebaa22702d09b0af57fef23e1 upstream.
+
+There's another Raydium touchscreen needs the no-lpm quirk:
+[    1.339149] usb 1-9: New USB device found, idVendor=2386, idProduct=350e, bcdDevice= 0.00
+[    1.339150] usb 1-9: New USB device strings: Mfr=1, Product=2, SerialNumber=0
+[    1.339151] usb 1-9: Product: Raydium Touch System
+[    1.339152] usb 1-9: Manufacturer: Raydium Corporation
+...
+[    6.450497] usb 1-9: can't set config #1, error -110
+
+BugLink: https://bugs.launchpad.net/bugs/1889446
+Signed-off-by: Kai-Heng Feng <kai.heng.feng@canonical.com>
+Cc: stable <stable@vger.kernel.org>
+Link: https://lore.kernel.org/r/20200731051622.28643-1-kai.heng.feng@canonical.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/core/quirks.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/usb/core/quirks.c
++++ b/drivers/usb/core/quirks.c
+@@ -465,6 +465,8 @@ static const struct usb_device_id usb_qu
+       { USB_DEVICE(0x2386, 0x3119), .driver_info = USB_QUIRK_NO_LPM },
++      { USB_DEVICE(0x2386, 0x350e), .driver_info = USB_QUIRK_NO_LPM },
++
+       /* DJI CineSSD */
+       { USB_DEVICE(0x2ca3, 0x0031), .driver_info = USB_QUIRK_NO_LPM },
diff --git a/queue-5.8/usb-quirks-ignore-duplicate-endpoint-on-sound-devices-mixpre-d.patch b/queue-5.8/usb-quirks-ignore-duplicate-endpoint-on-sound-devices-mixpre-d.patch
new file mode 100644 (file)
index 0000000..7034166
--- /dev/null
@@ -0,0 +1,53 @@
+From 068834a2773b6a12805105cfadbb3d4229fc6e0a Mon Sep 17 00:00:00 2001
+From: Alan Stern <stern@rowland.harvard.edu>
+Date: Wed, 26 Aug 2020 15:46:24 -0400
+Subject: USB: quirks: Ignore duplicate endpoint on Sound Devices MixPre-D
+
+From: Alan Stern <stern@rowland.harvard.edu>
+
+commit 068834a2773b6a12805105cfadbb3d4229fc6e0a upstream.
+
+The Sound Devices MixPre-D audio card suffers from the same defect
+as the Sound Devices USBPre2: an endpoint shared between a normal
+audio interface and a vendor-specific interface, in violation of the
+USB spec.  Since the USB core now treats duplicated endpoints as bugs
+and ignores them, the audio endpoint isn't available and the card
+can't be used for audio capture.
+
+Along the same lines as commit bdd1b147b802 ("USB: quirks: blacklist
+duplicate ep on Sound Devices USBPre2"), this patch adds a quirks
+entry saying to ignore ep5in for interface 1, leaving it available for
+use with standard audio interface 2.
+
+Reported-and-tested-by: Jean-Christophe Barnoud <jcbarnoud@gmail.com>
+Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
+CC: <stable@vger.kernel.org>
+Fixes: 3e4f8e21c4f2 ("USB: core: fix check for duplicate endpoints")
+Link: https://lore.kernel.org/r/20200826194624.GA412633@rowland.harvard.edu
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/core/quirks.c |    5 +++++
+ 1 file changed, 5 insertions(+)
+
+--- a/drivers/usb/core/quirks.c
++++ b/drivers/usb/core/quirks.c
+@@ -370,6 +370,10 @@ static const struct usb_device_id usb_qu
+       { USB_DEVICE(0x0926, 0x0202), .driver_info =
+                       USB_QUIRK_ENDPOINT_BLACKLIST },
++      /* Sound Devices MixPre-D */
++      { USB_DEVICE(0x0926, 0x0208), .driver_info =
++                      USB_QUIRK_ENDPOINT_BLACKLIST },
++
+       /* Keytouch QWERTY Panel keyboard */
+       { USB_DEVICE(0x0926, 0x3333), .driver_info =
+                       USB_QUIRK_CONFIG_INTF_STRINGS },
+@@ -511,6 +515,7 @@ static const struct usb_device_id usb_am
+  */
+ static const struct usb_device_id usb_endpoint_blacklist[] = {
+       { USB_DEVICE_INTERFACE_NUMBER(0x0926, 0x0202, 1), .driver_info = 0x85 },
++      { USB_DEVICE_INTERFACE_NUMBER(0x0926, 0x0208, 1), .driver_info = 0x85 },
+       { }
+ };
diff --git a/queue-5.8/usb-storage-add-unusual_uas-entry-for-sony-psz-drives.patch b/queue-5.8/usb-storage-add-unusual_uas-entry-for-sony-psz-drives.patch
new file mode 100644 (file)
index 0000000..adc63da
--- /dev/null
@@ -0,0 +1,42 @@
+From 20934c0de13b49a072fb1e0ca79fe0fe0e40eae5 Mon Sep 17 00:00:00 2001
+From: Alan Stern <stern@rowland.harvard.edu>
+Date: Wed, 26 Aug 2020 10:32:29 -0400
+Subject: usb: storage: Add unusual_uas entry for Sony PSZ drives
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Alan Stern <stern@rowland.harvard.edu>
+
+commit 20934c0de13b49a072fb1e0ca79fe0fe0e40eae5 upstream.
+
+The PSZ-HA* family of USB disk drives from Sony can't handle the
+REPORT OPCODES command when using the UAS protocol.  This patch adds
+an appropriate quirks entry.
+
+Reported-and-tested-by: Till Dörges <doerges@pre-sense.de>
+Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
+CC: <stable@vger.kernel.org>
+Link: https://lore.kernel.org/r/20200826143229.GB400430@rowland.harvard.edu
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/storage/unusual_uas.h |    7 +++++++
+ 1 file changed, 7 insertions(+)
+
+--- a/drivers/usb/storage/unusual_uas.h
++++ b/drivers/usb/storage/unusual_uas.h
+@@ -28,6 +28,13 @@
+  * and don't forget to CC: the USB development list <linux-usb@vger.kernel.org>
+  */
++/* Reported-by: Till Dörges <doerges@pre-sense.de> */
++UNUSUAL_DEV(0x054c, 0x087d, 0x0000, 0x9999,
++              "Sony",
++              "PSZ-HA*",
++              USB_SC_DEVICE, USB_PR_DEVICE, NULL,
++              US_FL_NO_REPORT_OPCODES),
++
+ /* Reported-by: Julian Groß <julian.g@posteo.de> */
+ UNUSUAL_DEV(0x059f, 0x105f, 0x0000, 0x9999,
+               "LaCie",
diff --git a/queue-5.8/usb-typec-tcpm-fix-fix-source-hard-reset-response-for-tda-2.3.1.1-and-tda-2.3.1.2-failures.patch b/queue-5.8/usb-typec-tcpm-fix-fix-source-hard-reset-response-for-tda-2.3.1.1-and-tda-2.3.1.2-failures.patch
new file mode 100644 (file)
index 0000000..e6543c0
--- /dev/null
@@ -0,0 +1,139 @@
+From 23e26d0577535f5ffe4ff8ed6d06e009553c0bca Mon Sep 17 00:00:00 2001
+From: Badhri Jagan Sridharan <badhri@google.com>
+Date: Mon, 17 Aug 2020 11:46:01 -0700
+Subject: usb: typec: tcpm: Fix Fix source hard reset response for TDA 2.3.1.1 and TDA 2.3.1.2 failures
+
+From: Badhri Jagan Sridharan <badhri@google.com>
+
+commit 23e26d0577535f5ffe4ff8ed6d06e009553c0bca upstream.
+
+The patch addresses the compliance test failures while running  TDA
+2.3.1.1 and  TDA 2.3.1.2 of the "PD Communications Engine USB PD
+Compliance MOI" test plan published in https://www.usb.org/usbc.
+For a product to be Type-C compliant, it's expected that these tests
+are run on usb.org certified Type-C compliance tester as mentioned in
+https://www.usb.org/usbc.
+
+While the purpose of TDA 2.3.1.1 and  TDA 2.3.1.2 is to verify that
+the static and dynamic electrical capabilities of a Source meet the
+requirements for each PDO offered,  while doing so, the tests also
+monitor that the timing of the VBUS waveform versus the messages meets
+the requirements for Hard Reset defined in PROT-PROC-HR-TSTR as
+mentioned in step 11 of TDA.2.3.1.1 and step 15 of TDA.2.3.1.2.
+
+TDB.2.2.13.1: PROT-PROC-HR-TSTR Procedure and Checks for Tester
+Originated Hard Reset
+Purpose: To perform the appropriate protocol checks relating to any
+circumstance in which the Hard Reset signal is sent by the Tester.
+
+UUT is behaving as source:
+The Tester sends a Hard Reset signal.
+1. Check VBUS stays within present valid voltage range for
+tPSHardReset min (25ms) after last bit of Hard Reset signal.
+[PROT_PROC_HR_TSTR_1]
+2. Check that VBUS starts to fall below present valid voltage range by
+tPSHardReset max (35ms). [PROT_PROC_HR_TSTR_2]
+3. Check that VBUS reaches vSafe0V within tSafe0v max (650 ms).
+[PROT_PROC_HR_TSTR_3]
+4. Check that VBUS starts rising to vSafe5V after a delay of
+tSrcRecover (0.66s - 1s) from reaching vSafe0V. [PROT_PROC_HR_TSTR_4]
+5. Check that VBUS reaches vSafe5V within tSrcTurnOn max (275ms) of
+rising above vSafe0v max (0.8V). [PROT_PROC_HR_TSTR_5] Power Delivery
+Compliance Plan 139 6. Check that Source Capabilities are finished
+sending within tFirstSourceCap max (250ms) of VBUS reaching vSafe5v
+min. [PROT_PROC_HR_TSTR_6].
+
+This is in line with 7.1.5 Response to Hard Resets of the USB Power
+Delivery Specification Revision 3.0, Version 1.2,
+"Hard Reset Signaling indicates a communication failure has occurred
+and the Source Shall stop driving VCONN, Shall remove Rp from the
+VCONN pin and Shall drive VBUS to vSafe0V as shown in Figure 7-9. The
+USB connection May reset during a Hard Reset since the VBUS voltage
+will be less than vSafe5V for an extended period of time. After
+establishing the vSafe0V voltage condition on VBUS, the Source Shall
+wait tSrcRecover before re-applying VCONN and restoring VBUS to
+vSafe5V. A Source Shall conform to the VCONN timing as specified in
+[USB Type-C 1.3]."
+
+With the above guidelines from the spec in mind, TCPM does not turn
+off VCONN while entering SRC_HARD_RESET_VBUS_OFF. The patch makes TCPM
+turn off VCONN while entering SRC_HARD_RESET_VBUS_OFF and turn it back
+on while entering SRC_HARD_RESET_VBUS_ON along with vbus instead of
+having VCONN on through hardreset.
+
+Also, the spec clearly states that "After establishing the vSafe0V
+voltage condition on VBUS",  the Source Shall wait tSrcRecover before
+re-applying VCONN and restoring VBUS to vSafe5V.
+TCPM does not conform to this requirement. If the TCPC driver calls
+tcpm_vbus_change with vbus off signal, TCPM right away enters
+SRC_HARD_RESET_VBUS_ON without waiting for tSrcRecover.
+For TCPC's which are buggy/does not call tcpm_vbus_change, TCPM
+assumes that the vsafe0v is instantaneous as TCPM only waits
+tSrcRecover instead of waiting for tSafe0v + tSrcRecover.
+This patch also fixes this behavior by making sure that TCPM waits for
+tSrcRecover before transitioning into SRC_HARD_RESET_VBUS_ON when
+tcpm_vbus_change is called by TCPC.
+When TCPC does not call tcpm_vbus_change, TCPM assumes the worst case
+i.e.  tSafe0v + tSrcRecover before transitioning into
+SRC_HARD_RESET_VBUS_ON.
+
+Signed-off-by: Badhri Jagan Sridharan <badhri@google.com>
+Reviewed-by: Guenter Roeck <linux@roeck-us.net>
+Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
+Cc: stable <stable@kernel.org>
+Link: https://lore.kernel.org/r/20200817184601.1899929-1-badhri@google.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/typec/tcpm/tcpm.c |   28 +++++++++++++++++++++++++---
+ 1 file changed, 25 insertions(+), 3 deletions(-)
+
+--- a/drivers/usb/typec/tcpm/tcpm.c
++++ b/drivers/usb/typec/tcpm/tcpm.c
+@@ -3321,13 +3321,31 @@ static void run_state_machine(struct tcp
+                       tcpm_set_state(port, SNK_HARD_RESET_SINK_OFF, 0);
+               break;
+       case SRC_HARD_RESET_VBUS_OFF:
+-              tcpm_set_vconn(port, true);
++              /*
++               * 7.1.5 Response to Hard Resets
++               * Hard Reset Signaling indicates a communication failure has occurred and the
++               * Source Shall stop driving VCONN, Shall remove Rp from the VCONN pin and Shall
++               * drive VBUS to vSafe0V as shown in Figure 7-9.
++               */
++              tcpm_set_vconn(port, false);
+               tcpm_set_vbus(port, false);
+               tcpm_set_roles(port, port->self_powered, TYPEC_SOURCE,
+                              tcpm_data_role_for_source(port));
+-              tcpm_set_state(port, SRC_HARD_RESET_VBUS_ON, PD_T_SRC_RECOVER);
++              /*
++               * If tcpc fails to notify vbus off, TCPM will wait for PD_T_SAFE_0V +
++               * PD_T_SRC_RECOVER before turning vbus back on.
++               * From Table 7-12 Sequence Description for a Source Initiated Hard Reset:
++               * 4. Policy Engine waits tPSHardReset after sending Hard Reset Signaling and then
++               * tells the Device Policy Manager to instruct the power supply to perform a
++               * Hard Reset. The transition to vSafe0V Shall occur within tSafe0V (t2).
++               * 5. After tSrcRecover the Source applies power to VBUS in an attempt to
++               * re-establish communication with the Sink and resume USB Default Operation.
++               * The transition to vSafe5V Shall occur within tSrcTurnOn(t4).
++               */
++              tcpm_set_state(port, SRC_HARD_RESET_VBUS_ON, PD_T_SAFE_0V + PD_T_SRC_RECOVER);
+               break;
+       case SRC_HARD_RESET_VBUS_ON:
++              tcpm_set_vconn(port, true);
+               tcpm_set_vbus(port, true);
+               port->tcpc->set_pd_rx(port->tcpc, true);
+               tcpm_set_attached_state(port, true);
+@@ -3887,7 +3905,11 @@ static void _tcpm_pd_vbus_off(struct tcp
+               tcpm_set_state(port, SNK_HARD_RESET_WAIT_VBUS, 0);
+               break;
+       case SRC_HARD_RESET_VBUS_OFF:
+-              tcpm_set_state(port, SRC_HARD_RESET_VBUS_ON, 0);
++              /*
++               * After establishing the vSafe0V voltage condition on VBUS, the Source Shall wait
++               * tSrcRecover before re-applying VCONN and restoring VBUS to vSafe5V.
++               */
++              tcpm_set_state(port, SRC_HARD_RESET_VBUS_ON, PD_T_SRC_RECOVER);
+               break;
+       case HARD_RESET_SEND:
+               break;
diff --git a/queue-5.8/usb-typec-ucsi-fix-2-unlocked-ucsi_run_command-calls.patch b/queue-5.8/usb-typec-ucsi-fix-2-unlocked-ucsi_run_command-calls.patch
new file mode 100644 (file)
index 0000000..da61adc
--- /dev/null
@@ -0,0 +1,65 @@
+From 7e90057f125c8c852940b848e06e7a72f050fc6f Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede@redhat.com>
+Date: Sun, 9 Aug 2020 16:19:02 +0200
+Subject: usb: typec: ucsi: Fix 2 unlocked ucsi_run_command calls
+
+From: Hans de Goede <hdegoede@redhat.com>
+
+commit 7e90057f125c8c852940b848e06e7a72f050fc6f upstream.
+
+Fix 2 unlocked ucsi_run_command calls:
+
+1. ucsi_handle_connector_change() contains one ucsi_send_command() call,
+which takes the ppm_lock for it; and one ucsi_run_command() call which
+relies on the caller have taking the ppm_lock.
+ucsi_handle_connector_change() does not take the lock, so the
+second (ucsi_run_command) calls should also be ucsi_send_command().
+
+2. ucsi_get_pdos() gets called from ucsi_handle_connector_change() which
+does not hold the ppm_lock, so it also must use ucsi_send_command().
+
+This commit also adds a WARN_ON(!mutex_is_locked(&ucsi->ppm_lock)); to
+ucsi_run_command() to avoid similar problems getting re-introduced in
+the future.
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Acked-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
+Reviewed-by: Guenter Roeck <linux@roeck-us.net>
+Link: https://lore.kernel.org/r/20200809141904.4317-3-hdegoede@redhat.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/typec/ucsi/ucsi.c |    6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+--- a/drivers/usb/typec/ucsi/ucsi.c
++++ b/drivers/usb/typec/ucsi/ucsi.c
+@@ -152,6 +152,8 @@ static int ucsi_run_command(struct ucsi
+       u8 length;
+       int ret;
++      WARN_ON(!mutex_is_locked(&ucsi->ppm_lock));
++
+       ret = ucsi_exec_command(ucsi, command);
+       if (ret < 0)
+               return ret;
+@@ -502,7 +504,7 @@ static void ucsi_get_pdos(struct ucsi_co
+       command |= UCSI_GET_PDOS_PARTNER_PDO(is_partner);
+       command |= UCSI_GET_PDOS_NUM_PDOS(UCSI_MAX_PDOS - 1);
+       command |= UCSI_GET_PDOS_SRC_PDOS;
+-      ret = ucsi_run_command(ucsi, command, con->src_pdos,
++      ret = ucsi_send_command(ucsi, command, con->src_pdos,
+                              sizeof(con->src_pdos));
+       if (ret < 0) {
+               dev_err(ucsi->dev, "UCSI_GET_PDOS failed (%d)\n", ret);
+@@ -681,7 +683,7 @@ static void ucsi_handle_connector_change
+                */
+               command = UCSI_GET_CAM_SUPPORTED;
+               command |= UCSI_CONNECTOR_NUMBER(con->num);
+-              ucsi_run_command(con->ucsi, command, NULL, 0);
++              ucsi_send_command(con->ucsi, command, NULL, 0);
+       }
+       if (con->status.change & UCSI_CONSTAT_PARTNER_CHANGE)
diff --git a/queue-5.8/usb-typec-ucsi-fix-ab-ba-lock-inversion.patch b/queue-5.8/usb-typec-ucsi-fix-ab-ba-lock-inversion.patch
new file mode 100644 (file)
index 0000000..992b8a4
--- /dev/null
@@ -0,0 +1,132 @@
+From 0ff0705a2ef2929e9326c95df48bdbebb0dafaad Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede@redhat.com>
+Date: Sun, 9 Aug 2020 16:19:01 +0200
+Subject: usb: typec: ucsi: Fix AB BA lock inversion
+
+From: Hans de Goede <hdegoede@redhat.com>
+
+commit 0ff0705a2ef2929e9326c95df48bdbebb0dafaad upstream.
+
+Lockdep reports an AB BA lock inversion between ucsi_init() and
+ucsi_handle_connector_change():
+
+AB order:
+
+1. ucsi_init takes ucsi->ppm_lock (it runs with that locked for the
+   duration of the function)
+2. usci_init eventually end up calling ucsi_register_displayport,
+   which takes ucsi_connector->lock
+
+BA order:
+
+1. ucsi_handle_connector_change work is started, takes ucsi_connector->lock
+2. ucsi_handle_connector_change calls ucsi_send_command which takes
+   ucsi->ppm_lock
+
+The ppm_lock really only needs to be hold during 2 functions:
+ucsi_reset_ppm() and ucsi_run_command().
+
+This commit fixes the AB BA lock inversion by making ucsi_init drop the
+ucsi->ppm_lock before it starts registering ports; and replacing any
+ucsi_run_command() calls after this point with ucsi_send_command()
+(which is a wrapper around run_command taking the lock while handling
+the command).
+
+Some of the replacing of ucsi_run_command with ucsi_send_command
+in the helpers used during port registration also fixes a number of
+code paths after registration which call ucsi_run_command() without
+holding the ppm_lock:
+1. ucsi_altmode_update_active() call in ucsi/displayport.c
+2. ucsi_register_altmodes() call from ucsi_handle_connector_change()
+   (through ucsi_partner_change())
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Acked-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
+Reviewed-by: Guenter Roeck <linux@roeck-us.net>
+Link: https://lore.kernel.org/r/20200809141904.4317-2-hdegoede@redhat.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/typec/ucsi/ucsi.c |   18 +++++++++---------
+ 1 file changed, 9 insertions(+), 9 deletions(-)
+
+--- a/drivers/usb/typec/ucsi/ucsi.c
++++ b/drivers/usb/typec/ucsi/ucsi.c
+@@ -205,7 +205,7 @@ void ucsi_altmode_update_active(struct u
+       int i;
+       command = UCSI_GET_CURRENT_CAM | UCSI_CONNECTOR_NUMBER(con->num);
+-      ret = ucsi_run_command(con->ucsi, command, &cur, sizeof(cur));
++      ret = ucsi_send_command(con->ucsi, command, &cur, sizeof(cur));
+       if (ret < 0) {
+               if (con->ucsi->version > 0x0100) {
+                       dev_err(con->ucsi->dev,
+@@ -354,7 +354,7 @@ ucsi_register_altmodes_nvidia(struct ucs
+               command |= UCSI_GET_ALTMODE_RECIPIENT(recipient);
+               command |= UCSI_GET_ALTMODE_CONNECTOR_NUMBER(con->num);
+               command |= UCSI_GET_ALTMODE_OFFSET(i);
+-              len = ucsi_run_command(con->ucsi, command, &alt, sizeof(alt));
++              len = ucsi_send_command(con->ucsi, command, &alt, sizeof(alt));
+               /*
+                * We are collecting all altmodes first and then registering.
+                * Some type-C device will return zero length data beyond last
+@@ -431,7 +431,7 @@ static int ucsi_register_altmodes(struct
+               command |= UCSI_GET_ALTMODE_RECIPIENT(recipient);
+               command |= UCSI_GET_ALTMODE_CONNECTOR_NUMBER(con->num);
+               command |= UCSI_GET_ALTMODE_OFFSET(i);
+-              len = ucsi_run_command(con->ucsi, command, alt, sizeof(alt));
++              len = ucsi_send_command(con->ucsi, command, alt, sizeof(alt));
+               if (len <= 0)
+                       return len;
+@@ -904,7 +904,7 @@ static int ucsi_register_port(struct ucs
+       /* Get connector capability */
+       command = UCSI_GET_CONNECTOR_CAPABILITY;
+       command |= UCSI_CONNECTOR_NUMBER(con->num);
+-      ret = ucsi_run_command(ucsi, command, &con->cap, sizeof(con->cap));
++      ret = ucsi_send_command(ucsi, command, &con->cap, sizeof(con->cap));
+       if (ret < 0)
+               return ret;
+@@ -953,8 +953,7 @@ static int ucsi_register_port(struct ucs
+       /* Get the status */
+       command = UCSI_GET_CONNECTOR_STATUS | UCSI_CONNECTOR_NUMBER(con->num);
+-      ret = ucsi_run_command(ucsi, command, &con->status,
+-                             sizeof(con->status));
++      ret = ucsi_send_command(ucsi, command, &con->status, sizeof(con->status));
+       if (ret < 0) {
+               dev_err(ucsi->dev, "con%d: failed to get status\n", con->num);
+               return 0;
+@@ -1044,6 +1043,8 @@ int ucsi_init(struct ucsi *ucsi)
+               goto err_reset;
+       }
++      mutex_unlock(&ucsi->ppm_lock);
++
+       /* Register all connectors */
+       for (i = 0; i < ucsi->cap.num_connectors; i++) {
+               ret = ucsi_register_port(ucsi, i);
+@@ -1054,12 +1055,10 @@ int ucsi_init(struct ucsi *ucsi)
+       /* Enable all notifications */
+       ucsi->ntfy = UCSI_ENABLE_NTFY_ALL;
+       command = UCSI_SET_NOTIFICATION_ENABLE | ucsi->ntfy;
+-      ret = ucsi_run_command(ucsi, command, NULL, 0);
++      ret = ucsi_send_command(ucsi, command, NULL, 0);
+       if (ret < 0)
+               goto err_unregister;
+-      mutex_unlock(&ucsi->ppm_lock);
+-
+       return 0;
+ err_unregister:
+@@ -1071,6 +1070,7 @@ err_unregister:
+               con->port = NULL;
+       }
++      mutex_lock(&ucsi->ppm_lock);
+ err_reset:
+       ucsi_reset_ppm(ucsi);
+ err:
diff --git a/queue-5.8/usb-typec-ucsi-hold-con-lock-for-the-entire-duration-of-ucsi_register_port.patch b/queue-5.8/usb-typec-ucsi-hold-con-lock-for-the-entire-duration-of-ucsi_register_port.patch
new file mode 100644 (file)
index 0000000..d779d85
--- /dev/null
@@ -0,0 +1,149 @@
+From bed97b30968ba354035a020989df0623e52b5536 Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede@redhat.com>
+Date: Sun, 9 Aug 2020 16:19:04 +0200
+Subject: usb: typec: ucsi: Hold con->lock for the entire duration of ucsi_register_port()
+
+From: Hans de Goede <hdegoede@redhat.com>
+
+commit bed97b30968ba354035a020989df0623e52b5536 upstream.
+
+Commit 081da1325d35 ("usb: typec: ucsi: displayport: Fix a potential race
+during registration") made the ucsi code hold con->lock in
+ucsi_register_displayport(). But we really don't want any interactions
+with the connector to run before the port-registration process is fully
+complete.
+
+This commit moves the taking of con->lock from ucsi_register_displayport()
+into ucsi_register_port() to achieve this.
+
+Cc: stable@vger.kernel.org
+Fixes: 081da1325d35 ("usb: typec: ucsi: displayport: Fix a potential race during registration")
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Acked-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
+Reviewed-by: Guenter Roeck <linux@roeck-us.net>
+Link: https://lore.kernel.org/r/20200809141904.4317-5-hdegoede@redhat.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/typec/ucsi/displayport.c |    9 +--------
+ drivers/usb/typec/ucsi/ucsi.c        |   31 ++++++++++++++++++++++---------
+ 2 files changed, 23 insertions(+), 17 deletions(-)
+
+--- a/drivers/usb/typec/ucsi/displayport.c
++++ b/drivers/usb/typec/ucsi/displayport.c
+@@ -288,8 +288,6 @@ struct typec_altmode *ucsi_register_disp
+       struct typec_altmode *alt;
+       struct ucsi_dp *dp;
+-      mutex_lock(&con->lock);
+-
+       /* We can't rely on the firmware with the capabilities. */
+       desc->vdo |= DP_CAP_DP_SIGNALING | DP_CAP_RECEPTACLE;
+@@ -298,15 +296,12 @@ struct typec_altmode *ucsi_register_disp
+       desc->vdo |= all_assignments << 16;
+       alt = typec_port_register_altmode(con->port, desc);
+-      if (IS_ERR(alt)) {
+-              mutex_unlock(&con->lock);
++      if (IS_ERR(alt))
+               return alt;
+-      }
+       dp = devm_kzalloc(&alt->dev, sizeof(*dp), GFP_KERNEL);
+       if (!dp) {
+               typec_unregister_altmode(alt);
+-              mutex_unlock(&con->lock);
+               return ERR_PTR(-ENOMEM);
+       }
+@@ -319,7 +314,5 @@ struct typec_altmode *ucsi_register_disp
+       alt->ops = &ucsi_displayport_ops;
+       typec_altmode_set_drvdata(alt, dp);
+-      mutex_unlock(&con->lock);
+-
+       return alt;
+ }
+--- a/drivers/usb/typec/ucsi/ucsi.c
++++ b/drivers/usb/typec/ucsi/ucsi.c
+@@ -898,12 +898,15 @@ static int ucsi_register_port(struct ucs
+       con->num = index + 1;
+       con->ucsi = ucsi;
++      /* Delay other interactions with the con until registration is complete */
++      mutex_lock(&con->lock);
++
+       /* Get connector capability */
+       command = UCSI_GET_CONNECTOR_CAPABILITY;
+       command |= UCSI_CONNECTOR_NUMBER(con->num);
+       ret = ucsi_send_command(ucsi, command, &con->cap, sizeof(con->cap));
+       if (ret < 0)
+-              return ret;
++              goto out;
+       if (con->cap.op_mode & UCSI_CONCAP_OPMODE_DRP)
+               cap->data = TYPEC_PORT_DRD;
+@@ -935,26 +938,32 @@ static int ucsi_register_port(struct ucs
+       ret = ucsi_register_port_psy(con);
+       if (ret)
+-              return ret;
++              goto out;
+       /* Register the connector */
+       con->port = typec_register_port(ucsi->dev, cap);
+-      if (IS_ERR(con->port))
+-              return PTR_ERR(con->port);
++      if (IS_ERR(con->port)) {
++              ret = PTR_ERR(con->port);
++              goto out;
++      }
+       /* Alternate modes */
+       ret = ucsi_register_altmodes(con, UCSI_RECIPIENT_CON);
+-      if (ret)
++      if (ret) {
+               dev_err(ucsi->dev, "con%d: failed to register alt modes\n",
+                       con->num);
++              goto out;
++      }
+       /* Get the status */
+       command = UCSI_GET_CONNECTOR_STATUS | UCSI_CONNECTOR_NUMBER(con->num);
+       ret = ucsi_send_command(ucsi, command, &con->status, sizeof(con->status));
+       if (ret < 0) {
+               dev_err(ucsi->dev, "con%d: failed to get status\n", con->num);
+-              return 0;
++              ret = 0;
++              goto out;
+       }
++      ret = 0; /* ucsi_send_command() returns length on success */
+       switch (UCSI_CONSTAT_PARTNER_TYPE(con->status.flags)) {
+       case UCSI_CONSTAT_PARTNER_TYPE_UFP:
+@@ -979,17 +988,21 @@ static int ucsi_register_port(struct ucs
+       if (con->partner) {
+               ret = ucsi_register_altmodes(con, UCSI_RECIPIENT_SOP);
+-              if (ret)
++              if (ret) {
+                       dev_err(ucsi->dev,
+                               "con%d: failed to register alternate modes\n",
+                               con->num);
+-              else
++                      ret = 0;
++              } else {
+                       ucsi_altmode_update_active(con);
++              }
+       }
+       trace_ucsi_register_port(con->num, &con->status);
+-      return 0;
++out:
++      mutex_unlock(&con->lock);
++      return ret;
+ }
+ /**
diff --git a/queue-5.8/usb-typec-ucsi-rework-ppm_lock-handling.patch b/queue-5.8/usb-typec-ucsi-rework-ppm_lock-handling.patch
new file mode 100644 (file)
index 0000000..ec1289e
--- /dev/null
@@ -0,0 +1,188 @@
+From 25794e3079d2a98547b6bf5764ef0240aa89b798 Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede@redhat.com>
+Date: Sun, 9 Aug 2020 16:19:03 +0200
+Subject: usb: typec: ucsi: Rework ppm_lock handling
+
+From: Hans de Goede <hdegoede@redhat.com>
+
+commit 25794e3079d2a98547b6bf5764ef0240aa89b798 upstream.
+
+The ppm_lock really only needs to be hold during 2 functions:
+ucsi_reset_ppm() and ucsi_run_command().
+
+Push the taking of the lock down into these 2 functions, renaming
+ucsi_run_command() to ucsi_send_command() which was an existing
+wrapper already taking the lock for its callers.
+
+This simplifies things for the callers and removes the difference
+between ucsi_send_command() and ucsi_run_command() which has led
+to various locking bugs in the past.
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Acked-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
+Reviewed-by: Guenter Roeck <linux@roeck-us.net>
+Link: https://lore.kernel.org/r/20200809141904.4317-4-hdegoede@redhat.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/typec/ucsi/ucsi.c |   56 ++++++++++++++++--------------------------
+ 1 file changed, 22 insertions(+), 34 deletions(-)
+
+--- a/drivers/usb/typec/ucsi/ucsi.c
++++ b/drivers/usb/typec/ucsi/ucsi.c
+@@ -146,42 +146,33 @@ static int ucsi_exec_command(struct ucsi
+       return UCSI_CCI_LENGTH(cci);
+ }
+-static int ucsi_run_command(struct ucsi *ucsi, u64 command,
+-                          void *data, size_t size)
++int ucsi_send_command(struct ucsi *ucsi, u64 command,
++                    void *data, size_t size)
+ {
+       u8 length;
+       int ret;
+-      WARN_ON(!mutex_is_locked(&ucsi->ppm_lock));
++      mutex_lock(&ucsi->ppm_lock);
+       ret = ucsi_exec_command(ucsi, command);
+       if (ret < 0)
+-              return ret;
++              goto out;
+       length = ret;
+       if (data) {
+               ret = ucsi->ops->read(ucsi, UCSI_MESSAGE_IN, data, size);
+               if (ret)
+-                      return ret;
++                      goto out;
+       }
+       ret = ucsi_acknowledge_command(ucsi);
+       if (ret)
+-              return ret;
+-
+-      return length;
+-}
++              goto out;
+-int ucsi_send_command(struct ucsi *ucsi, u64 command,
+-                    void *retval, size_t size)
+-{
+-      int ret;
+-
+-      mutex_lock(&ucsi->ppm_lock);
+-      ret = ucsi_run_command(ucsi, command, retval, size);
++      ret = length;
++out:
+       mutex_unlock(&ucsi->ppm_lock);
+-
+       return ret;
+ }
+ EXPORT_SYMBOL_GPL(ucsi_send_command);
+@@ -738,20 +729,24 @@ static int ucsi_reset_ppm(struct ucsi *u
+       u32 cci;
+       int ret;
++      mutex_lock(&ucsi->ppm_lock);
++
+       ret = ucsi->ops->async_write(ucsi, UCSI_CONTROL, &command,
+                                    sizeof(command));
+       if (ret < 0)
+-              return ret;
++              goto out;
+       tmo = jiffies + msecs_to_jiffies(UCSI_TIMEOUT_MS);
+       do {
+-              if (time_is_before_jiffies(tmo))
+-                      return -ETIMEDOUT;
++              if (time_is_before_jiffies(tmo)) {
++                      ret = -ETIMEDOUT;
++                      goto out;
++              }
+               ret = ucsi->ops->read(ucsi, UCSI_CCI, &cci, sizeof(cci));
+               if (ret)
+-                      return ret;
++                      goto out;
+               /* If the PPM is still doing something else, reset it again. */
+               if (cci & ~UCSI_CCI_RESET_COMPLETE) {
+@@ -759,13 +754,15 @@ static int ucsi_reset_ppm(struct ucsi *u
+                                                    &command,
+                                                    sizeof(command));
+                       if (ret < 0)
+-                              return ret;
++                              goto out;
+               }
+               msleep(20);
+       } while (!(cci & UCSI_CCI_RESET_COMPLETE));
+-      return 0;
++out:
++      mutex_unlock(&ucsi->ppm_lock);
++      return ret;
+ }
+ static int ucsi_role_cmd(struct ucsi_connector *con, u64 command)
+@@ -777,9 +774,7 @@ static int ucsi_role_cmd(struct ucsi_con
+               u64 c;
+               /* PPM most likely stopped responding. Resetting everything. */
+-              mutex_lock(&con->ucsi->ppm_lock);
+               ucsi_reset_ppm(con->ucsi);
+-              mutex_unlock(&con->ucsi->ppm_lock);
+               c = UCSI_SET_NOTIFICATION_ENABLE | con->ucsi->ntfy;
+               ucsi_send_command(con->ucsi, c, NULL, 0);
+@@ -1010,8 +1005,6 @@ int ucsi_init(struct ucsi *ucsi)
+       int ret;
+       int i;
+-      mutex_lock(&ucsi->ppm_lock);
+-
+       /* Reset the PPM */
+       ret = ucsi_reset_ppm(ucsi);
+       if (ret) {
+@@ -1022,13 +1015,13 @@ int ucsi_init(struct ucsi *ucsi)
+       /* Enable basic notifications */
+       ucsi->ntfy = UCSI_ENABLE_NTFY_CMD_COMPLETE | UCSI_ENABLE_NTFY_ERROR;
+       command = UCSI_SET_NOTIFICATION_ENABLE | ucsi->ntfy;
+-      ret = ucsi_run_command(ucsi, command, NULL, 0);
++      ret = ucsi_send_command(ucsi, command, NULL, 0);
+       if (ret < 0)
+               goto err_reset;
+       /* Get PPM capabilities */
+       command = UCSI_GET_CAPABILITY;
+-      ret = ucsi_run_command(ucsi, command, &ucsi->cap, sizeof(ucsi->cap));
++      ret = ucsi_send_command(ucsi, command, &ucsi->cap, sizeof(ucsi->cap));
+       if (ret < 0)
+               goto err_reset;
+@@ -1045,8 +1038,6 @@ int ucsi_init(struct ucsi *ucsi)
+               goto err_reset;
+       }
+-      mutex_unlock(&ucsi->ppm_lock);
+-
+       /* Register all connectors */
+       for (i = 0; i < ucsi->cap.num_connectors; i++) {
+               ret = ucsi_register_port(ucsi, i);
+@@ -1072,12 +1063,9 @@ err_unregister:
+               con->port = NULL;
+       }
+-      mutex_lock(&ucsi->ppm_lock);
+ err_reset:
+       ucsi_reset_ppm(ucsi);
+ err:
+-      mutex_unlock(&ucsi->ppm_lock);
+-
+       return ret;
+ }
+ EXPORT_SYMBOL_GPL(ucsi_init);
diff --git a/queue-5.8/usb-uas-add-quirk-for-pny-pro-elite.patch b/queue-5.8/usb-uas-add-quirk-for-pny-pro-elite.patch
new file mode 100644 (file)
index 0000000..4e87b37
--- /dev/null
@@ -0,0 +1,39 @@
+From 9a469bc9f32dd33c7aac5744669d21a023a719cd Mon Sep 17 00:00:00 2001
+From: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
+Date: Tue, 18 Aug 2020 19:27:47 -0700
+Subject: usb: uas: Add quirk for PNY Pro Elite
+
+From: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
+
+commit 9a469bc9f32dd33c7aac5744669d21a023a719cd upstream.
+
+PNY Pro Elite USB 3.1 Gen 2 device (SSD) doesn't respond to ATA_12
+pass-through command (i.e. it just hangs). If it doesn't support this
+command, it should respond properly to the host. Let's just add a quirk
+to be able to move forward with other operations.
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Thinh Nguyen <thinhn@synopsys.com>
+Link: https://lore.kernel.org/r/2b0585228b003eedcc82db84697b31477df152e0.1597803605.git.thinhn@synopsys.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/storage/unusual_uas.h |    7 +++++++
+ 1 file changed, 7 insertions(+)
+
+--- a/drivers/usb/storage/unusual_uas.h
++++ b/drivers/usb/storage/unusual_uas.h
+@@ -80,6 +80,13 @@ UNUSUAL_DEV(0x152d, 0x0578, 0x0000, 0x99
+               USB_SC_DEVICE, USB_PR_DEVICE, NULL,
+               US_FL_BROKEN_FUA),
++/* Reported-by: Thinh Nguyen <thinhn@synopsys.com> */
++UNUSUAL_DEV(0x154b, 0xf00d, 0x0000, 0x9999,
++              "PNY",
++              "Pro Elite SSD",
++              USB_SC_DEVICE, USB_PR_DEVICE, NULL,
++              US_FL_NO_ATA_1X),
++
+ /* Reported-by: Hans de Goede <hdegoede@redhat.com> */
+ UNUSUAL_DEV(0x2109, 0x0711, 0x0000, 0x9999,
+               "VIA",
diff --git a/queue-5.8/usb-yurex-fix-bad-gfp-argument.patch b/queue-5.8/usb-yurex-fix-bad-gfp-argument.patch
new file mode 100644 (file)
index 0000000..86f97f5
--- /dev/null
@@ -0,0 +1,72 @@
+From f176ede3a3bde5b398a6777a7f9ff091baa2d3ff Mon Sep 17 00:00:00 2001
+From: Alan Stern <stern@rowland.harvard.edu>
+Date: Mon, 10 Aug 2020 14:29:54 -0400
+Subject: USB: yurex: Fix bad gfp argument
+
+From: Alan Stern <stern@rowland.harvard.edu>
+
+commit f176ede3a3bde5b398a6777a7f9ff091baa2d3ff upstream.
+
+The syzbot fuzzer identified a bug in the yurex driver: It passes
+GFP_KERNEL as a memory-allocation flag to usb_submit_urb() at a time
+when its state is TASK_INTERRUPTIBLE, not TASK_RUNNING:
+
+do not call blocking ops when !TASK_RUNNING; state=1 set at [<00000000370c7c68>] prepare_to_wait+0xb1/0x2a0 kernel/sched/wait.c:247
+WARNING: CPU: 1 PID: 340 at kernel/sched/core.c:7253 __might_sleep+0x135/0x190
+kernel/sched/core.c:7253
+Kernel panic - not syncing: panic_on_warn set ...
+CPU: 1 PID: 340 Comm: syz-executor677 Not tainted 5.8.0-syzkaller #0
+Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google
+01/01/2011
+Call Trace:
+ __dump_stack lib/dump_stack.c:77 [inline]
+ dump_stack+0xf6/0x16e lib/dump_stack.c:118
+ panic+0x2aa/0x6e1 kernel/panic.c:231
+ __warn.cold+0x20/0x50 kernel/panic.c:600
+ report_bug+0x1bd/0x210 lib/bug.c:198
+ handle_bug+0x41/0x80 arch/x86/kernel/traps.c:234
+ exc_invalid_op+0x14/0x40 arch/x86/kernel/traps.c:254
+ asm_exc_invalid_op+0x12/0x20 arch/x86/include/asm/idtentry.h:536
+RIP: 0010:__might_sleep+0x135/0x190 kernel/sched/core.c:7253
+Code: 65 48 8b 1c 25 40 ef 01 00 48 8d 7b 10 48 89 fe 48 c1 ee 03 80 3c 06 00 75
+2b 48 8b 73 10 48 c7 c7 e0 9e 06 86 e8 ed 12 f6 ff <0f> 0b e9 46 ff ff ff e8 1f
+b2 4b 00 e9 29 ff ff ff e8 15 b2 4b 00
+RSP: 0018:ffff8881cdb77a28 EFLAGS: 00010282
+RAX: 0000000000000000 RBX: ffff8881c6458000 RCX: 0000000000000000
+RDX: ffff8881c6458000 RSI: ffffffff8129ec93 RDI: ffffed1039b6ef37
+RBP: ffffffff86fdade2 R08: 0000000000000001 R09: ffff8881db32f54f
+R10: 0000000000000000 R11: 0000000030343354 R12: 00000000000001f2
+R13: 0000000000000000 R14: 0000000000000068 R15: ffffffff83c1b1aa
+ slab_pre_alloc_hook.constprop.0+0xea/0x200 mm/slab.h:498
+ slab_alloc_node mm/slub.c:2816 [inline]
+ slab_alloc mm/slub.c:2900 [inline]
+ kmem_cache_alloc_trace+0x46/0x220 mm/slub.c:2917
+ kmalloc include/linux/slab.h:554 [inline]
+ dummy_urb_enqueue+0x7a/0x880 drivers/usb/gadget/udc/dummy_hcd.c:1251
+ usb_hcd_submit_urb+0x2b2/0x22d0 drivers/usb/core/hcd.c:1547
+ usb_submit_urb+0xb4e/0x13e0 drivers/usb/core/urb.c:570
+ yurex_write+0x3ea/0x820 drivers/usb/misc/yurex.c:495
+
+This patch changes the call to use GFP_ATOMIC instead of GFP_KERNEL.
+
+Reported-and-tested-by: syzbot+c2c3302f9c601a4b1be2@syzkaller.appspotmail.com
+Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
+CC: <stable@vger.kernel.org>
+Link: https://lore.kernel.org/r/20200810182954.GB307778@rowland.harvard.edu
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/misc/yurex.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/usb/misc/yurex.c
++++ b/drivers/usb/misc/yurex.c
+@@ -492,7 +492,7 @@ static ssize_t yurex_write(struct file *
+       prepare_to_wait(&dev->waitq, &wait, TASK_INTERRUPTIBLE);
+       dev_dbg(&dev->interface->dev, "%s - submit %c\n", __func__,
+               dev->cntl_buffer[0]);
+-      retval = usb_submit_urb(dev->cntl_urb, GFP_KERNEL);
++      retval = usb_submit_urb(dev->cntl_urb, GFP_ATOMIC);
+       if (retval >= 0)
+               timeout = schedule_timeout(YUREX_WRITE_TIMEOUT);
+       finish_wait(&dev->waitq, &wait);