]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.9-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 3 Nov 2020 14:19:50 +0000 (15:19 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 3 Nov 2020 14:19:50 +0000 (15:19 +0100)
added patches:
drm-i915-force-vt-d-workarounds-when-running-as-a-guest-os.patch
hid-wacom-avoid-entering-wacom_wac_pen_report-for-pad-battery.patch
usb-apple-mfi-fastcharge-don-t-probe-unhandled-devices.patch
usb-cdc-acm-fix-cooldown-mechanism.patch
usb-cdns3-fix-on-chip-memory-overflow-issue.patch
usb-dwc3-core-add-phy-cleanup-for-probe-error-handling.patch
usb-dwc3-core-don-t-trigger-runtime-pm-when-remove-driver.patch
usb-dwc3-ep0-fix-zlp-for-out-ep0-requests.patch
usb-dwc3-gadget-check-mps-of-the-request-length.patch
usb-dwc3-gadget-end_transfer-before-clear_stall-command.patch
usb-dwc3-gadget-reclaim-extra-trbs-after-request-completion.patch
usb-dwc3-gadget-resume-pending-requests-after-clear_stall.patch
usb-dwc3-pci-allow-elkhart-lake-to-utilize-dsm-method-for-pm-functionality.patch
usb-host-fsl-mph-dr-of-check-return-of-dma_set_mask.patch
usb-typec-tcpm-reset-hard_reset_count-for-any-disconnect.patch
usb-xhci-workaround-for-s3-issue-on-amd-snps-3.0-xhc.patch
usbcore-check-both-id_table-and-match-when-both-available.patch
vt-keyboard-extend-func_buf_lock-to-readers.patch
vt-keyboard-simplify-vt_kdgkbsent.patch
vt_ioctl-fix-gio_unimap-regression.patch
x86-mce-allow-for-copy_mc_fragile-symbol-checksum-to-be-generated.patch

22 files changed:
queue-5.9/drm-i915-force-vt-d-workarounds-when-running-as-a-guest-os.patch [new file with mode: 0644]
queue-5.9/hid-wacom-avoid-entering-wacom_wac_pen_report-for-pad-battery.patch [new file with mode: 0644]
queue-5.9/series
queue-5.9/usb-apple-mfi-fastcharge-don-t-probe-unhandled-devices.patch [new file with mode: 0644]
queue-5.9/usb-cdc-acm-fix-cooldown-mechanism.patch [new file with mode: 0644]
queue-5.9/usb-cdns3-fix-on-chip-memory-overflow-issue.patch [new file with mode: 0644]
queue-5.9/usb-dwc3-core-add-phy-cleanup-for-probe-error-handling.patch [new file with mode: 0644]
queue-5.9/usb-dwc3-core-don-t-trigger-runtime-pm-when-remove-driver.patch [new file with mode: 0644]
queue-5.9/usb-dwc3-ep0-fix-zlp-for-out-ep0-requests.patch [new file with mode: 0644]
queue-5.9/usb-dwc3-gadget-check-mps-of-the-request-length.patch [new file with mode: 0644]
queue-5.9/usb-dwc3-gadget-end_transfer-before-clear_stall-command.patch [new file with mode: 0644]
queue-5.9/usb-dwc3-gadget-reclaim-extra-trbs-after-request-completion.patch [new file with mode: 0644]
queue-5.9/usb-dwc3-gadget-resume-pending-requests-after-clear_stall.patch [new file with mode: 0644]
queue-5.9/usb-dwc3-pci-allow-elkhart-lake-to-utilize-dsm-method-for-pm-functionality.patch [new file with mode: 0644]
queue-5.9/usb-host-fsl-mph-dr-of-check-return-of-dma_set_mask.patch [new file with mode: 0644]
queue-5.9/usb-typec-tcpm-reset-hard_reset_count-for-any-disconnect.patch [new file with mode: 0644]
queue-5.9/usb-xhci-workaround-for-s3-issue-on-amd-snps-3.0-xhc.patch [new file with mode: 0644]
queue-5.9/usbcore-check-both-id_table-and-match-when-both-available.patch [new file with mode: 0644]
queue-5.9/vt-keyboard-extend-func_buf_lock-to-readers.patch [new file with mode: 0644]
queue-5.9/vt-keyboard-simplify-vt_kdgkbsent.patch [new file with mode: 0644]
queue-5.9/vt_ioctl-fix-gio_unimap-regression.patch [new file with mode: 0644]
queue-5.9/x86-mce-allow-for-copy_mc_fragile-symbol-checksum-to-be-generated.patch [new file with mode: 0644]

diff --git a/queue-5.9/drm-i915-force-vt-d-workarounds-when-running-as-a-guest-os.patch b/queue-5.9/drm-i915-force-vt-d-workarounds-when-running-as-a-guest-os.patch
new file mode 100644 (file)
index 0000000..1a59267
--- /dev/null
@@ -0,0 +1,55 @@
+From 8195400f7ea95399f721ad21f4d663a62c65036f Mon Sep 17 00:00:00 2001
+From: Chris Wilson <chris@chris-wilson.co.uk>
+Date: Mon, 19 Oct 2020 11:15:23 +0100
+Subject: drm/i915: Force VT'd workarounds when running as a guest OS
+
+From: Chris Wilson <chris@chris-wilson.co.uk>
+
+commit 8195400f7ea95399f721ad21f4d663a62c65036f upstream.
+
+If i915.ko is being used as a passthrough device, it does not know if
+the host is using intel_iommu. Mixing the iommu and gfx causes a few
+issues (such as scanout overfetch) which we need to workaround inside
+the driver, so if we detect we are running under a hypervisor, also
+assume the device access is being virtualised.
+
+Reported-by: Stefan Fritsch <sf@sfritsch.de>
+Suggested-by: Stefan Fritsch <sf@sfritsch.de>
+Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
+Cc: Zhenyu Wang <zhenyuw@linux.intel.com>
+Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
+Cc: Stefan Fritsch <sf@sfritsch.de>
+Cc: stable@vger.kernel.org
+Tested-by: Stefan Fritsch <sf@sfritsch.de>
+Reviewed-by: Zhenyu Wang <zhenyuw@linux.intel.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20201019101523.4145-1-chris@chris-wilson.co.uk
+(cherry picked from commit f566fdcd6cc49a9d5b5d782f56e3e7cb243f01b8)
+Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/i915/i915_drv.h |    6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+--- a/drivers/gpu/drm/i915/i915_drv.h
++++ b/drivers/gpu/drm/i915/i915_drv.h
+@@ -33,6 +33,8 @@
+ #include <uapi/drm/i915_drm.h>
+ #include <uapi/drm/drm_fourcc.h>
++#include <asm/hypervisor.h>
++
+ #include <linux/io-mapping.h>
+ #include <linux/i2c.h>
+ #include <linux/i2c-algo-bit.h>
+@@ -1716,7 +1718,9 @@ static inline bool intel_vtd_active(void
+       if (intel_iommu_gfx_mapped)
+               return true;
+ #endif
+-      return false;
++
++      /* Running as a guest, we assume the host is enforcing VT'd */
++      return !hypervisor_is_type(X86_HYPER_NATIVE);
+ }
+ static inline bool intel_scanout_needs_vtd_wa(struct drm_i915_private *dev_priv)
diff --git a/queue-5.9/hid-wacom-avoid-entering-wacom_wac_pen_report-for-pad-battery.patch b/queue-5.9/hid-wacom-avoid-entering-wacom_wac_pen_report-for-pad-battery.patch
new file mode 100644 (file)
index 0000000..7de8bc3
--- /dev/null
@@ -0,0 +1,61 @@
+From d9216d753b2b1406b801243b12aaf00a5ce5b861 Mon Sep 17 00:00:00 2001
+From: Jason Gerecke <jason.gerecke@wacom.com>
+Date: Wed, 23 Sep 2020 13:14:56 -0700
+Subject: HID: wacom: Avoid entering wacom_wac_pen_report for pad / battery
+
+From: Jason Gerecke <jason.gerecke@wacom.com>
+
+commit d9216d753b2b1406b801243b12aaf00a5ce5b861 upstream.
+
+It has recently been reported that the "heartbeat" report from devices
+like the 2nd-gen Intuos Pro (PTH-460, PTH-660, PTH-860) or the 2nd-gen
+Bluetooth-enabled Intuos tablets (CTL-4100WL, CTL-6100WL) can cause the
+driver to send a spurious BTN_TOUCH=0 once per second in the middle of
+drawing. This can result in broken lines while drawing on Chrome OS.
+
+The source of the issue has been traced back to a change which modified
+the driver to only call `wacom_wac_pad_report()` once per report instead
+of once per collection. As part of this change, pad-handling code was
+removed from `wacom_wac_collection()` under the assumption that the
+`WACOM_PEN_FIELD` and `WACOM_TOUCH_FIELD` checks would not be satisfied
+when a pad or battery collection was being processed.
+
+To be clear, the macros `WACOM_PAD_FIELD` and `WACOM_PEN_FIELD` do not
+currently check exclusive conditions. In fact, most "pad" fields will
+also appear to be "pen" fields simply due to their presence inside of
+a Digitizer application collection. Because of this, the removal of
+the check from `wacom_wac_collection()` just causes pad / battery
+collections to instead trigger a call to `wacom_wac_pen_report()`
+instead. The pen report function in turn resets the tip switch state
+just prior to exiting, resulting in the observed BTN_TOUCH=0 symptom.
+
+To correct this, we restore a version of the `WACOM_PAD_FIELD` check
+in `wacom_wac_collection()` and return early. This effectively prevents
+pad / battery collections from being reported until the very end of the
+report as originally intended.
+
+Fixes: d4b8efeb46d9 ("HID: wacom: generic: Correct pad syncing")
+Cc: stable@vger.kernel.org # v4.17+
+Signed-off-by: Jason Gerecke <jason.gerecke@wacom.com>
+Reviewed-by: Ping Cheng <ping.cheng@wacom.com>
+Tested-by: Ping Cheng <ping.cheng@wacom.com>
+Signed-off-by: Jiri Kosina <jkosina@suse.cz>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/hid/wacom_wac.c |    4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/drivers/hid/wacom_wac.c
++++ b/drivers/hid/wacom_wac.c
+@@ -2773,7 +2773,9 @@ static int wacom_wac_collection(struct h
+       if (report->type != HID_INPUT_REPORT)
+               return -1;
+-      if (WACOM_PEN_FIELD(field) && wacom->wacom_wac.pen_input)
++      if (WACOM_PAD_FIELD(field))
++              return 0;
++      else if (WACOM_PEN_FIELD(field) && wacom->wacom_wac.pen_input)
+               wacom_wac_pen_report(hdev, report);
+       else if (WACOM_FINGER_FIELD(field) && wacom->wacom_wac.touch_input)
+               wacom_wac_finger_report(hdev, report);
index 171954010d4963ff9cb7b98486eccb5dbc5345bb..ece81c8a72d6f96cb2833555fd0123f53653aa0e 100644 (file)
@@ -235,3 +235,24 @@ btrfs-tree-checker-validate-number-of-chunk-stripes-and-parity.patch
 btrfs-fix-use-after-free-on-readahead-extent-after-failure-to-create-it.patch
 btrfs-fix-readahead-hang-and-use-after-free-after-removing-a-device.patch
 btrfs-drop-the-path-before-adding-block-group-sysfs-files.patch
+usb-xhci-workaround-for-s3-issue-on-amd-snps-3.0-xhc.patch
+usb-dwc3-pci-allow-elkhart-lake-to-utilize-dsm-method-for-pm-functionality.patch
+usb-dwc3-ep0-fix-zlp-for-out-ep0-requests.patch
+usb-dwc3-gadget-check-mps-of-the-request-length.patch
+usb-dwc3-gadget-reclaim-extra-trbs-after-request-completion.patch
+usb-dwc3-core-add-phy-cleanup-for-probe-error-handling.patch
+usb-dwc3-core-don-t-trigger-runtime-pm-when-remove-driver.patch
+usb-dwc3-gadget-resume-pending-requests-after-clear_stall.patch
+usb-dwc3-gadget-end_transfer-before-clear_stall-command.patch
+usb-cdns3-fix-on-chip-memory-overflow-issue.patch
+usb-cdc-acm-fix-cooldown-mechanism.patch
+usb-typec-tcpm-reset-hard_reset_count-for-any-disconnect.patch
+usb-host-fsl-mph-dr-of-check-return-of-dma_set_mask.patch
+usbcore-check-both-id_table-and-match-when-both-available.patch
+usb-apple-mfi-fastcharge-don-t-probe-unhandled-devices.patch
+drm-i915-force-vt-d-workarounds-when-running-as-a-guest-os.patch
+vt-keyboard-simplify-vt_kdgkbsent.patch
+vt-keyboard-extend-func_buf_lock-to-readers.patch
+vt_ioctl-fix-gio_unimap-regression.patch
+hid-wacom-avoid-entering-wacom_wac_pen_report-for-pad-battery.patch
+x86-mce-allow-for-copy_mc_fragile-symbol-checksum-to-be-generated.patch
diff --git a/queue-5.9/usb-apple-mfi-fastcharge-don-t-probe-unhandled-devices.patch b/queue-5.9/usb-apple-mfi-fastcharge-don-t-probe-unhandled-devices.patch
new file mode 100644 (file)
index 0000000..c95ab5d
--- /dev/null
@@ -0,0 +1,80 @@
+From 0cb686692fd200db12dcfb8231e793c1c98aec41 Mon Sep 17 00:00:00 2001
+From: Bastien Nocera <hadess@hadess.net>
+Date: Thu, 22 Oct 2020 09:55:21 -0400
+Subject: USB: apple-mfi-fastcharge: don't probe unhandled devices
+
+From: Bastien Nocera <hadess@hadess.net>
+
+commit 0cb686692fd200db12dcfb8231e793c1c98aec41 upstream.
+
+From: Bastien Nocera <hadess@hadess.net>
+
+Contrary to the comment above the id table, we didn't implement a match
+function. This meant that every single Apple device that was already
+plugged in to the computer would have its device driver reprobed
+when the apple-mfi-fastcharge driver was loaded, eg. the SD card reader
+could be reprobed when the apple-mfi-fastcharge after pivoting root
+during boot up and the module became available.
+
+Make sure that the driver probe isn't being run for unsupported
+devices by adding a match function that checks the product ID, in
+addition to the id_table checking the vendor ID.
+
+Link: https://bugzilla.redhat.com/show_bug.cgi?id=1878347
+Link: https://lore.kernel.org/linux-usb/CAE3RAxt0WhBEz8zkHrVO5RiyEOasayy1QUAjsv-pB0fAbY1GSw@mail.gmail.com/
+Fixes: 249fa8217b84 ("USB: Add driver to control USB fast charge for iOS devices")
+Cc: <stable@vger.kernel.org> # 5.8
+Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Cc: Alan Stern <stern@rowland.harvard.edu>
+[m.v.b: Add Link and Reported-by tags to the commit message]
+Reported-by: Pany <pany@fedoraproject.org>
+Tested-by: Pan (Pany) YUAN <pany@fedoraproject.org>
+Tested-by: Bastien Nocera <hadess@hadess.net>
+Signed-off-by: Bastien Nocera <hadess@hadess.net>
+Signed-off-by: M. Vefa Bicakci <m.v.b@runbox.com>
+Link: https://lore.kernel.org/r/20201022135521.375211-3-m.v.b@runbox.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/misc/apple-mfi-fastcharge.c |   17 ++++++++++++-----
+ 1 file changed, 12 insertions(+), 5 deletions(-)
+
+--- a/drivers/usb/misc/apple-mfi-fastcharge.c
++++ b/drivers/usb/misc/apple-mfi-fastcharge.c
+@@ -163,17 +163,23 @@ static const struct power_supply_desc ap
+       .property_is_writeable  = apple_mfi_fc_property_is_writeable
+ };
++static bool mfi_fc_match(struct usb_device *udev)
++{
++      int idProduct;
++
++      idProduct = le16_to_cpu(udev->descriptor.idProduct);
++      /* See comment above mfi_fc_id_table[] */
++      return (idProduct >= 0x1200 && idProduct <= 0x12ff);
++}
++
+ static int mfi_fc_probe(struct usb_device *udev)
+ {
+       struct power_supply_config battery_cfg = {};
+       struct mfi_device *mfi = NULL;
+-      int err, idProduct;
++      int err;
+-      idProduct = le16_to_cpu(udev->descriptor.idProduct);
+-      /* See comment above mfi_fc_id_table[] */
+-      if (idProduct < 0x1200 || idProduct > 0x12ff) {
++      if (!mfi_fc_match(udev))
+               return -ENODEV;
+-      }
+       mfi = kzalloc(sizeof(struct mfi_device), GFP_KERNEL);
+       if (!mfi) {
+@@ -220,6 +226,7 @@ static struct usb_device_driver mfi_fc_d
+       .probe =        mfi_fc_probe,
+       .disconnect =   mfi_fc_disconnect,
+       .id_table =     mfi_fc_id_table,
++      .match =        mfi_fc_match,
+       .generic_subclass = 1,
+ };
diff --git a/queue-5.9/usb-cdc-acm-fix-cooldown-mechanism.patch b/queue-5.9/usb-cdc-acm-fix-cooldown-mechanism.patch
new file mode 100644 (file)
index 0000000..19be0b6
--- /dev/null
@@ -0,0 +1,126 @@
+From 38203b8385bf6283537162bde7d499f830964711 Mon Sep 17 00:00:00 2001
+From: Jerome Brunet <jbrunet@baylibre.com>
+Date: Mon, 19 Oct 2020 19:07:02 +0200
+Subject: usb: cdc-acm: fix cooldown mechanism
+
+From: Jerome Brunet <jbrunet@baylibre.com>
+
+commit 38203b8385bf6283537162bde7d499f830964711 upstream.
+
+Commit a4e7279cd1d1 ("cdc-acm: introduce a cool down") is causing
+regression if there is some USB error, such as -EPROTO.
+
+This has been reported on some samples of the Odroid-N2 using the Combee II
+Zibgee USB dongle.
+
+> struct acm *acm = container_of(work, struct acm, work)
+
+is incorrect in case of a delayed work and causes warnings, usually from
+the workqueue:
+
+> WARNING: CPU: 0 PID: 0 at kernel/workqueue.c:1474 __queue_work+0x480/0x528.
+
+When this happens, USB eventually stops working completely after a while.
+Also the ACM_ERROR_DELAY bit is never set, so the cooldown mechanism
+previously introduced cannot be triggered and acm_submit_read_urb() is
+never called.
+
+This changes makes the cdc-acm driver use a single delayed work, fixing the
+pointer arithmetic in acm_softint() and set the ACM_ERROR_DELAY when the
+cooldown mechanism appear to be needed.
+
+Fixes: a4e7279cd1d1 ("cdc-acm: introduce a cool down")
+Cc: Oliver Neukum <oneukum@suse.com>
+Reported-by: Pascal Vizeli <pascal.vizeli@nabucasa.com>
+Acked-by: Oliver Neukum <oneukum@suse.com>
+Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
+Link: https://lore.kernel.org/r/20201019170702.150534-1-jbrunet@baylibre.com
+Cc: stable <stable@vger.kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/class/cdc-acm.c |   12 +++++-------
+ drivers/usb/class/cdc-acm.h |    3 +--
+ 2 files changed, 6 insertions(+), 9 deletions(-)
+
+--- a/drivers/usb/class/cdc-acm.c
++++ b/drivers/usb/class/cdc-acm.c
+@@ -507,6 +507,7 @@ static void acm_read_bulk_callback(struc
+                       "%s - cooling babbling device\n", __func__);
+               usb_mark_last_busy(acm->dev);
+               set_bit(rb->index, &acm->urbs_in_error_delay);
++              set_bit(ACM_ERROR_DELAY, &acm->flags);
+               cooldown = true;
+               break;
+       default:
+@@ -532,7 +533,7 @@ static void acm_read_bulk_callback(struc
+       if (stopped || stalled || cooldown) {
+               if (stalled)
+-                      schedule_work(&acm->work);
++                      schedule_delayed_work(&acm->dwork, 0);
+               else if (cooldown)
+                       schedule_delayed_work(&acm->dwork, HZ / 2);
+               return;
+@@ -562,13 +563,13 @@ static void acm_write_bulk(struct urb *u
+       acm_write_done(acm, wb);
+       spin_unlock_irqrestore(&acm->write_lock, flags);
+       set_bit(EVENT_TTY_WAKEUP, &acm->flags);
+-      schedule_work(&acm->work);
++      schedule_delayed_work(&acm->dwork, 0);
+ }
+ static void acm_softint(struct work_struct *work)
+ {
+       int i;
+-      struct acm *acm = container_of(work, struct acm, work);
++      struct acm *acm = container_of(work, struct acm, dwork.work);
+       if (test_bit(EVENT_RX_STALL, &acm->flags)) {
+               smp_mb(); /* against acm_suspend() */
+@@ -584,7 +585,7 @@ static void acm_softint(struct work_stru
+       if (test_and_clear_bit(ACM_ERROR_DELAY, &acm->flags)) {
+               for (i = 0; i < acm->rx_buflimit; i++)
+                       if (test_and_clear_bit(i, &acm->urbs_in_error_delay))
+-                                      acm_submit_read_urb(acm, i, GFP_NOIO);
++                              acm_submit_read_urb(acm, i, GFP_KERNEL);
+       }
+       if (test_and_clear_bit(EVENT_TTY_WAKEUP, &acm->flags))
+@@ -1364,7 +1365,6 @@ made_compressed_probe:
+       acm->ctrlsize = ctrlsize;
+       acm->readsize = readsize;
+       acm->rx_buflimit = num_rx_buf;
+-      INIT_WORK(&acm->work, acm_softint);
+       INIT_DELAYED_WORK(&acm->dwork, acm_softint);
+       init_waitqueue_head(&acm->wioctl);
+       spin_lock_init(&acm->write_lock);
+@@ -1574,7 +1574,6 @@ static void acm_disconnect(struct usb_in
+       }
+       acm_kill_urbs(acm);
+-      cancel_work_sync(&acm->work);
+       cancel_delayed_work_sync(&acm->dwork);
+       tty_unregister_device(acm_tty_driver, acm->minor);
+@@ -1617,7 +1616,6 @@ static int acm_suspend(struct usb_interf
+               return 0;
+       acm_kill_urbs(acm);
+-      cancel_work_sync(&acm->work);
+       cancel_delayed_work_sync(&acm->dwork);
+       acm->urbs_in_error_delay = 0;
+--- a/drivers/usb/class/cdc-acm.h
++++ b/drivers/usb/class/cdc-acm.h
+@@ -112,8 +112,7 @@ struct acm {
+ #             define ACM_ERROR_DELAY  3
+       unsigned long urbs_in_error_delay;              /* these need to be restarted after a delay */
+       struct usb_cdc_line_coding line;                /* bits, stop, parity */
+-      struct work_struct work;                        /* work queue entry for various purposes*/
+-      struct delayed_work dwork;                      /* for cool downs needed in error recovery */
++      struct delayed_work dwork;                      /* work queue entry for various purposes */
+       unsigned int ctrlin;                            /* input control lines (DCD, DSR, RI, break, overruns) */
+       unsigned int ctrlout;                           /* output control lines (DTR, RTS) */
+       struct async_icount iocount;                    /* counters for control line changes */
diff --git a/queue-5.9/usb-cdns3-fix-on-chip-memory-overflow-issue.patch b/queue-5.9/usb-cdns3-fix-on-chip-memory-overflow-issue.patch
new file mode 100644 (file)
index 0000000..80f6b4f
--- /dev/null
@@ -0,0 +1,367 @@
+From 52d3967704aea6cb316d419a33a5e1d56d33a3c1 Mon Sep 17 00:00:00 2001
+From: Pawel Laszczak <pawell@cadence.com>
+Date: Thu, 22 Oct 2020 08:55:05 +0800
+Subject: usb: cdns3: Fix on-chip memory overflow issue
+
+From: Pawel Laszczak <pawell@cadence.com>
+
+commit 52d3967704aea6cb316d419a33a5e1d56d33a3c1 upstream.
+
+Patch fixes issue caused setting On-chip memory overflow bit in usb_sts
+register. The issue occurred because EP_CFG register was set twice
+before USB_STS.CFGSTS was set. Every write operation on EP_CFG.BUFFERING
+causes that controller increases internal counter holding the number
+of reserved on-chip buffers. First time this register was updated in
+function cdns3_ep_config before delegating SET_CONFIGURATION request
+to class driver and again it was updated when class wanted to enable
+endpoint.  This patch fixes this issue by configuring endpoints
+enabled by class driver in cdns3_gadget_ep_enable and others just
+before status stage.
+
+Cc: stable@vger.kernel.org#v5.8+
+Fixes: 7733f6c32e36 ("usb: cdns3: Add Cadence USB3 DRD Driver")
+Reported-and-tested-by: Peter Chen <peter.chen@nxp.com>
+Signed-off-by: Pawel Laszczak <pawell@cadence.com>
+Signed-off-by: Peter Chen <peter.chen@nxp.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/cdns3/ep0.c    |   65 +++++++++++++++-------------
+ drivers/usb/cdns3/gadget.c |  102 +++++++++++++++++++++++++--------------------
+ drivers/usb/cdns3/gadget.h |    3 -
+ 3 files changed, 94 insertions(+), 76 deletions(-)
+
+--- a/drivers/usb/cdns3/ep0.c
++++ b/drivers/usb/cdns3/ep0.c
+@@ -137,48 +137,36 @@ static int cdns3_req_ep0_set_configurati
+                                          struct usb_ctrlrequest *ctrl_req)
+ {
+       enum usb_device_state device_state = priv_dev->gadget.state;
+-      struct cdns3_endpoint *priv_ep;
+       u32 config = le16_to_cpu(ctrl_req->wValue);
+       int result = 0;
+-      int i;
+       switch (device_state) {
+       case USB_STATE_ADDRESS:
+-              /* Configure non-control EPs */
+-              for (i = 0; i < CDNS3_ENDPOINTS_MAX_COUNT; i++) {
+-                      priv_ep = priv_dev->eps[i];
+-                      if (!priv_ep)
+-                              continue;
+-
+-                      if (priv_ep->flags & EP_CLAIMED)
+-                              cdns3_ep_config(priv_ep);
+-              }
+-
+               result = cdns3_ep0_delegate_req(priv_dev, ctrl_req);
+-              if (result)
+-                      return result;
+-
+-              if (!config) {
+-                      cdns3_hw_reset_eps_config(priv_dev);
+-                      usb_gadget_set_state(&priv_dev->gadget,
+-                                           USB_STATE_ADDRESS);
+-              }
++              if (result || !config)
++                      goto reset_config;
+               break;
+       case USB_STATE_CONFIGURED:
+               result = cdns3_ep0_delegate_req(priv_dev, ctrl_req);
++              if (!config && !result)
++                      goto reset_config;
+-              if (!config && !result) {
+-                      cdns3_hw_reset_eps_config(priv_dev);
+-                      usb_gadget_set_state(&priv_dev->gadget,
+-                                           USB_STATE_ADDRESS);
+-              }
+               break;
+       default:
+-              result = -EINVAL;
++              return -EINVAL;
+       }
++      return 0;
++
++reset_config:
++      if (result != USB_GADGET_DELAYED_STATUS)
++              cdns3_hw_reset_eps_config(priv_dev);
++
++      usb_gadget_set_state(&priv_dev->gadget,
++                           USB_STATE_ADDRESS);
++
+       return result;
+ }
+@@ -705,6 +693,7 @@ static int cdns3_gadget_ep0_queue(struct
+       unsigned long flags;
+       int ret = 0;
+       u8 zlp = 0;
++      int i;
+       spin_lock_irqsave(&priv_dev->lock, flags);
+       trace_cdns3_ep0_queue(priv_dev, request);
+@@ -718,6 +707,17 @@ static int cdns3_gadget_ep0_queue(struct
+       /* send STATUS stage. Should be called only for SET_CONFIGURATION */
+       if (priv_dev->ep0_stage == CDNS3_STATUS_STAGE) {
+               cdns3_select_ep(priv_dev, 0x00);
++
++              /*
++               * Configure all non-control EPs which are not enabled by class driver
++               */
++              for (i = 0; i < CDNS3_ENDPOINTS_MAX_COUNT; i++) {
++                      priv_ep = priv_dev->eps[i];
++                      if (priv_ep && priv_ep->flags & EP_CLAIMED &&
++                          !(priv_ep->flags & EP_ENABLED))
++                              cdns3_ep_config(priv_ep, 0);
++              }
++
+               cdns3_set_hw_configuration(priv_dev);
+               cdns3_ep0_complete_setup(priv_dev, 0, 1);
+               request->actual = 0;
+@@ -803,6 +803,7 @@ void cdns3_ep0_config(struct cdns3_devic
+       struct cdns3_usb_regs __iomem *regs;
+       struct cdns3_endpoint *priv_ep;
+       u32 max_packet_size = 64;
++      u32 ep_cfg;
+       regs = priv_dev->regs;
+@@ -834,8 +835,10 @@ void cdns3_ep0_config(struct cdns3_devic
+                                      BIT(0) | BIT(16));
+       }
+-      writel(EP_CFG_ENABLE | EP_CFG_MAXPKTSIZE(max_packet_size),
+-             &regs->ep_cfg);
++      ep_cfg = EP_CFG_ENABLE | EP_CFG_MAXPKTSIZE(max_packet_size);
++
++      if (!(priv_ep->flags & EP_CONFIGURED))
++              writel(ep_cfg, &regs->ep_cfg);
+       writel(EP_STS_EN_SETUPEN | EP_STS_EN_DESCMISEN | EP_STS_EN_TRBERREN,
+              &regs->ep_sts_en);
+@@ -843,8 +846,10 @@ void cdns3_ep0_config(struct cdns3_devic
+       /* init ep in */
+       cdns3_select_ep(priv_dev, USB_DIR_IN);
+-      writel(EP_CFG_ENABLE | EP_CFG_MAXPKTSIZE(max_packet_size),
+-             &regs->ep_cfg);
++      if (!(priv_ep->flags & EP_CONFIGURED))
++              writel(ep_cfg, &regs->ep_cfg);
++
++      priv_ep->flags |= EP_CONFIGURED;
+       writel(EP_STS_EN_SETUPEN | EP_STS_EN_TRBERREN, &regs->ep_sts_en);
+--- a/drivers/usb/cdns3/gadget.c
++++ b/drivers/usb/cdns3/gadget.c
+@@ -296,6 +296,8 @@ static void cdns3_ep_stall_flush(struct
+  */
+ void cdns3_hw_reset_eps_config(struct cdns3_device *priv_dev)
+ {
++      int i;
++
+       writel(USB_CONF_CFGRST, &priv_dev->regs->usb_conf);
+       cdns3_allow_enable_l1(priv_dev, 0);
+@@ -304,6 +306,10 @@ void cdns3_hw_reset_eps_config(struct cd
+       priv_dev->out_mem_is_allocated = 0;
+       priv_dev->wait_for_setup = 0;
+       priv_dev->using_streams = 0;
++
++      for (i = 0; i < CDNS3_ENDPOINTS_MAX_COUNT; i++)
++              if (priv_dev->eps[i])
++                      priv_dev->eps[i]->flags &= ~EP_CONFIGURED;
+ }
+ /**
+@@ -1907,27 +1913,6 @@ static int cdns3_ep_onchip_buffer_reserv
+       return 0;
+ }
+-static void cdns3_stream_ep_reconfig(struct cdns3_device *priv_dev,
+-                                   struct cdns3_endpoint *priv_ep)
+-{
+-      if (!priv_ep->use_streams || priv_dev->gadget.speed < USB_SPEED_SUPER)
+-              return;
+-
+-      if (priv_dev->dev_ver >= DEV_VER_V3) {
+-              u32 mask = BIT(priv_ep->num + (priv_ep->dir ? 16 : 0));
+-
+-              /*
+-               * Stream capable endpoints are handled by using ep_tdl
+-               * register. Other endpoints use TDL from TRB feature.
+-               */
+-              cdns3_clear_register_bit(&priv_dev->regs->tdl_from_trb, mask);
+-      }
+-
+-      /*  Enable Stream Bit TDL chk and SID chk */
+-      cdns3_set_register_bit(&priv_dev->regs->ep_cfg, EP_CFG_STREAM_EN |
+-                             EP_CFG_TDL_CHK | EP_CFG_SID_CHK);
+-}
+-
+ static void cdns3_configure_dmult(struct cdns3_device *priv_dev,
+                                 struct cdns3_endpoint *priv_ep)
+ {
+@@ -1965,8 +1950,9 @@ static void cdns3_configure_dmult(struct
+ /**
+  * cdns3_ep_config Configure hardware endpoint
+  * @priv_ep: extended endpoint object
++ * @enable: set EP_CFG_ENABLE bit in ep_cfg register.
+  */
+-void cdns3_ep_config(struct cdns3_endpoint *priv_ep)
++int cdns3_ep_config(struct cdns3_endpoint *priv_ep, bool enable)
+ {
+       bool is_iso_ep = (priv_ep->type == USB_ENDPOINT_XFER_ISOC);
+       struct cdns3_device *priv_dev = priv_ep->cdns3_dev;
+@@ -2027,7 +2013,7 @@ void cdns3_ep_config(struct cdns3_endpoi
+               break;
+       default:
+               /* all other speed are not supported */
+-              return;
++              return -EINVAL;
+       }
+       if (max_packet_size == 1024)
+@@ -2037,11 +2023,33 @@ void cdns3_ep_config(struct cdns3_endpoi
+       else
+               priv_ep->trb_burst_size = 16;
+-      ret = cdns3_ep_onchip_buffer_reserve(priv_dev, buffering + 1,
+-                                           !!priv_ep->dir);
+-      if (ret) {
+-              dev_err(priv_dev->dev, "onchip mem is full, ep is invalid\n");
+-              return;
++      /* onchip buffer is only allocated before configuration */
++      if (!priv_dev->hw_configured_flag) {
++              ret = cdns3_ep_onchip_buffer_reserve(priv_dev, buffering + 1,
++                                                   !!priv_ep->dir);
++              if (ret) {
++                      dev_err(priv_dev->dev, "onchip mem is full, ep is invalid\n");
++                      return ret;
++              }
++      }
++
++      if (enable)
++              ep_cfg |= EP_CFG_ENABLE;
++
++      if (priv_ep->use_streams && priv_dev->gadget.speed >= USB_SPEED_SUPER) {
++              if (priv_dev->dev_ver >= DEV_VER_V3) {
++                      u32 mask = BIT(priv_ep->num + (priv_ep->dir ? 16 : 0));
++
++                      /*
++                       * Stream capable endpoints are handled by using ep_tdl
++                       * register. Other endpoints use TDL from TRB feature.
++                       */
++                      cdns3_clear_register_bit(&priv_dev->regs->tdl_from_trb,
++                                               mask);
++              }
++
++              /*  Enable Stream Bit TDL chk and SID chk */
++              ep_cfg |=  EP_CFG_STREAM_EN | EP_CFG_TDL_CHK | EP_CFG_SID_CHK;
+       }
+       ep_cfg |= EP_CFG_MAXPKTSIZE(max_packet_size) |
+@@ -2051,9 +2059,12 @@ void cdns3_ep_config(struct cdns3_endpoi
+       cdns3_select_ep(priv_dev, bEndpointAddress);
+       writel(ep_cfg, &priv_dev->regs->ep_cfg);
++      priv_ep->flags |= EP_CONFIGURED;
+       dev_dbg(priv_dev->dev, "Configure %s: with val %08x\n",
+               priv_ep->name, ep_cfg);
++
++      return 0;
+ }
+ /* Find correct direction for HW endpoint according to description */
+@@ -2194,7 +2205,7 @@ static int cdns3_gadget_ep_enable(struct
+       u32 bEndpointAddress;
+       unsigned long flags;
+       int enable = 1;
+-      int ret;
++      int ret = 0;
+       int val;
+       priv_ep = ep_to_cdns3_ep(ep);
+@@ -2233,6 +2244,17 @@ static int cdns3_gadget_ep_enable(struct
+       bEndpointAddress = priv_ep->num | priv_ep->dir;
+       cdns3_select_ep(priv_dev, bEndpointAddress);
++      /*
++       * For some versions of controller at some point during ISO OUT traffic
++       * DMA reads Transfer Ring for the EP which has never got doorbell.
++       * This issue was detected only on simulation, but to avoid this issue
++       * driver add protection against it. To fix it driver enable ISO OUT
++       * endpoint before setting DRBL. This special treatment of ISO OUT
++       * endpoints are recommended by controller specification.
++       */
++      if (priv_ep->type == USB_ENDPOINT_XFER_ISOC  && !priv_ep->dir)
++              enable = 0;
++
+       if (usb_ss_max_streams(comp_desc) && usb_endpoint_xfer_bulk(desc)) {
+               /*
+                * Enable stream support (SS mode) related interrupts
+@@ -2243,13 +2265,17 @@ static int cdns3_gadget_ep_enable(struct
+                               EP_STS_EN_SIDERREN | EP_STS_EN_MD_EXITEN |
+                               EP_STS_EN_STREAMREN;
+                       priv_ep->use_streams = true;
+-                      cdns3_stream_ep_reconfig(priv_dev, priv_ep);
++                      ret = cdns3_ep_config(priv_ep, enable);
+                       priv_dev->using_streams |= true;
+               }
++      } else {
++              ret = cdns3_ep_config(priv_ep, enable);
+       }
+-      ret = cdns3_allocate_trb_pool(priv_ep);
++      if (ret)
++              goto exit;
++      ret = cdns3_allocate_trb_pool(priv_ep);
+       if (ret)
+               goto exit;
+@@ -2279,20 +2305,6 @@ static int cdns3_gadget_ep_enable(struct
+       writel(reg, &priv_dev->regs->ep_sts_en);
+-      /*
+-       * For some versions of controller at some point during ISO OUT traffic
+-       * DMA reads Transfer Ring for the EP which has never got doorbell.
+-       * This issue was detected only on simulation, but to avoid this issue
+-       * driver add protection against it. To fix it driver enable ISO OUT
+-       * endpoint before setting DRBL. This special treatment of ISO OUT
+-       * endpoints are recommended by controller specification.
+-       */
+-      if (priv_ep->type == USB_ENDPOINT_XFER_ISOC  && !priv_ep->dir)
+-              enable = 0;
+-
+-      if (enable)
+-              cdns3_set_register_bit(&priv_dev->regs->ep_cfg, EP_CFG_ENABLE);
+-
+       ep->desc = desc;
+       priv_ep->flags &= ~(EP_PENDING_REQUEST | EP_STALLED | EP_STALL_PENDING |
+                           EP_QUIRK_ISO_OUT_EN | EP_QUIRK_EXTRA_BUF_EN);
+--- a/drivers/usb/cdns3/gadget.h
++++ b/drivers/usb/cdns3/gadget.h
+@@ -1154,6 +1154,7 @@ struct cdns3_endpoint {
+ #define EP_QUIRK_EXTRA_BUF_DET        BIT(12)
+ #define EP_QUIRK_EXTRA_BUF_EN BIT(13)
+ #define EP_TDLCHK_EN          BIT(15)
++#define EP_CONFIGURED         BIT(16)
+       u32                     flags;
+       struct cdns3_request    *descmis_req;
+@@ -1351,7 +1352,7 @@ void cdns3_gadget_giveback(struct cdns3_
+ int cdns3_init_ep0(struct cdns3_device *priv_dev,
+                  struct cdns3_endpoint *priv_ep);
+ void cdns3_ep0_config(struct cdns3_device *priv_dev);
+-void cdns3_ep_config(struct cdns3_endpoint *priv_ep);
++int cdns3_ep_config(struct cdns3_endpoint *priv_ep, bool enable);
+ void cdns3_check_ep0_interrupt_proceed(struct cdns3_device *priv_dev, int dir);
+ int __cdns3_gadget_wakeup(struct cdns3_device *priv_dev);
diff --git a/queue-5.9/usb-dwc3-core-add-phy-cleanup-for-probe-error-handling.patch b/queue-5.9/usb-dwc3-core-add-phy-cleanup-for-probe-error-handling.patch
new file mode 100644 (file)
index 0000000..1f2c9d3
--- /dev/null
@@ -0,0 +1,42 @@
+From 03c1fd622f72c7624c81b64fdba4a567ae5ee9cb Mon Sep 17 00:00:00 2001
+From: Li Jun <jun.li@nxp.com>
+Date: Tue, 28 Jul 2020 20:42:41 +0800
+Subject: usb: dwc3: core: add phy cleanup for probe error handling
+
+From: Li Jun <jun.li@nxp.com>
+
+commit 03c1fd622f72c7624c81b64fdba4a567ae5ee9cb upstream.
+
+Add the phy cleanup if dwc3 mode init fail, which is the missing part of
+de-init for dwc3 core init.
+
+Fixes: c499ff71ff2a ("usb: dwc3: core: re-factor init and exit paths")
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Li Jun <jun.li@nxp.com>
+Signed-off-by: Felipe Balbi <balbi@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/dwc3/core.c |   11 +++++++++++
+ 1 file changed, 11 insertions(+)
+
+--- a/drivers/usb/dwc3/core.c
++++ b/drivers/usb/dwc3/core.c
+@@ -1564,6 +1564,17 @@ static int dwc3_probe(struct platform_de
+ err5:
+       dwc3_event_buffers_cleanup(dwc);
++
++      usb_phy_shutdown(dwc->usb2_phy);
++      usb_phy_shutdown(dwc->usb3_phy);
++      phy_exit(dwc->usb2_generic_phy);
++      phy_exit(dwc->usb3_generic_phy);
++
++      usb_phy_set_suspend(dwc->usb2_phy, 1);
++      usb_phy_set_suspend(dwc->usb3_phy, 1);
++      phy_power_off(dwc->usb2_generic_phy);
++      phy_power_off(dwc->usb3_generic_phy);
++
+       dwc3_ulpi_exit(dwc);
+ err4:
diff --git a/queue-5.9/usb-dwc3-core-don-t-trigger-runtime-pm-when-remove-driver.patch b/queue-5.9/usb-dwc3-core-don-t-trigger-runtime-pm-when-remove-driver.patch
new file mode 100644 (file)
index 0000000..b5470b8
--- /dev/null
@@ -0,0 +1,106 @@
+From 266d0493900ac5d6a21cdbe6b1624ed2da94d47a Mon Sep 17 00:00:00 2001
+From: Li Jun <jun.li@nxp.com>
+Date: Tue, 28 Jul 2020 20:42:40 +0800
+Subject: usb: dwc3: core: don't trigger runtime pm when remove driver
+
+From: Li Jun <jun.li@nxp.com>
+
+commit 266d0493900ac5d6a21cdbe6b1624ed2da94d47a upstream.
+
+No need to trigger runtime pm in driver removal, otherwise if user
+disable auto suspend via sys file, runtime suspend may be entered,
+which will call dwc3_core_exit() again and there will be clock disable
+not balance warning:
+
+[ 2026.820154] xhci-hcd xhci-hcd.0.auto: remove, state 4
+[ 2026.825268] usb usb2: USB disconnect, device number 1
+[ 2026.831017] xhci-hcd xhci-hcd.0.auto: USB bus 2 deregistered
+[ 2026.836806] xhci-hcd xhci-hcd.0.auto: remove, state 4
+[ 2026.842029] usb usb1: USB disconnect, device number 1
+[ 2026.848029] xhci-hcd xhci-hcd.0.auto: USB bus 1 deregistered
+[ 2026.865889] ------------[ cut here ]------------
+[ 2026.870506] usb2_ctrl_root_clk already disabled
+[ 2026.875082] WARNING: CPU: 0 PID: 731 at drivers/clk/clk.c:958
+clk_core_disable+0xa0/0xa8
+[ 2026.883170] Modules linked in: dwc3(-) phy_fsl_imx8mq_usb [last
+unloaded: dwc3]
+[ 2026.890488] CPU: 0 PID: 731 Comm: rmmod Not tainted
+5.8.0-rc7-00280-g9d08cca-dirty #245
+[ 2026.898489] Hardware name: NXP i.MX8MQ EVK (DT)
+[ 2026.903020] pstate: 20000085 (nzCv daIf -PAN -UAO BTYPE=--)
+[ 2026.908594] pc : clk_core_disable+0xa0/0xa8
+[ 2026.912777] lr : clk_core_disable+0xa0/0xa8
+[ 2026.916958] sp : ffff8000121b39a0
+[ 2026.920271] x29: ffff8000121b39a0 x28: ffff0000b11f3700
+[ 2026.925583] x27: 0000000000000000 x26: ffff0000b539c700
+[ 2026.930895] x25: 000001d7e44e1232 x24: ffff0000b76fa800
+[ 2026.936208] x23: ffff0000b76fa6f8 x22: ffff800008d01040
+[ 2026.941520] x21: ffff0000b539ce00 x20: ffff0000b7105000
+[ 2026.946832] x19: ffff0000b7105000 x18: 0000000000000010
+[ 2026.952144] x17: 0000000000000001 x16: 0000000000000000
+[ 2026.957456] x15: ffff0000b11f3b70 x14: ffffffffffffffff
+[ 2026.962768] x13: ffff8000921b36f7 x12: ffff8000121b36ff
+[ 2026.968080] x11: ffff8000119e1000 x10: ffff800011bf26d0
+[ 2026.973392] x9 : 0000000000000000 x8 : ffff800011bf3000
+[ 2026.978704] x7 : ffff800010695d68 x6 : 0000000000000252
+[ 2026.984016] x5 : ffff0000bb9881f0 x4 : 0000000000000000
+[ 2026.989327] x3 : 0000000000000027 x2 : 0000000000000023
+[ 2026.994639] x1 : ac2fa471aa7cab00 x0 : 0000000000000000
+[ 2026.999951] Call trace:
+[ 2027.002401]  clk_core_disable+0xa0/0xa8
+[ 2027.006238]  clk_core_disable_lock+0x20/0x38
+[ 2027.010508]  clk_disable+0x1c/0x28
+[ 2027.013911]  clk_bulk_disable+0x34/0x50
+[ 2027.017758]  dwc3_core_exit+0xec/0x110 [dwc3]
+[ 2027.022122]  dwc3_suspend_common+0x84/0x188 [dwc3]
+[ 2027.026919]  dwc3_runtime_suspend+0x74/0x9c [dwc3]
+[ 2027.031712]  pm_generic_runtime_suspend+0x28/0x40
+[ 2027.036419]  genpd_runtime_suspend+0xa0/0x258
+[ 2027.040777]  __rpm_callback+0x88/0x140
+[ 2027.044526]  rpm_callback+0x20/0x80
+[ 2027.048015]  rpm_suspend+0xd0/0x418
+[ 2027.051503]  __pm_runtime_suspend+0x58/0xa0
+[ 2027.055693]  dwc3_runtime_idle+0x7c/0x90 [dwc3]
+[ 2027.060224]  __rpm_callback+0x88/0x140
+[ 2027.063973]  rpm_idle+0x78/0x150
+[ 2027.067201]  __pm_runtime_idle+0x58/0xa0
+[ 2027.071130]  dwc3_remove+0x64/0xc0 [dwc3]
+[ 2027.075140]  platform_drv_remove+0x28/0x48
+[ 2027.079239]  device_release_driver_internal+0xf4/0x1c0
+[ 2027.084377]  driver_detach+0x4c/0xd8
+[ 2027.087954]  bus_remove_driver+0x54/0xa8
+[ 2027.091877]  driver_unregister+0x2c/0x58
+[ 2027.095799]  platform_driver_unregister+0x10/0x18
+[ 2027.100509]  dwc3_driver_exit+0x14/0x1408 [dwc3]
+[ 2027.105129]  __arm64_sys_delete_module+0x178/0x218
+[ 2027.109922]  el0_svc_common.constprop.0+0x68/0x160
+[ 2027.114714]  do_el0_svc+0x20/0x80
+[ 2027.118031]  el0_sync_handler+0x88/0x190
+[ 2027.121953]  el0_sync+0x140/0x180
+[ 2027.125267] ---[ end trace 027f4f8189958f1f ]---
+[ 2027.129976] ------------[ cut here ]------------
+
+Fixes: fc8bb91bc83e ("usb: dwc3: implement runtime PM")
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Li Jun <jun.li@nxp.com>
+Signed-off-by: Felipe Balbi <balbi@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/dwc3/core.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/usb/dwc3/core.c
++++ b/drivers/usb/dwc3/core.c
+@@ -1610,9 +1610,9 @@ static int dwc3_remove(struct platform_d
+       dwc3_core_exit(dwc);
+       dwc3_ulpi_exit(dwc);
+-      pm_runtime_put_sync(&pdev->dev);
+-      pm_runtime_allow(&pdev->dev);
+       pm_runtime_disable(&pdev->dev);
++      pm_runtime_put_noidle(&pdev->dev);
++      pm_runtime_set_suspended(&pdev->dev);
+       dwc3_free_event_buffers(dwc);
+       dwc3_free_scratch_buffers(dwc);
diff --git a/queue-5.9/usb-dwc3-ep0-fix-zlp-for-out-ep0-requests.patch b/queue-5.9/usb-dwc3-ep0-fix-zlp-for-out-ep0-requests.patch
new file mode 100644 (file)
index 0000000..705aae7
--- /dev/null
@@ -0,0 +1,63 @@
+From 66706077dc89c66a4777a4c6298273816afb848c Mon Sep 17 00:00:00 2001
+From: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
+Date: Thu, 24 Sep 2020 01:21:43 -0700
+Subject: usb: dwc3: ep0: Fix ZLP for OUT ep0 requests
+
+From: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
+
+commit 66706077dc89c66a4777a4c6298273816afb848c upstream.
+
+The current ZLP handling for ep0 requests is only for control IN
+requests. For OUT direction, DWC3 needs to check and setup for MPS
+alignment.
+
+Usually, control OUT requests can indicate its transfer size via the
+wLength field of the control message. So usb_request->zero is usually
+not needed for OUT direction. To handle ZLP OUT for control endpoint,
+make sure the TRB is MPS size.
+
+Cc: stable@vger.kernel.org
+Fixes: c7fcdeb2627c ("usb: dwc3: ep0: simplify EP0 state machine")
+Fixes: d6e5a549cc4d ("usb: dwc3: simplify ZLP handling")
+Signed-off-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
+Signed-off-by: Felipe Balbi <balbi@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/dwc3/ep0.c |   11 +++++++++--
+ 1 file changed, 9 insertions(+), 2 deletions(-)
+
+--- a/drivers/usb/dwc3/ep0.c
++++ b/drivers/usb/dwc3/ep0.c
+@@ -942,12 +942,16 @@ static void dwc3_ep0_xfer_complete(struc
+ static void __dwc3_ep0_do_control_data(struct dwc3 *dwc,
+               struct dwc3_ep *dep, struct dwc3_request *req)
+ {
++      unsigned int            trb_length = 0;
+       int                     ret;
+       req->direction = !!dep->number;
+       if (req->request.length == 0) {
+-              dwc3_ep0_prepare_one_trb(dep, dwc->ep0_trb_addr, 0,
++              if (!req->direction)
++                      trb_length = dep->endpoint.maxpacket;
++
++              dwc3_ep0_prepare_one_trb(dep, dwc->bounce_addr, trb_length,
+                               DWC3_TRBCTL_CONTROL_DATA, false);
+               ret = dwc3_ep0_start_trans(dep);
+       } else if (!IS_ALIGNED(req->request.length, dep->endpoint.maxpacket)
+@@ -994,9 +998,12 @@ static void __dwc3_ep0_do_control_data(s
+               req->trb = &dwc->ep0_trb[dep->trb_enqueue - 1];
++              if (!req->direction)
++                      trb_length = dep->endpoint.maxpacket;
++
+               /* Now prepare one extra TRB to align transfer size */
+               dwc3_ep0_prepare_one_trb(dep, dwc->bounce_addr,
+-                                       0, DWC3_TRBCTL_CONTROL_DATA,
++                                       trb_length, DWC3_TRBCTL_CONTROL_DATA,
+                                        false);
+               ret = dwc3_ep0_start_trans(dep);
+       } else {
diff --git a/queue-5.9/usb-dwc3-gadget-check-mps-of-the-request-length.patch b/queue-5.9/usb-dwc3-gadget-check-mps-of-the-request-length.patch
new file mode 100644 (file)
index 0000000..ad9a4ac
--- /dev/null
@@ -0,0 +1,43 @@
+From ca3df3468eec87f6374662f7de425bc44c3810c1 Mon Sep 17 00:00:00 2001
+From: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
+Date: Thu, 24 Sep 2020 01:21:18 -0700
+Subject: usb: dwc3: gadget: Check MPS of the request length
+
+From: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
+
+commit ca3df3468eec87f6374662f7de425bc44c3810c1 upstream.
+
+When preparing for SG, not all the entries are prepared at once. When
+resume, don't use the remaining request length to calculate for MPS
+alignment. Use the entire request->length to do that.
+
+Cc: stable@vger.kernel.org
+Fixes: 5d187c0454ef ("usb: dwc3: gadget: Don't setup more than requested")
+Signed-off-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
+Signed-off-by: Felipe Balbi <balbi@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/dwc3/gadget.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/usb/dwc3/gadget.c
++++ b/drivers/usb/dwc3/gadget.c
+@@ -1095,6 +1095,8 @@ static void dwc3_prepare_one_trb_sg(stru
+       struct scatterlist *s;
+       int             i;
+       unsigned int length = req->request.length;
++      unsigned int maxp = usb_endpoint_maxp(dep->endpoint.desc);
++      unsigned int rem = length % maxp;
+       unsigned int remaining = req->request.num_mapped_sgs
+               - req->num_queued_sgs;
+@@ -1106,8 +1108,6 @@ static void dwc3_prepare_one_trb_sg(stru
+               length -= sg_dma_len(s);
+       for_each_sg(sg, s, remaining, i) {
+-              unsigned int maxp = usb_endpoint_maxp(dep->endpoint.desc);
+-              unsigned int rem = length % maxp;
+               unsigned int trb_length;
+               unsigned chain = true;
diff --git a/queue-5.9/usb-dwc3-gadget-end_transfer-before-clear_stall-command.patch b/queue-5.9/usb-dwc3-gadget-end_transfer-before-clear_stall-command.patch
new file mode 100644 (file)
index 0000000..44957c8
--- /dev/null
@@ -0,0 +1,145 @@
+From d97c78a1908e59a1fdbcbece87cd0440b5d7a1f2 Mon Sep 17 00:00:00 2001
+From: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
+Date: Wed, 2 Sep 2020 18:43:04 -0700
+Subject: usb: dwc3: gadget: END_TRANSFER before CLEAR_STALL command
+
+From: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
+
+commit d97c78a1908e59a1fdbcbece87cd0440b5d7a1f2 upstream.
+
+According the programming guide (for all DWC3 IPs), when the driver
+handles ClearFeature(halt) request, it should issue CLEAR_STALL command
+_after_ the END_TRANSFER command completes. The END_TRANSFER command may
+take some time to complete. So, delay the ClearFeature(halt) request
+control status stage and wait for END_TRANSFER command completion
+interrupt. Only after END_TRANSFER command completes that the driver
+may issue CLEAR_STALL command.
+
+Cc: stable@vger.kernel.org
+Fixes: cb11ea56f37a ("usb: dwc3: gadget: Properly handle ClearFeature(halt)")
+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/core.h   |    1 +
+ drivers/usb/dwc3/ep0.c    |   16 ++++++++++++++++
+ drivers/usb/dwc3/gadget.c |   40 ++++++++++++++++++++++++++++++++--------
+ drivers/usb/dwc3/gadget.h |    1 +
+ 4 files changed, 50 insertions(+), 8 deletions(-)
+
+--- a/drivers/usb/dwc3/core.h
++++ b/drivers/usb/dwc3/core.h
+@@ -710,6 +710,7 @@ struct dwc3_ep {
+ #define DWC3_EP_IGNORE_NEXT_NOSTREAM  BIT(8)
+ #define DWC3_EP_FORCE_RESTART_STREAM  BIT(9)
+ #define DWC3_EP_FIRST_STREAM_PRIMED   BIT(10)
++#define DWC3_EP_PENDING_CLEAR_STALL   BIT(11)
+       /* This last one is specific to EP0 */
+ #define DWC3_EP0_DIR_IN               BIT(31)
+--- a/drivers/usb/dwc3/ep0.c
++++ b/drivers/usb/dwc3/ep0.c
+@@ -524,6 +524,11 @@ static int dwc3_ep0_handle_endpoint(stru
+               ret = __dwc3_gadget_ep_set_halt(dep, set, true);
+               if (ret)
+                       return -EINVAL;
++
++              /* ClearFeature(Halt) may need delayed status */
++              if (!set && (dep->flags & DWC3_EP_END_TRANSFER_PENDING))
++                      return USB_GADGET_DELAYED_STATUS;
++
+               break;
+       default:
+               return -EINVAL;
+@@ -1049,6 +1054,17 @@ static void dwc3_ep0_do_control_status(s
+       __dwc3_ep0_do_control_status(dwc, dep);
+ }
++void dwc3_ep0_send_delayed_status(struct dwc3 *dwc)
++{
++      unsigned int direction = !dwc->ep0_expect_in;
++
++      if (dwc->ep0state != EP0_STATUS_PHASE)
++              return;
++
++      dwc->delayed_status = false;
++      __dwc3_ep0_do_control_status(dwc, dwc->eps[direction]);
++}
++
+ static void dwc3_ep0_end_control_data(struct dwc3 *dwc, struct dwc3_ep *dep)
+ {
+       struct dwc3_gadget_ep_cmd_params params;
+--- a/drivers/usb/dwc3/gadget.c
++++ b/drivers/usb/dwc3/gadget.c
+@@ -1827,6 +1827,18 @@ int __dwc3_gadget_ep_set_halt(struct dwc
+                       return 0;
+               }
++              dwc3_stop_active_transfer(dep, true, true);
++
++              list_for_each_entry_safe(req, tmp, &dep->started_list, list)
++                      dwc3_gadget_move_cancelled_request(req);
++
++              if (dep->flags & DWC3_EP_END_TRANSFER_PENDING) {
++                      dep->flags |= DWC3_EP_PENDING_CLEAR_STALL;
++                      return 0;
++              }
++
++              dwc3_gadget_ep_cleanup_cancelled_requests(dep);
++
+               ret = dwc3_send_clear_stall_ep_cmd(dep);
+               if (ret) {
+                       dev_err(dwc->dev, "failed to clear STALL on %s\n",
+@@ -1836,14 +1848,6 @@ int __dwc3_gadget_ep_set_halt(struct dwc
+               dep->flags &= ~(DWC3_EP_STALL | DWC3_EP_WEDGE);
+-              dwc3_stop_active_transfer(dep, true, true);
+-
+-              list_for_each_entry_safe(req, tmp, &dep->started_list, list)
+-                      dwc3_gadget_move_cancelled_request(req);
+-
+-              if (!(dep->flags & DWC3_EP_END_TRANSFER_PENDING))
+-                      dwc3_gadget_ep_cleanup_cancelled_requests(dep);
+-
+               if ((dep->flags & DWC3_EP_DELAY_START) &&
+                   !usb_endpoint_xfer_isoc(dep->endpoint.desc))
+                       __dwc3_gadget_kick_transfer(dep);
+@@ -3003,6 +3007,26 @@ static void dwc3_endpoint_interrupt(stru
+                       dep->flags &= ~DWC3_EP_END_TRANSFER_PENDING;
+                       dep->flags &= ~DWC3_EP_TRANSFER_STARTED;
+                       dwc3_gadget_ep_cleanup_cancelled_requests(dep);
++
++                      if (dep->flags & DWC3_EP_PENDING_CLEAR_STALL) {
++                              struct dwc3 *dwc = dep->dwc;
++
++                              dep->flags &= ~DWC3_EP_PENDING_CLEAR_STALL;
++                              if (dwc3_send_clear_stall_ep_cmd(dep)) {
++                                      struct usb_ep *ep0 = &dwc->eps[0]->endpoint;
++
++                                      dev_err(dwc->dev, "failed to clear STALL on %s\n",
++                                              dep->name);
++                                      if (dwc->delayed_status)
++                                              __dwc3_gadget_ep0_set_halt(ep0, 1);
++                                      return;
++                              }
++
++                              dep->flags &= ~(DWC3_EP_STALL | DWC3_EP_WEDGE);
++                              if (dwc->delayed_status)
++                                      dwc3_ep0_send_delayed_status(dwc);
++                      }
++
+                       if ((dep->flags & DWC3_EP_DELAY_START) &&
+                           !usb_endpoint_xfer_isoc(dep->endpoint.desc))
+                               __dwc3_gadget_kick_transfer(dep);
+--- a/drivers/usb/dwc3/gadget.h
++++ b/drivers/usb/dwc3/gadget.h
+@@ -113,6 +113,7 @@ int dwc3_gadget_ep0_set_halt(struct usb_
+ int dwc3_gadget_ep0_queue(struct usb_ep *ep, struct usb_request *request,
+               gfp_t gfp_flags);
+ int __dwc3_gadget_ep_set_halt(struct dwc3_ep *dep, int value, int protocol);
++void dwc3_ep0_send_delayed_status(struct dwc3 *dwc);
+ /**
+  * dwc3_gadget_ep_get_transfer_index - Gets transfer index from HW
diff --git a/queue-5.9/usb-dwc3-gadget-reclaim-extra-trbs-after-request-completion.patch b/queue-5.9/usb-dwc3-gadget-reclaim-extra-trbs-after-request-completion.patch
new file mode 100644 (file)
index 0000000..92afc0c
--- /dev/null
@@ -0,0 +1,50 @@
+From 690e5c2dc29f8891fcfd30da67e0d5837c2c9df5 Mon Sep 17 00:00:00 2001
+From: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
+Date: Thu, 24 Sep 2020 01:21:24 -0700
+Subject: usb: dwc3: gadget: Reclaim extra TRBs after request completion
+
+From: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
+
+commit 690e5c2dc29f8891fcfd30da67e0d5837c2c9df5 upstream.
+
+An SG request may be partially completed (due to no available TRBs).
+Don't reclaim extra TRBs and clear the needs_extra_trb flag until the
+request is fully completed. Otherwise, the driver will reclaim the wrong
+TRB.
+
+Cc: stable@vger.kernel.org
+Fixes: 1f512119a08c ("usb: dwc3: gadget: add remaining sg entries to ring")
+Signed-off-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
+Signed-off-by: Felipe Balbi <balbi@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/dwc3/gadget.c |   10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+--- a/drivers/usb/dwc3/gadget.c
++++ b/drivers/usb/dwc3/gadget.c
+@@ -2732,6 +2732,11 @@ static int dwc3_gadget_ep_cleanup_comple
+               ret = dwc3_gadget_ep_reclaim_trb_linear(dep, req, event,
+                               status);
++      req->request.actual = req->request.length - req->remaining;
++
++      if (!dwc3_gadget_ep_request_completed(req))
++              goto out;
++
+       if (req->needs_extra_trb) {
+               unsigned int maxp = usb_endpoint_maxp(dep->endpoint.desc);
+@@ -2747,11 +2752,6 @@ static int dwc3_gadget_ep_cleanup_comple
+               req->needs_extra_trb = false;
+       }
+-      req->request.actual = req->request.length - req->remaining;
+-
+-      if (!dwc3_gadget_ep_request_completed(req))
+-              goto out;
+-
+       dwc3_gadget_giveback(dep, req, status);
+ out:
diff --git a/queue-5.9/usb-dwc3-gadget-resume-pending-requests-after-clear_stall.patch b/queue-5.9/usb-dwc3-gadget-resume-pending-requests-after-clear_stall.patch
new file mode 100644 (file)
index 0000000..7d14dc6
--- /dev/null
@@ -0,0 +1,66 @@
+From c503672abe1348f10f5a54a662336358c6e1a297 Mon Sep 17 00:00:00 2001
+From: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
+Date: Wed, 2 Sep 2020 18:42:58 -0700
+Subject: usb: dwc3: gadget: Resume pending requests after CLEAR_STALL
+
+From: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
+
+commit c503672abe1348f10f5a54a662336358c6e1a297 upstream.
+
+The function driver may queue new requests right after halting the
+endpoint (i.e. queue new requests while the endpoint is stalled).
+There's no restriction preventing it from doing so. However, dwc3
+currently drops those requests after CLEAR_STALL. The driver should only
+drop started requests. Keep the pending requests in the pending list to
+resume and process them after the host issues ClearFeature(Halt) to the
+endpoint.
+
+Cc: stable@vger.kernel.org
+Fixes: cb11ea56f37a ("usb: dwc3: gadget: Properly handle ClearFeature(halt)")
+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 |   22 ++++++++++++++--------
+ 1 file changed, 14 insertions(+), 8 deletions(-)
+
+--- a/drivers/usb/dwc3/gadget.c
++++ b/drivers/usb/dwc3/gadget.c
+@@ -1628,8 +1628,13 @@ static int __dwc3_gadget_ep_queue(struct
+       if (dep->flags & DWC3_EP_WAIT_TRANSFER_COMPLETE)
+               return 0;
+-      /* Start the transfer only after the END_TRANSFER is completed */
+-      if (dep->flags & DWC3_EP_END_TRANSFER_PENDING) {
++      /*
++       * Start the transfer only after the END_TRANSFER is completed
++       * and endpoint STALL is cleared.
++       */
++      if ((dep->flags & DWC3_EP_END_TRANSFER_PENDING) ||
++          (dep->flags & DWC3_EP_WEDGE) ||
++          (dep->flags & DWC3_EP_STALL)) {
+               dep->flags |= DWC3_EP_DELAY_START;
+               return 0;
+       }
+@@ -1836,13 +1841,14 @@ int __dwc3_gadget_ep_set_halt(struct dwc
+               list_for_each_entry_safe(req, tmp, &dep->started_list, list)
+                       dwc3_gadget_move_cancelled_request(req);
+-              list_for_each_entry_safe(req, tmp, &dep->pending_list, list)
+-                      dwc3_gadget_move_cancelled_request(req);
+-
+-              if (!(dep->flags & DWC3_EP_END_TRANSFER_PENDING)) {
+-                      dep->flags &= ~DWC3_EP_DELAY_START;
++              if (!(dep->flags & DWC3_EP_END_TRANSFER_PENDING))
+                       dwc3_gadget_ep_cleanup_cancelled_requests(dep);
+-              }
++
++              if ((dep->flags & DWC3_EP_DELAY_START) &&
++                  !usb_endpoint_xfer_isoc(dep->endpoint.desc))
++                      __dwc3_gadget_kick_transfer(dep);
++
++              dep->flags &= ~DWC3_EP_DELAY_START;
+       }
+       return ret;
diff --git a/queue-5.9/usb-dwc3-pci-allow-elkhart-lake-to-utilize-dsm-method-for-pm-functionality.patch b/queue-5.9/usb-dwc3-pci-allow-elkhart-lake-to-utilize-dsm-method-for-pm-functionality.patch
new file mode 100644 (file)
index 0000000..b9b3dc2
--- /dev/null
@@ -0,0 +1,40 @@
+From a609ce2a13360d639b384b6ca783b38c1247f2db Mon Sep 17 00:00:00 2001
+From: Raymond Tan <raymond.tan@intel.com>
+Date: Fri, 21 Aug 2020 16:11:01 +0300
+Subject: usb: dwc3: pci: Allow Elkhart Lake to utilize DSM method for PM functionality
+
+From: Raymond Tan <raymond.tan@intel.com>
+
+commit a609ce2a13360d639b384b6ca783b38c1247f2db upstream.
+
+Similar to some other IA platforms, Elkhart Lake too depends on the
+PMU register write to request transition of Dx power state.
+
+Thus, we add the PCI_DEVICE_ID_INTEL_EHLLP to the list of devices that
+shall execute the ACPI _DSM method during D0/D3 sequence.
+
+[heikki.krogerus@linux.intel.com: included Fixes tag]
+
+Fixes: dbb0569de852 ("usb: dwc3: pci: Add Support for Intel Elkhart Lake Devices")
+Cc: stable@vger.kernel.org
+Signed-off-by: Raymond Tan <raymond.tan@intel.com>
+Signed-off-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
+Signed-off-by: Felipe Balbi <balbi@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/dwc3/dwc3-pci.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/usb/dwc3/dwc3-pci.c
++++ b/drivers/usb/dwc3/dwc3-pci.c
+@@ -147,7 +147,8 @@ static int dwc3_pci_quirks(struct dwc3_p
+       if (pdev->vendor == PCI_VENDOR_ID_INTEL) {
+               if (pdev->device == PCI_DEVICE_ID_INTEL_BXT ||
+-                              pdev->device == PCI_DEVICE_ID_INTEL_BXT_M) {
++                  pdev->device == PCI_DEVICE_ID_INTEL_BXT_M ||
++                  pdev->device == PCI_DEVICE_ID_INTEL_EHLLP) {
+                       guid_parse(PCI_INTEL_BXT_DSM_GUID, &dwc->guid);
+                       dwc->has_dsm_for_pm = true;
+               }
diff --git a/queue-5.9/usb-host-fsl-mph-dr-of-check-return-of-dma_set_mask.patch b/queue-5.9/usb-host-fsl-mph-dr-of-check-return-of-dma_set_mask.patch
new file mode 100644 (file)
index 0000000..3aaecbf
--- /dev/null
@@ -0,0 +1,42 @@
+From 3cd54a618834430a26a648d880dd83d740f2ae30 Mon Sep 17 00:00:00 2001
+From: Ran Wang <ran.wang_1@nxp.com>
+Date: Sat, 10 Oct 2020 14:03:08 +0800
+Subject: usb: host: fsl-mph-dr-of: check return of dma_set_mask()
+
+From: Ran Wang <ran.wang_1@nxp.com>
+
+commit 3cd54a618834430a26a648d880dd83d740f2ae30 upstream.
+
+fsl_usb2_device_register() should stop init if dma_set_mask() return
+error.
+
+Fixes: cae058610465 ("drivers/usb/host: fsl: Set DMA_MASK of usb platform device")
+Reviewed-by: Peter Chen <peter.chen@nxp.com>
+Signed-off-by: Ran Wang <ran.wang_1@nxp.com>
+Link: https://lore.kernel.org/r/20201010060308.33693-1-ran.wang_1@nxp.com
+Cc: stable <stable@vger.kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/host/fsl-mph-dr-of.c |    9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+--- a/drivers/usb/host/fsl-mph-dr-of.c
++++ b/drivers/usb/host/fsl-mph-dr-of.c
+@@ -94,10 +94,13 @@ static struct platform_device *fsl_usb2_
+       pdev->dev.coherent_dma_mask = ofdev->dev.coherent_dma_mask;
+-      if (!pdev->dev.dma_mask)
++      if (!pdev->dev.dma_mask) {
+               pdev->dev.dma_mask = &ofdev->dev.coherent_dma_mask;
+-      else
+-              dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
++      } else {
++              retval = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
++              if (retval)
++                      goto error;
++      }
+       retval = platform_device_add_data(pdev, pdata, sizeof(*pdata));
+       if (retval)
diff --git a/queue-5.9/usb-typec-tcpm-reset-hard_reset_count-for-any-disconnect.patch b/queue-5.9/usb-typec-tcpm-reset-hard_reset_count-for-any-disconnect.patch
new file mode 100644 (file)
index 0000000..e83502d
--- /dev/null
@@ -0,0 +1,103 @@
+From 2d9c6442a9c81f4f8dee678d0b3c183173ab1e2d Mon Sep 17 00:00:00 2001
+From: Li Jun <jun.li@nxp.com>
+Date: Mon, 12 Oct 2020 19:03:12 +0800
+Subject: usb: typec: tcpm: reset hard_reset_count for any disconnect
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Li Jun <jun.li@nxp.com>
+
+commit 2d9c6442a9c81f4f8dee678d0b3c183173ab1e2d upstream.
+
+Current tcpm_detach() only reset hard_reset_count if port->attached
+is true, this may cause this counter clear is missed if the CC
+disconnect event is generated after tcpm_port_reset() is done
+by other events, e.g. VBUS off comes first before CC disconect for
+a power sink, in that case the first tcpm_detach() will only clear
+port->attached flag but leave hard_reset_count there because
+tcpm_port_is_disconnected() is still false, then later tcpm_detach()
+by CC disconnect will directly return due to port->attached is cleared,
+finally this will result tcpm will not try hard reset or error recovery
+for later attach.
+
+ChiYuan reported this issue on his platform with below tcpm trace:
+After power sink session setup after hard reset 2 times, detach
+from the power source and then attach:
+[ 4848.046358] VBUS off
+[ 4848.046384] state change SNK_READY -> SNK_UNATTACHED
+[ 4848.050908] Setting voltage/current limit 0 mV 0 mA
+[ 4848.050936] polarity 0
+[ 4848.052593] Requesting mux state 0, usb-role 0, orientation 0
+[ 4848.053222] Start toggling
+[ 4848.086500] state change SNK_UNATTACHED -> TOGGLING
+[ 4848.089983] CC1: 0 -> 0, CC2: 3 -> 3 [state TOGGLING, polarity 0, connected]
+[ 4848.089993] state change TOGGLING -> SNK_ATTACH_WAIT
+[ 4848.090031] pending state change SNK_ATTACH_WAIT -> SNK_DEBOUNCED @200 ms
+[ 4848.141162] CC1: 0 -> 0, CC2: 3 -> 0 [state SNK_ATTACH_WAIT, polarity 0, disconnected]
+[ 4848.141170] state change SNK_ATTACH_WAIT -> SNK_ATTACH_WAIT
+[ 4848.141184] pending state change SNK_ATTACH_WAIT -> SNK_UNATTACHED @20 ms
+[ 4848.163156] state change SNK_ATTACH_WAIT -> SNK_UNATTACHED [delayed 20 ms]
+[ 4848.163162] Start toggling
+[ 4848.216918] CC1: 0 -> 0, CC2: 0 -> 3 [state TOGGLING, polarity 0, connected]
+[ 4848.216954] state change TOGGLING -> SNK_ATTACH_WAIT
+[ 4848.217080] pending state change SNK_ATTACH_WAIT -> SNK_DEBOUNCED @200 ms
+[ 4848.231771] CC1: 0 -> 0, CC2: 3 -> 0 [state SNK_ATTACH_WAIT, polarity 0, disconnected]
+[ 4848.231800] state change SNK_ATTACH_WAIT -> SNK_ATTACH_WAIT
+[ 4848.231857] pending state change SNK_ATTACH_WAIT -> SNK_UNATTACHED @20 ms
+[ 4848.256022] state change SNK_ATTACH_WAIT -> SNK_UNATTACHED [delayed20 ms]
+[ 4848.256049] Start toggling
+[ 4848.871148] VBUS on
+[ 4848.885324] CC1: 0 -> 0, CC2: 0 -> 3 [state TOGGLING, polarity 0, connected]
+[ 4848.885372] state change TOGGLING -> SNK_ATTACH_WAIT
+[ 4848.885548] pending state change SNK_ATTACH_WAIT -> SNK_DEBOUNCED @200 ms
+[ 4849.088240] state change SNK_ATTACH_WAIT -> SNK_DEBOUNCED [delayed200 ms]
+[ 4849.088284] state change SNK_DEBOUNCED -> SNK_ATTACHED
+[ 4849.088291] polarity 1
+[ 4849.088769] Requesting mux state 1, usb-role 2, orientation 2
+[ 4849.088895] state change SNK_ATTACHED -> SNK_STARTUP
+[ 4849.088907] state change SNK_STARTUP -> SNK_DISCOVERY
+[ 4849.088915] Setting voltage/current limit 5000 mV 0 mA
+[ 4849.088927] vbus=0 charge:=1
+[ 4849.090505] state change SNK_DISCOVERY -> SNK_WAIT_CAPABILITIES
+[ 4849.090828] pending state change SNK_WAIT_CAPABILITIES -> SNK_READY @240 ms
+[ 4849.335878] state change SNK_WAIT_CAPABILITIES -> SNK_READY [delayed240 ms]
+
+this patch fix this issue by clear hard_reset_count at any cases
+of cc disconnect, í.e. don't check port->attached flag.
+
+Fixes: 4b4e02c83167 ("typec: tcpm: Move out of staging")
+Cc: stable@vger.kernel.org
+Reported-and-tested-by: ChiYuan Huang <cy_huang@richtek.com>
+Reviewed-by: Guenter Roeck <linux@roeck-us.net>
+Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
+Signed-off-by: Li Jun <jun.li@nxp.com>
+Link: https://lore.kernel.org/r/1602500592-3817-1-git-send-email-jun.li@nxp.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/typec/tcpm/tcpm.c |    6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- a/drivers/usb/typec/tcpm/tcpm.c
++++ b/drivers/usb/typec/tcpm/tcpm.c
+@@ -2789,6 +2789,9 @@ static void tcpm_reset_port(struct tcpm_
+ static void tcpm_detach(struct tcpm_port *port)
+ {
++      if (tcpm_port_is_disconnected(port))
++              port->hard_reset_count = 0;
++
+       if (!port->attached)
+               return;
+@@ -2797,9 +2800,6 @@ static void tcpm_detach(struct tcpm_port
+               port->tcpc->set_bist_data(port->tcpc, false);
+       }
+-      if (tcpm_port_is_disconnected(port))
+-              port->hard_reset_count = 0;
+-
+       tcpm_reset_port(port);
+ }
diff --git a/queue-5.9/usb-xhci-workaround-for-s3-issue-on-amd-snps-3.0-xhc.patch b/queue-5.9/usb-xhci-workaround-for-s3-issue-on-amd-snps-3.0-xhc.patch
new file mode 100644 (file)
index 0000000..1182a93
--- /dev/null
@@ -0,0 +1,81 @@
+From 2a632815683d2d34df52b701a36fe5ac6654e719 Mon Sep 17 00:00:00 2001
+From: Sandeep Singh <sandeep.singh@amd.com>
+Date: Wed, 28 Oct 2020 22:31:23 +0200
+Subject: usb: xhci: Workaround for S3 issue on AMD SNPS 3.0 xHC
+
+From: Sandeep Singh <sandeep.singh@amd.com>
+
+commit 2a632815683d2d34df52b701a36fe5ac6654e719 upstream.
+
+On some platform of AMD, S3 fails with HCE and SRE errors. To fix this,
+need to disable a bit which is enable in sparse controller.
+
+Cc: stable@vger.kernel.org #v4.19+
+Signed-off-by: Sanket Goswami <Sanket.Goswami@amd.com>
+Signed-off-by: Sandeep Singh <sandeep.singh@amd.com>
+Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Link: https://lore.kernel.org/r/20201028203124.375344-3-mathias.nyman@linux.intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/host/xhci-pci.c |   17 +++++++++++++++++
+ drivers/usb/host/xhci.h     |    1 +
+ 2 files changed, 18 insertions(+)
+
+--- a/drivers/usb/host/xhci-pci.c
++++ b/drivers/usb/host/xhci-pci.c
+@@ -22,6 +22,8 @@
+ #define SSIC_PORT_CFG2_OFFSET 0x30
+ #define PROG_DONE             (1 << 30)
+ #define SSIC_PORT_UNUSED      (1 << 31)
++#define SPARSE_DISABLE_BIT    17
++#define SPARSE_CNTL_ENABLE    0xC12C
+ /* Device for a quirk */
+ #define PCI_VENDOR_ID_FRESCO_LOGIC    0x1b73
+@@ -160,6 +162,9 @@ static void xhci_pci_quirks(struct devic
+           (pdev->device == 0x15e0 || pdev->device == 0x15e1))
+               xhci->quirks |= XHCI_SNPS_BROKEN_SUSPEND;
++      if (pdev->vendor == PCI_VENDOR_ID_AMD && pdev->device == 0x15e5)
++              xhci->quirks |= XHCI_DISABLE_SPARSE;
++
+       if (pdev->vendor == PCI_VENDOR_ID_AMD)
+               xhci->quirks |= XHCI_TRUST_TX_LENGTH;
+@@ -490,6 +495,15 @@ static void xhci_pme_quirk(struct usb_hc
+       readl(reg);
+ }
++static void xhci_sparse_control_quirk(struct usb_hcd *hcd)
++{
++      u32 reg;
++
++      reg = readl(hcd->regs + SPARSE_CNTL_ENABLE);
++      reg &= ~BIT(SPARSE_DISABLE_BIT);
++      writel(reg, hcd->regs + SPARSE_CNTL_ENABLE);
++}
++
+ static int xhci_pci_suspend(struct usb_hcd *hcd, bool do_wakeup)
+ {
+       struct xhci_hcd *xhci = hcd_to_xhci(hcd);
+@@ -509,6 +523,9 @@ static int xhci_pci_suspend(struct usb_h
+       if (xhci->quirks & XHCI_SSIC_PORT_UNUSED)
+               xhci_ssic_port_unused_quirk(hcd, true);
++      if (xhci->quirks & XHCI_DISABLE_SPARSE)
++              xhci_sparse_control_quirk(hcd);
++
+       ret = xhci_suspend(xhci, do_wakeup);
+       if (ret && (xhci->quirks & XHCI_SSIC_PORT_UNUSED))
+               xhci_ssic_port_unused_quirk(hcd, false);
+--- a/drivers/usb/host/xhci.h
++++ b/drivers/usb/host/xhci.h
+@@ -1874,6 +1874,7 @@ struct xhci_hcd {
+ #define XHCI_RESET_PLL_ON_DISCONNECT  BIT_ULL(34)
+ #define XHCI_SNPS_BROKEN_SUSPEND    BIT_ULL(35)
+ #define XHCI_RENESAS_FW_QUIRK BIT_ULL(36)
++#define XHCI_DISABLE_SPARSE   BIT_ULL(38)
+       unsigned int            num_active_eps;
+       unsigned int            limit_active_eps;
diff --git a/queue-5.9/usbcore-check-both-id_table-and-match-when-both-available.patch b/queue-5.9/usbcore-check-both-id_table-and-match-when-both-available.patch
new file mode 100644 (file)
index 0000000..c3590fa
--- /dev/null
@@ -0,0 +1,117 @@
+From 0942d59b0af46511d59dbf5bd69ec4a64d1a854c Mon Sep 17 00:00:00 2001
+From: Bastien Nocera <hadess@hadess.net>
+Date: Thu, 22 Oct 2020 09:55:20 -0400
+Subject: usbcore: Check both id_table and match() when both available
+
+From: Bastien Nocera <hadess@hadess.net>
+
+commit 0942d59b0af46511d59dbf5bd69ec4a64d1a854c upstream.
+
+From: Bastien Nocera <hadess@hadess.net>
+
+When a USB device driver has both an id_table and a match() function, make
+sure to check both to find a match, first matching the id_table, then
+checking the match() function.
+
+This makes it possible to have module autoloading done through the
+id_table when devices are plugged in, before checking for further
+device eligibility in the match() function.
+
+Cc: <stable@vger.kernel.org> # 5.8
+Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Cc: Alan Stern <stern@rowland.harvard.edu>
+Co-developed-by: M. Vefa Bicakci <m.v.b@runbox.com>
+Tested-by: Bastien Nocera <hadess@hadess.net>
+Signed-off-by: Bastien Nocera <hadess@hadess.net>
+Signed-off-by: M. Vefa Bicakci <m.v.b@runbox.com>
+Tested-by: Pan (Pany) YUAN <pany@fedoraproject.org>
+Link: https://lore.kernel.org/r/20201022135521.375211-2-m.v.b@runbox.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/core/driver.c  |   30 +++++++++++++++++++++---------
+ drivers/usb/core/generic.c |    4 +---
+ drivers/usb/core/usb.h     |    2 ++
+ 3 files changed, 24 insertions(+), 12 deletions(-)
+
+--- a/drivers/usb/core/driver.c
++++ b/drivers/usb/core/driver.c
+@@ -839,6 +839,22 @@ const struct usb_device_id *usb_device_m
+       return NULL;
+ }
++bool usb_driver_applicable(struct usb_device *udev,
++                         struct usb_device_driver *udrv)
++{
++      if (udrv->id_table && udrv->match)
++              return usb_device_match_id(udev, udrv->id_table) != NULL &&
++                     udrv->match(udev);
++
++      if (udrv->id_table)
++              return usb_device_match_id(udev, udrv->id_table) != NULL;
++
++      if (udrv->match)
++              return udrv->match(udev);
++
++      return false;
++}
++
+ static int usb_device_match(struct device *dev, struct device_driver *drv)
+ {
+       /* devices and interfaces are handled separately */
+@@ -853,17 +869,14 @@ static int usb_device_match(struct devic
+               udev = to_usb_device(dev);
+               udrv = to_usb_device_driver(drv);
+-              if (udrv->id_table)
+-                      return usb_device_match_id(udev, udrv->id_table) != NULL;
+-
+-              if (udrv->match)
+-                      return udrv->match(udev);
+-
+               /* If the device driver under consideration does not have a
+                * id_table or a match function, then let the driver's probe
+                * function decide.
+                */
+-              return 1;
++              if (!udrv->id_table && !udrv->match)
++                      return 1;
++
++              return usb_driver_applicable(udev, udrv);
+       } else if (is_usb_interface(dev)) {
+               struct usb_interface *intf;
+@@ -941,8 +954,7 @@ static int __usb_bus_reprobe_drivers(str
+               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))
++      if (!usb_driver_applicable(udev, new_udriver))
+               return 0;
+       ret = device_reprobe(dev);
+--- a/drivers/usb/core/generic.c
++++ b/drivers/usb/core/generic.c
+@@ -205,9 +205,7 @@ static int __check_usb_generic(struct de
+       udrv = to_usb_device_driver(drv);
+       if (udrv == &usb_generic_driver)
+               return 0;
+-      if (usb_device_match_id(udev, udrv->id_table) != NULL)
+-              return 1;
+-      return (udrv->match && udrv->match(udev));
++      return usb_driver_applicable(udev, udrv);
+ }
+ static bool usb_generic_driver_match(struct usb_device *udev)
+--- a/drivers/usb/core/usb.h
++++ b/drivers/usb/core/usb.h
+@@ -74,6 +74,8 @@ extern int usb_match_device(struct usb_d
+                           const struct usb_device_id *id);
+ extern const struct usb_device_id *usb_device_match_id(struct usb_device *udev,
+                               const struct usb_device_id *id);
++extern bool usb_driver_applicable(struct usb_device *udev,
++                                struct usb_device_driver *udrv);
+ extern void usb_forced_unbind_intf(struct usb_interface *intf);
+ extern void usb_unbind_and_rebind_marked_interfaces(struct usb_device *udev);
diff --git a/queue-5.9/vt-keyboard-extend-func_buf_lock-to-readers.patch b/queue-5.9/vt-keyboard-extend-func_buf_lock-to-readers.patch
new file mode 100644 (file)
index 0000000..4fd8238
--- /dev/null
@@ -0,0 +1,94 @@
+From 82e61c3909db51d91b9d3e2071557b6435018b80 Mon Sep 17 00:00:00 2001
+From: Jiri Slaby <jirislaby@kernel.org>
+Date: Mon, 19 Oct 2020 10:55:17 +0200
+Subject: vt: keyboard, extend func_buf_lock to readers
+
+From: Jiri Slaby <jslaby@suse.cz>
+
+commit 82e61c3909db51d91b9d3e2071557b6435018b80 upstream.
+
+Both read-side users of func_table/func_buf need locking. Without that,
+one can easily confuse the code by repeatedly setting altering strings
+like:
+while (1)
+       for (a = 0; a < 2; a++) {
+               struct kbsentry kbs = {};
+               strcpy((char *)kbs.kb_string, a ? ".\n" : "88888\n");
+               ioctl(fd, KDSKBSENT, &kbs);
+       }
+
+When that program runs, one can get unexpected output by holding F1
+(note the unxpected period on the last line):
+.
+88888
+.8888
+
+So protect all accesses to 'func_table' (and func_buf) by preexisting
+'func_buf_lock'.
+
+It is easy in 'k_fn' handler as 'puts_queue' is expected not to sleep.
+On the other hand, KDGKBSENT needs a local (atomic) copy of the string
+because copy_to_user can sleep. Use already allocated, but unused
+'kbs->kb_string' for that purpose.
+
+Note that the program above needs at least CAP_SYS_TTY_CONFIG.
+
+This depends on the previous patch and on the func_buf_lock lock added
+in commit 46ca3f735f34 (tty/vt: fix write/write race in ioctl(KDSKBSENT)
+handler) in 5.2.
+
+Likely fixes CVE-2020-25656.
+
+Cc: <stable@vger.kernel.org>
+Reported-by: Minh Yuan <yuanmingbuaa@gmail.com>
+Signed-off-by: Jiri Slaby <jslaby@suse.cz>
+Link: https://lore.kernel.org/r/20201019085517.10176-2-jslaby@suse.cz
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/tty/vt/keyboard.c |   17 +++++++++++++----
+ 1 file changed, 13 insertions(+), 4 deletions(-)
+
+--- a/drivers/tty/vt/keyboard.c
++++ b/drivers/tty/vt/keyboard.c
+@@ -743,8 +743,13 @@ static void k_fn(struct vc_data *vc, uns
+               return;
+       if ((unsigned)value < ARRAY_SIZE(func_table)) {
++              unsigned long flags;
++
++              spin_lock_irqsave(&func_buf_lock, flags);
+               if (func_table[value])
+                       puts_queue(vc, func_table[value]);
++              spin_unlock_irqrestore(&func_buf_lock, flags);
++
+       } else
+               pr_err("k_fn called with value=%d\n", value);
+ }
+@@ -1991,7 +1996,7 @@ out:
+ #undef s
+ #undef v
+-/* FIXME: This one needs untangling and locking */
++/* FIXME: This one needs untangling */
+ int vt_do_kdgkb_ioctl(int cmd, struct kbsentry __user *user_kdgkb, int perm)
+ {
+       struct kbsentry *kbs;
+@@ -2023,10 +2028,14 @@ int vt_do_kdgkb_ioctl(int cmd, struct kb
+       switch (cmd) {
+       case KDGKBSENT: {
+               /* size should have been a struct member */
+-              unsigned char *from = func_table[i] ? : "";
++              ssize_t len = sizeof(user_kdgkb->kb_string);
++
++              spin_lock_irqsave(&func_buf_lock, flags);
++              len = strlcpy(kbs->kb_string, func_table[i] ? : "", len);
++              spin_unlock_irqrestore(&func_buf_lock, flags);
+-              ret = copy_to_user(user_kdgkb->kb_string, from,
+-                              strlen(from) + 1) ? -EFAULT : 0;
++              ret = copy_to_user(user_kdgkb->kb_string, kbs->kb_string,
++                              len + 1) ? -EFAULT : 0;
+               goto reterr;
+       }
diff --git a/queue-5.9/vt-keyboard-simplify-vt_kdgkbsent.patch b/queue-5.9/vt-keyboard-simplify-vt_kdgkbsent.patch
new file mode 100644 (file)
index 0000000..f03a1cc
--- /dev/null
@@ -0,0 +1,73 @@
+From 6ca03f90527e499dd5e32d6522909e2ad390896b Mon Sep 17 00:00:00 2001
+From: Jiri Slaby <jirislaby@kernel.org>
+Date: Mon, 19 Oct 2020 10:55:16 +0200
+Subject: vt: keyboard, simplify vt_kdgkbsent
+
+From: Jiri Slaby <jslaby@suse.cz>
+
+commit 6ca03f90527e499dd5e32d6522909e2ad390896b upstream.
+
+Use 'strlen' of the string, add one for NUL terminator and simply do
+'copy_to_user' instead of the explicit 'for' loop. This makes the
+KDGKBSENT case more compact.
+
+The only thing we need to take care about is NULL 'func_table[i]'. Use
+an empty string in that case.
+
+The original check for overflow could never trigger as the func_buf
+strings are always shorter or equal to 'struct kbsentry's.
+
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Jiri Slaby <jslaby@suse.cz>
+Link: https://lore.kernel.org/r/20201019085517.10176-1-jslaby@suse.cz
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/tty/vt/keyboard.c |   28 +++++++++-------------------
+ 1 file changed, 9 insertions(+), 19 deletions(-)
+
+--- a/drivers/tty/vt/keyboard.c
++++ b/drivers/tty/vt/keyboard.c
+@@ -1995,9 +1995,7 @@ out:
+ int vt_do_kdgkb_ioctl(int cmd, struct kbsentry __user *user_kdgkb, int perm)
+ {
+       struct kbsentry *kbs;
+-      char *p;
+       u_char *q;
+-      u_char __user *up;
+       int sz, fnw_sz;
+       int delta;
+       char *first_free, *fj, *fnw;
+@@ -2023,23 +2021,15 @@ int vt_do_kdgkb_ioctl(int cmd, struct kb
+       i = array_index_nospec(kbs->kb_func, MAX_NR_FUNC);
+       switch (cmd) {
+-      case KDGKBSENT:
+-              sz = sizeof(kbs->kb_string) - 1; /* sz should have been
+-                                                a struct member */
+-              up = user_kdgkb->kb_string;
+-              p = func_table[i];
+-              if(p)
+-                      for ( ; *p && sz; p++, sz--)
+-                              if (put_user(*p, up++)) {
+-                                      ret = -EFAULT;
+-                                      goto reterr;
+-                              }
+-              if (put_user('\0', up)) {
+-                      ret = -EFAULT;
+-                      goto reterr;
+-              }
+-              kfree(kbs);
+-              return ((p && *p) ? -EOVERFLOW : 0);
++      case KDGKBSENT: {
++              /* size should have been a struct member */
++              unsigned char *from = func_table[i] ? : "";
++
++              ret = copy_to_user(user_kdgkb->kb_string, from,
++                              strlen(from) + 1) ? -EFAULT : 0;
++
++              goto reterr;
++      }
+       case KDSKBSENT:
+               if (!perm) {
+                       ret = -EPERM;
diff --git a/queue-5.9/vt_ioctl-fix-gio_unimap-regression.patch b/queue-5.9/vt_ioctl-fix-gio_unimap-regression.patch
new file mode 100644 (file)
index 0000000..cd92298
--- /dev/null
@@ -0,0 +1,64 @@
+From d54654790302ccaa72589380dce060d376ef8716 Mon Sep 17 00:00:00 2001
+From: Jiri Slaby <jirislaby@kernel.org>
+Date: Mon, 26 Oct 2020 06:54:19 +0100
+Subject: vt_ioctl: fix GIO_UNIMAP regression
+
+From: Jiri Slaby <jslaby@suse.cz>
+
+commit d54654790302ccaa72589380dce060d376ef8716 upstream.
+
+In commit 5ba127878722, we shuffled with the check of 'perm'. But my
+brain somehow inverted the condition in 'do_unimap_ioctl' (I thought
+it is ||, not &&), so GIO_UNIMAP stopped working completely.
+
+Move the 'perm' checks back to do_unimap_ioctl and do them right again.
+In fact, this reverts this part of code to the pre-5ba127878722 state.
+Except 'perm' is now a bool.
+
+Fixes: 5ba127878722 ("vt_ioctl: move perm checks level up")
+Cc: stable@vger.kernel.org
+Reported-by: Fabian Vogt <fvogt@suse.com>
+Signed-off-by: Jiri Slaby <jslaby@suse.cz>
+Link: https://lore.kernel.org/r/20201026055419.30518-1-jslaby@suse.cz
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/tty/vt/vt_ioctl.c |   11 +++++------
+ 1 file changed, 5 insertions(+), 6 deletions(-)
+
+--- a/drivers/tty/vt/vt_ioctl.c
++++ b/drivers/tty/vt/vt_ioctl.c
+@@ -550,7 +550,7 @@ static int vt_io_fontreset(struct consol
+ }
+ static inline int do_unimap_ioctl(int cmd, struct unimapdesc __user *user_ud,
+-              struct vc_data *vc)
++              bool perm, struct vc_data *vc)
+ {
+       struct unimapdesc tmp;
+@@ -558,9 +558,11 @@ static inline int do_unimap_ioctl(int cm
+               return -EFAULT;
+       switch (cmd) {
+       case PIO_UNIMAP:
++              if (!perm)
++                      return -EPERM;
+               return con_set_unimap(vc, tmp.entry_ct, tmp.entries);
+       case GIO_UNIMAP:
+-              if (fg_console != vc->vc_num)
++              if (!perm && fg_console != vc->vc_num)
+                       return -EPERM;
+               return con_get_unimap(vc, tmp.entry_ct, &(user_ud->entry_ct),
+                               tmp.entries);
+@@ -640,10 +642,7 @@ static int vt_io_ioctl(struct vc_data *v
+       case PIO_UNIMAP:
+       case GIO_UNIMAP:
+-              if (!perm)
+-                      return -EPERM;
+-
+-              return do_unimap_ioctl(cmd, up, vc);
++              return do_unimap_ioctl(cmd, up, perm, vc);
+       default:
+               return -ENOIOCTLCMD;
diff --git a/queue-5.9/x86-mce-allow-for-copy_mc_fragile-symbol-checksum-to-be-generated.patch b/queue-5.9/x86-mce-allow-for-copy_mc_fragile-symbol-checksum-to-be-generated.patch
new file mode 100644 (file)
index 0000000..1e1fae2
--- /dev/null
@@ -0,0 +1,39 @@
+From b3149ffcdb31a8eb854cc442a389ae0b539bf28a Mon Sep 17 00:00:00 2001
+From: Borislav Petkov <bp@suse.de>
+Date: Wed, 7 Oct 2020 18:55:35 +0200
+Subject: x86/mce: Allow for copy_mc_fragile symbol checksum to be generated
+
+From: Borislav Petkov <bp@suse.de>
+
+commit b3149ffcdb31a8eb854cc442a389ae0b539bf28a upstream.
+
+Add asm/mce.h to asm/asm-prototypes.h so that that asm symbol's checksum
+can be generated in order to support CONFIG_MODVERSIONS with it and fix:
+
+  WARNING: modpost: EXPORT symbol "copy_mc_fragile" [vmlinux] version \
+         generation failed, symbol will not be versioned.
+
+For reference see:
+
+  4efca4ed05cb ("kbuild: modversions for EXPORT_SYMBOL() for asm")
+  334bb7738764 ("x86/kbuild: enable modversions for symbols exported from asm")
+
+Fixes: ec6347bb4339 ("x86, powerpc: Rename memcpy_mcsafe() to copy_mc_to_{user, kernel}()")
+Signed-off-by: Borislav Petkov <bp@suse.de>
+Link: https://lkml.kernel.org/r/20201007111447.GA23257@zn.tnic
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/x86/include/asm/asm-prototypes.h |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/arch/x86/include/asm/asm-prototypes.h
++++ b/arch/x86/include/asm/asm-prototypes.h
+@@ -5,6 +5,7 @@
+ #include <asm/string.h>
+ #include <asm/page.h>
+ #include <asm/checksum.h>
++#include <asm/mce.h>
+ #include <asm-generic/asm-prototypes.h>