]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
6.1-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 22 Jan 2024 18:50:18 +0000 (10:50 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 22 Jan 2024 18:50:18 +0000 (10:50 -0800)
added patches:
binder-fix-race-between-mmput-and-do_exit.patch
clocksource-drivers-timer-ti-dm-fix-make-w-n-kerneldoc-warnings.patch
powerpc-64s-increase-default-stack-size-to-32kb.patch
revert-usb-dwc3-don-t-reset-device-side-if-dwc3-was-configured-as-host-only.patch
revert-usb-dwc3-soft-reset-phy-on-probe-for-host.patch
revert-usb-typec-class-fix-typec_altmode_put_partner-to-put-plugs.patch
serial-8250_bcm2835aux-restore-clock-error-handling.patch
serial-8250_exar-set-missing-rs485_supported-flag.patch
serial-core-fix-sanitizing-check-for-rts-settings.patch
serial-core-imx-do-not-set-rs485-enabled-if-it-is-not-supported.patch
serial-core-make-sure-rs485-cannot-be-enabled-when-it-is-not-supported.patch
serial-imx-ensure-that-imx_uart_rs485_config-is-called-with-enabled-clock.patch
serial-omap-do-not-override-settings-for-rs485-support.patch
tick-sched-fix-idle-and-iowait-sleeptime-accounting-vs-cpu-hotplug.patch
usb-cdns3-fix-iso-transfer-error-when-mult-is-not-zero.patch
usb-cdns3-fix-uvc-fail-when-dma-cross-4k-boundery-since-sg-enabled.patch
usb-cdns3-fix-uvc-failure-work-since-sg-support-enabled.patch
usb-chipidea-wait-controller-resume-finished-for-wakeup-irq.patch
usb-dwc-ep0-update-request-status-in-dwc3_ep0_stall_restart.patch
usb-dwc3-gadget-handle-ep0-request-dequeuing-properly.patch
usb-mon-fix-atomicity-violation-in-mon_bin_vma_fault.patch
usb-phy-mxs-remove-config_usb_otg-condition-for-mxs_phy_is_otg_host.patch
usb-typec-class-fix-typec_altmode_put_partner-to-put-plugs.patch
xen-netback-don-t-produce-zero-size-skb-frags.patch

25 files changed:
queue-6.1/binder-fix-race-between-mmput-and-do_exit.patch [new file with mode: 0644]
queue-6.1/clocksource-drivers-timer-ti-dm-fix-make-w-n-kerneldoc-warnings.patch [new file with mode: 0644]
queue-6.1/powerpc-64s-increase-default-stack-size-to-32kb.patch [new file with mode: 0644]
queue-6.1/revert-usb-dwc3-don-t-reset-device-side-if-dwc3-was-configured-as-host-only.patch [new file with mode: 0644]
queue-6.1/revert-usb-dwc3-soft-reset-phy-on-probe-for-host.patch [new file with mode: 0644]
queue-6.1/revert-usb-typec-class-fix-typec_altmode_put_partner-to-put-plugs.patch [new file with mode: 0644]
queue-6.1/serial-8250_bcm2835aux-restore-clock-error-handling.patch [new file with mode: 0644]
queue-6.1/serial-8250_exar-set-missing-rs485_supported-flag.patch [new file with mode: 0644]
queue-6.1/serial-core-fix-sanitizing-check-for-rts-settings.patch [new file with mode: 0644]
queue-6.1/serial-core-imx-do-not-set-rs485-enabled-if-it-is-not-supported.patch [new file with mode: 0644]
queue-6.1/serial-core-make-sure-rs485-cannot-be-enabled-when-it-is-not-supported.patch [new file with mode: 0644]
queue-6.1/serial-imx-ensure-that-imx_uart_rs485_config-is-called-with-enabled-clock.patch [new file with mode: 0644]
queue-6.1/serial-omap-do-not-override-settings-for-rs485-support.patch [new file with mode: 0644]
queue-6.1/series
queue-6.1/tick-sched-fix-idle-and-iowait-sleeptime-accounting-vs-cpu-hotplug.patch [new file with mode: 0644]
queue-6.1/usb-cdns3-fix-iso-transfer-error-when-mult-is-not-zero.patch [new file with mode: 0644]
queue-6.1/usb-cdns3-fix-uvc-fail-when-dma-cross-4k-boundery-since-sg-enabled.patch [new file with mode: 0644]
queue-6.1/usb-cdns3-fix-uvc-failure-work-since-sg-support-enabled.patch [new file with mode: 0644]
queue-6.1/usb-chipidea-wait-controller-resume-finished-for-wakeup-irq.patch [new file with mode: 0644]
queue-6.1/usb-dwc-ep0-update-request-status-in-dwc3_ep0_stall_restart.patch [new file with mode: 0644]
queue-6.1/usb-dwc3-gadget-handle-ep0-request-dequeuing-properly.patch [new file with mode: 0644]
queue-6.1/usb-mon-fix-atomicity-violation-in-mon_bin_vma_fault.patch [new file with mode: 0644]
queue-6.1/usb-phy-mxs-remove-config_usb_otg-condition-for-mxs_phy_is_otg_host.patch [new file with mode: 0644]
queue-6.1/usb-typec-class-fix-typec_altmode_put_partner-to-put-plugs.patch [new file with mode: 0644]
queue-6.1/xen-netback-don-t-produce-zero-size-skb-frags.patch [new file with mode: 0644]

diff --git a/queue-6.1/binder-fix-race-between-mmput-and-do_exit.patch b/queue-6.1/binder-fix-race-between-mmput-and-do_exit.patch
new file mode 100644 (file)
index 0000000..3c1c1ec
--- /dev/null
@@ -0,0 +1,66 @@
+From 9a9ab0d963621d9d12199df9817e66982582d5a5 Mon Sep 17 00:00:00 2001
+From: Carlos Llamas <cmllamas@google.com>
+Date: Fri, 1 Dec 2023 17:21:32 +0000
+Subject: binder: fix race between mmput() and do_exit()
+
+From: Carlos Llamas <cmllamas@google.com>
+
+commit 9a9ab0d963621d9d12199df9817e66982582d5a5 upstream.
+
+Task A calls binder_update_page_range() to allocate and insert pages on
+a remote address space from Task B. For this, Task A pins the remote mm
+via mmget_not_zero() first. This can race with Task B do_exit() and the
+final mmput() refcount decrement will come from Task A.
+
+  Task A            | Task B
+  ------------------+------------------
+  mmget_not_zero()  |
+                    |  do_exit()
+                    |    exit_mm()
+                    |      mmput()
+  mmput()           |
+    exit_mmap()     |
+      remove_vma()  |
+        fput()      |
+
+In this case, the work of ____fput() from Task B is queued up in Task A
+as TWA_RESUME. So in theory, Task A returns to userspace and the cleanup
+work gets executed. However, Task A instead sleep, waiting for a reply
+from Task B that never comes (it's dead).
+
+This means the binder_deferred_release() is blocked until an unrelated
+binder event forces Task A to go back to userspace. All the associated
+death notifications will also be delayed until then.
+
+In order to fix this use mmput_async() that will schedule the work in
+the corresponding mm->async_put_work WQ instead of Task A.
+
+Fixes: 457b9a6f09f0 ("Staging: android: add binder driver")
+Reviewed-by: Alice Ryhl <aliceryhl@google.com>
+Signed-off-by: Carlos Llamas <cmllamas@google.com>
+Link: https://lore.kernel.org/r/20231201172212.1813387-4-cmllamas@google.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/android/binder_alloc.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/android/binder_alloc.c
++++ b/drivers/android/binder_alloc.c
+@@ -271,7 +271,7 @@ static int binder_update_page_range(stru
+       }
+       if (mm) {
+               mmap_write_unlock(mm);
+-              mmput(mm);
++              mmput_async(mm);
+       }
+       return 0;
+@@ -304,7 +304,7 @@ err_page_ptr_cleared:
+ err_no_vma:
+       if (mm) {
+               mmap_write_unlock(mm);
+-              mmput(mm);
++              mmput_async(mm);
+       }
+       return vma ? -ENOMEM : -ESRCH;
+ }
diff --git a/queue-6.1/clocksource-drivers-timer-ti-dm-fix-make-w-n-kerneldoc-warnings.patch b/queue-6.1/clocksource-drivers-timer-ti-dm-fix-make-w-n-kerneldoc-warnings.patch
new file mode 100644 (file)
index 0000000..c7d1c88
--- /dev/null
@@ -0,0 +1,50 @@
+From b99a212a7697c542b460adaa15d4a98abf8223f0 Mon Sep 17 00:00:00 2001
+From: Tony Lindgren <tony@atomide.com>
+Date: Tue, 14 Nov 2023 09:29:30 +0200
+Subject: clocksource/drivers/timer-ti-dm: Fix make W=n kerneldoc warnings
+
+From: Tony Lindgren <tony@atomide.com>
+
+commit b99a212a7697c542b460adaa15d4a98abf8223f0 upstream.
+
+Kernel test robot reports of kerneldoc related warnings that happen with
+make W=n for "parameter or member not described".
+
+These were caused by changes to function parameter names with
+earlier commits where the kerneldoc parts were not updated.
+
+Fixes: 49cd16bb573e ("clocksource/drivers/timer-ti-dm: Simplify register writes with dmtimer_write()")
+Fixes: a6e543f61531 ("clocksource/drivers/timer-ti-dm: Move struct omap_dm_timer fields to driver")
+Reported-by: kernel test robot <lkp@intel.com>
+Closes: https://lore.kernel.org/oe-kbuild-all/202311040403.DzIiBuwU-lkp@intel.com/
+Closes: https://lore.kernel.org/oe-kbuild-all/202311040606.XL5OcR9O-lkp@intel.com/
+Signed-off-by: Tony Lindgren <tony@atomide.com>
+Reviewed-by: Randy Dunlap <rdunlap@infradead.org>
+Tested-by: Randy Dunlap <rdunlap@infradead.org>
+Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
+Link: https://lore.kernel.org/r/20231114072930.40615-1-tony@atomide.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/clocksource/timer-ti-dm.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/clocksource/timer-ti-dm.c
++++ b/drivers/clocksource/timer-ti-dm.c
+@@ -184,7 +184,7 @@ static inline u32 dmtimer_read(struct dm
+  * dmtimer_write - write timer registers in posted and non-posted mode
+  * @timer:      timer pointer over which write operation is to perform
+  * @reg:        lowest byte holds the register offset
+- * @value:      data to write into the register
++ * @val:        data to write into the register
+  *
+  * The posted mode bit is encoded in reg. Note that in posted mode, the write
+  * pending bit must be checked. Otherwise a write on a register which has a
+@@ -937,7 +937,7 @@ static int omap_dm_timer_set_int_enable(
+ /**
+  * omap_dm_timer_set_int_disable - disable timer interrupts
+- * @timer:    pointer to timer handle
++ * @cookie:   pointer to timer cookie
+  * @mask:     bit mask of interrupts to be disabled
+  *
+  * Disables the specified timer interrupts for a timer.
diff --git a/queue-6.1/powerpc-64s-increase-default-stack-size-to-32kb.patch b/queue-6.1/powerpc-64s-increase-default-stack-size-to-32kb.patch
new file mode 100644 (file)
index 0000000..84330ee
--- /dev/null
@@ -0,0 +1,47 @@
+From 18f14afe281648e31ed35c9ad2fcb724c4838ad9 Mon Sep 17 00:00:00 2001
+From: Michael Ellerman <mpe@ellerman.id.au>
+Date: Fri, 15 Dec 2023 23:44:49 +1100
+Subject: powerpc/64s: Increase default stack size to 32KB
+
+From: Michael Ellerman <mpe@ellerman.id.au>
+
+commit 18f14afe281648e31ed35c9ad2fcb724c4838ad9 upstream.
+
+There are reports of kernels crashing due to stack overflow while
+running OpenShift (Kubernetes). The primary contributor to the stack
+usage seems to be openvswitch, which is used by OVN-Kubernetes (based on
+OVN (Open Virtual Network)), but NFS also contributes in some stack
+traces.
+
+There may be some opportunities to reduce stack usage in the openvswitch
+code, but doing so potentially require tradeoffs vs performance, and
+also requires testing across architectures.
+
+Looking at stack usage across the kernel (using -fstack-usage), shows
+that ppc64le stack frames are on average 50-100% larger than the
+equivalent function built for x86-64. Which is not surprising given the
+minimum stack frame size is 32 bytes on ppc64le vs 16 bytes on x86-64.
+
+So increase the default stack size to 32KB for the modern 64-bit Book3S
+platforms, ie. pseries (virtualised) and powernv (bare metal). That
+leaves the older systems like G5s, and the AmigaOne (pasemi) with a 16KB
+stack which should be sufficient on those machines.
+
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Signed-off-by: Aneesh Kumar K.V (IBM) <aneesh.kumar@kernel.org>
+Link: https://msgid.link/20231215124449.317597-1-mpe@ellerman.id.au
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/powerpc/Kconfig |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/arch/powerpc/Kconfig
++++ b/arch/powerpc/Kconfig
+@@ -806,6 +806,7 @@ config THREAD_SHIFT
+       int "Thread shift" if EXPERT
+       range 13 15
+       default "15" if PPC_256K_PAGES
++      default "15" if PPC_PSERIES || PPC_POWERNV
+       default "14" if PPC64
+       default "13"
+       help
diff --git a/queue-6.1/revert-usb-dwc3-don-t-reset-device-side-if-dwc3-was-configured-as-host-only.patch b/queue-6.1/revert-usb-dwc3-don-t-reset-device-side-if-dwc3-was-configured-as-host-only.patch
new file mode 100644 (file)
index 0000000..523a1fb
--- /dev/null
@@ -0,0 +1,42 @@
+From afe28cd686aeb77e8d9140d50fb1cf06a7ecb731 Mon Sep 17 00:00:00 2001
+From: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
+Date: Fri, 22 Dec 2023 22:11:33 +0000
+Subject: Revert "usb: dwc3: don't reset device side if dwc3 was configured as host-only"
+
+From: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
+
+commit afe28cd686aeb77e8d9140d50fb1cf06a7ecb731 upstream.
+
+This reverts commit e835c0a4e23c38531dcee5ef77e8d1cf462658c7.
+
+Don't omit soft-reset. During initialization, the driver may need to
+perform a soft reset to ensure the phy is ready when the controller
+updates the GCTL.PRTCAPDIR or other settings by issuing phy soft-reset.
+Many platforms often have access to DCTL register for soft-reset despite
+being host-only. If there are actual reported issues from the platforms
+that don't expose DCTL registers, then we will need to revisit (perhaps
+to teach dwc3 to perform xhci's soft-reset USBCMD.HCRST).
+
+Cc:  <stable@vger.kernel.org>
+Fixes: e835c0a4e23c ("usb: dwc3: don't reset device side if dwc3 was configured as host-only")
+Signed-off-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
+Link: https://lore.kernel.org/r/7668ab11a48f260820825274976eb41fec7f54d1.1703282469.git.Thinh.Nguyen@synopsys.com
+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
+@@ -277,9 +277,9 @@ int dwc3_core_soft_reset(struct dwc3 *dw
+       /*
+        * We're resetting only the device side because, if we're in host mode,
+        * XHCI driver will reset the host block. If dwc3 was configured for
+-       * host-only mode or current role is host, then we can return early.
++       * host-only mode, then we can return early.
+        */
+-      if (dwc->dr_mode == USB_DR_MODE_HOST || dwc->current_dr_role == DWC3_GCTL_PRTCAP_HOST)
++      if (dwc->current_dr_role == DWC3_GCTL_PRTCAP_HOST)
+               return 0;
+       reg = dwc3_readl(dwc->regs, DWC3_DCTL);
diff --git a/queue-6.1/revert-usb-dwc3-soft-reset-phy-on-probe-for-host.patch b/queue-6.1/revert-usb-dwc3-soft-reset-phy-on-probe-for-host.patch
new file mode 100644 (file)
index 0000000..7941686
--- /dev/null
@@ -0,0 +1,78 @@
+From 7059fbebcb00554c3f31e5b5d93ef6d2d96dc7b4 Mon Sep 17 00:00:00 2001
+From: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
+Date: Fri, 22 Dec 2023 22:11:27 +0000
+Subject: Revert "usb: dwc3: Soft reset phy on probe for host"
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
+
+commit 7059fbebcb00554c3f31e5b5d93ef6d2d96dc7b4 upstream.
+
+This reverts commit 8bea147dfdf823eaa8d3baeccc7aeb041b41944b.
+
+The phy soft reset GUSB2PHYCFG.PHYSOFTRST only applies to UTMI phy, not
+ULPI. This fix is incomplete.
+
+Cc:  <stable@vger.kernel.org>
+Fixes: 8bea147dfdf8 ("usb: dwc3: Soft reset phy on probe for host")
+Reported-by: Köry Maincent <kory.maincent@bootlin.com>
+Closes: https://lore.kernel.org/linux-usb/20231205151959.5236c231@kmaincent-XPS-13-7390
+Signed-off-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
+Link: https://lore.kernel.org/r/29a26593a60eba727de872a3e580a674807b3339.1703282469.git.Thinh.Nguyen@synopsys.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/dwc3/core.c |   39 +--------------------------------------
+ 1 file changed, 1 insertion(+), 38 deletions(-)
+
+--- a/drivers/usb/dwc3/core.c
++++ b/drivers/usb/dwc3/core.c
+@@ -279,46 +279,9 @@ int dwc3_core_soft_reset(struct dwc3 *dw
+        * XHCI driver will reset the host block. If dwc3 was configured for
+        * host-only mode or current role is host, then we can return early.
+        */
+-      if (dwc->current_dr_role == DWC3_GCTL_PRTCAP_HOST)
++      if (dwc->dr_mode == USB_DR_MODE_HOST || dwc->current_dr_role == DWC3_GCTL_PRTCAP_HOST)
+               return 0;
+-      /*
+-       * If the dr_mode is host and the dwc->current_dr_role is not the
+-       * corresponding DWC3_GCTL_PRTCAP_HOST, then the dwc3_core_init_mode
+-       * isn't executed yet. Ensure the phy is ready before the controller
+-       * updates the GCTL.PRTCAPDIR or other settings by soft-resetting
+-       * the phy.
+-       *
+-       * Note: GUSB3PIPECTL[n] and GUSB2PHYCFG[n] are port settings where n
+-       * is port index. If this is a multiport host, then we need to reset
+-       * all active ports.
+-       */
+-      if (dwc->dr_mode == USB_DR_MODE_HOST) {
+-              u32 usb3_port;
+-              u32 usb2_port;
+-
+-              usb3_port = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(0));
+-              usb3_port |= DWC3_GUSB3PIPECTL_PHYSOFTRST;
+-              dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), usb3_port);
+-
+-              usb2_port = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
+-              usb2_port |= DWC3_GUSB2PHYCFG_PHYSOFTRST;
+-              dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), usb2_port);
+-
+-              /* Small delay for phy reset assertion */
+-              usleep_range(1000, 2000);
+-
+-              usb3_port &= ~DWC3_GUSB3PIPECTL_PHYSOFTRST;
+-              dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), usb3_port);
+-
+-              usb2_port &= ~DWC3_GUSB2PHYCFG_PHYSOFTRST;
+-              dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), usb2_port);
+-
+-              /* Wait for clock synchronization */
+-              msleep(50);
+-              return 0;
+-      }
+-
+       reg = dwc3_readl(dwc->regs, DWC3_DCTL);
+       reg |= DWC3_DCTL_CSFTRST;
+       reg &= ~DWC3_DCTL_RUN_STOP;
diff --git a/queue-6.1/revert-usb-typec-class-fix-typec_altmode_put_partner-to-put-plugs.patch b/queue-6.1/revert-usb-typec-class-fix-typec_altmode_put_partner-to-put-plugs.patch
new file mode 100644 (file)
index 0000000..db0ce4c
--- /dev/null
@@ -0,0 +1,47 @@
+From 9c6b789e954fae73c548f39332bcc56bdf0d4373 Mon Sep 17 00:00:00 2001
+From: Heikki Krogerus <heikki.krogerus@linux.intel.com>
+Date: Tue, 2 Jan 2024 11:11:41 +0200
+Subject: Revert "usb: typec: class: fix typec_altmode_put_partner to put plugs"
+
+From: Heikki Krogerus <heikki.krogerus@linux.intel.com>
+
+commit 9c6b789e954fae73c548f39332bcc56bdf0d4373 upstream.
+
+This reverts commit b17b7fe6dd5c6ff74b38b0758ca799cdbb79e26e.
+
+That commit messed up the reference counting, so it needs to
+be rethought.
+
+Fixes: b17b7fe6dd5c ("usb: typec: class: fix typec_altmode_put_partner to put plugs")
+Cc:  <stable@vger.kernel.org>
+Cc: RD Babiera <rdbabiera@google.com>
+Reported-by: Chris Bainbridge <chris.bainbridge@gmail.com>
+Closes: https://lore.kernel.org/lkml/CAP-bSRb3SXpgo_BEdqZB-p1K5625fMegRZ17ZkPE1J8ZYgEHDg@mail.gmail.com/
+Signed-off-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
+Link: https://lore.kernel.org/r/20240102091142.2136472-1-heikki.krogerus@linux.intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/typec/class.c |    5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+--- a/drivers/usb/typec/class.c
++++ b/drivers/usb/typec/class.c
+@@ -267,7 +267,7 @@ static void typec_altmode_put_partner(st
+       if (!partner)
+               return;
+-      adev = &altmode->adev;
++      adev = &partner->adev;
+       if (is_typec_plug(adev->dev.parent)) {
+               struct typec_plug *plug = to_typec_plug(adev->dev.parent);
+@@ -497,8 +497,7 @@ static void typec_altmode_release(struct
+ {
+       struct altmode *alt = to_altmode(to_typec_altmode(dev));
+-      if (!is_typec_port(dev->parent))
+-              typec_altmode_put_partner(alt);
++      typec_altmode_put_partner(alt);
+       altmode_id_remove(alt->adev.dev.parent, alt->id);
+       kfree(alt);
diff --git a/queue-6.1/serial-8250_bcm2835aux-restore-clock-error-handling.patch b/queue-6.1/serial-8250_bcm2835aux-restore-clock-error-handling.patch
new file mode 100644 (file)
index 0000000..d1dc698
--- /dev/null
@@ -0,0 +1,34 @@
+From 83e571f054cd742eb9a46d46ef05193904adf53f Mon Sep 17 00:00:00 2001
+From: Stefan Wahren <wahrenst@gmx.net>
+Date: Wed, 20 Dec 2023 12:43:34 +0100
+Subject: serial: 8250_bcm2835aux: Restore clock error handling
+
+From: Stefan Wahren <wahrenst@gmx.net>
+
+commit 83e571f054cd742eb9a46d46ef05193904adf53f upstream.
+
+The commit fcc446c8aa63 ("serial: 8250_bcm2835aux: Add ACPI support")
+dropped the error handling for clock acquiring. But even an optional
+clock needs this.
+
+Fixes: fcc446c8aa63 ("serial: 8250_bcm2835aux: Add ACPI support")
+Cc: stable <stable@kernel.org>
+Signed-off-by: Stefan Wahren <wahrenst@gmx.net>
+Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
+Link: https://lore.kernel.org/r/20231220114334.4712-1-wahrenst@gmx.net
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/tty/serial/8250/8250_bcm2835aux.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/tty/serial/8250/8250_bcm2835aux.c
++++ b/drivers/tty/serial/8250/8250_bcm2835aux.c
+@@ -119,6 +119,8 @@ static int bcm2835aux_serial_probe(struc
+       /* get the clock - this also enables the HW */
+       data->clk = devm_clk_get_optional(&pdev->dev, NULL);
++      if (IS_ERR(data->clk))
++              return dev_err_probe(&pdev->dev, PTR_ERR(data->clk), "could not get clk\n");
+       /* get the interrupt */
+       ret = platform_get_irq(pdev, 0);
diff --git a/queue-6.1/serial-8250_exar-set-missing-rs485_supported-flag.patch b/queue-6.1/serial-8250_exar-set-missing-rs485_supported-flag.patch
new file mode 100644 (file)
index 0000000..1757f27
--- /dev/null
@@ -0,0 +1,53 @@
+From 0c2a5f471ce58bca8f8ab5fcb911aff91eaaa5eb Mon Sep 17 00:00:00 2001
+From: Lino Sanfilippo <l.sanfilippo@kunbus.com>
+Date: Wed, 3 Jan 2024 07:18:18 +0100
+Subject: serial: 8250_exar: Set missing rs485_supported flag
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Lino Sanfilippo <l.sanfilippo@kunbus.com>
+
+commit 0c2a5f471ce58bca8f8ab5fcb911aff91eaaa5eb upstream.
+
+The UART supports an auto-RTS mode in which the RTS pin is automatically
+activated during transmission. So mark this mode as being supported even
+if RTS is not controlled by the driver but the UART.
+
+Also the serial core expects now at least one of both modes rts-on-send or
+rts-after-send to be supported. This is since during sanitization
+unsupported flags are deleted from a RS485 configuration set by userspace.
+However if the configuration ends up with both flags unset, the core prints
+a warning since it considers such a configuration invalid (see
+uart_sanitize_serial_rs485()).
+
+Cc:  <stable@vger.kernel.org>
+Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Signed-off-by: Lino Sanfilippo <l.sanfilippo@kunbus.com>
+Link: https://lore.kernel.org/r/20240103061818.564-8-l.sanfilippo@kunbus.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/tty/serial/8250/8250_exar.c |    5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+--- a/drivers/tty/serial/8250/8250_exar.c
++++ b/drivers/tty/serial/8250/8250_exar.c
+@@ -442,7 +442,7 @@ static int generic_rs485_config(struct u
+ }
+ static const struct serial_rs485 generic_rs485_supported = {
+-      .flags = SER_RS485_ENABLED,
++      .flags = SER_RS485_ENABLED | SER_RS485_RTS_ON_SEND,
+ };
+ static const struct exar8250_platform exar8250_default_platform = {
+@@ -486,7 +486,8 @@ static int iot2040_rs485_config(struct u
+ }
+ static const struct serial_rs485 iot2040_rs485_supported = {
+-      .flags = SER_RS485_ENABLED | SER_RS485_RX_DURING_TX | SER_RS485_TERMINATE_BUS,
++      .flags = SER_RS485_ENABLED | SER_RS485_RTS_ON_SEND |
++               SER_RS485_RX_DURING_TX | SER_RS485_TERMINATE_BUS,
+ };
+ static const struct property_entry iot2040_gpio_properties[] = {
diff --git a/queue-6.1/serial-core-fix-sanitizing-check-for-rts-settings.patch b/queue-6.1/serial-core-fix-sanitizing-check-for-rts-settings.patch
new file mode 100644 (file)
index 0000000..e6005b9
--- /dev/null
@@ -0,0 +1,79 @@
+From 4afeced55baa391490b61ed9164867e2927353ed Mon Sep 17 00:00:00 2001
+From: Lino Sanfilippo <l.sanfilippo@kunbus.com>
+Date: Wed, 3 Jan 2024 07:18:14 +0100
+Subject: serial: core: fix sanitizing check for RTS settings
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Lino Sanfilippo <l.sanfilippo@kunbus.com>
+
+commit 4afeced55baa391490b61ed9164867e2927353ed upstream.
+
+Among other things uart_sanitize_serial_rs485() tests the sanity of the RTS
+settings in a RS485 configuration that has been passed by userspace.
+If RTS-on-send and RTS-after-send are both set or unset the configuration
+is adjusted and RTS-after-send is disabled and RTS-on-send enabled.
+
+This however makes only sense if both RTS modes are actually supported by
+the driver.
+
+With commit be2e2cb1d281 ("serial: Sanitize rs485_struct") the code does
+take the driver support into account but only checks if one of both RTS
+modes are supported. This may lead to the errorneous result of RTS-on-send
+being set even if only RTS-after-send is supported.
+
+Fix this by changing the implemented logic: First clear all unsupported
+flags in the RS485 configuration, then adjust an invalid RTS setting by
+taking into account which RTS mode is supported.
+
+Cc:  <stable@vger.kernel.org>
+Fixes: be2e2cb1d281 ("serial: Sanitize rs485_struct")
+Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Signed-off-by: Lino Sanfilippo <l.sanfilippo@kunbus.com>
+Link: https://lore.kernel.org/r/20240103061818.564-4-l.sanfilippo@kunbus.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/tty/serial/serial_core.c |   28 ++++++++++++++++++----------
+ 1 file changed, 18 insertions(+), 10 deletions(-)
+
+--- a/drivers/tty/serial/serial_core.c
++++ b/drivers/tty/serial/serial_core.c
+@@ -1353,19 +1353,27 @@ static void uart_sanitize_serial_rs485(s
+               return;
+       }
++      rs485->flags &= supported_flags;
++
+       /* Pick sane settings if the user hasn't */
+-      if ((supported_flags & (SER_RS485_RTS_ON_SEND|SER_RS485_RTS_AFTER_SEND)) &&
+-          !(rs485->flags & SER_RS485_RTS_ON_SEND) ==
++      if (!(rs485->flags & SER_RS485_RTS_ON_SEND) ==
+           !(rs485->flags & SER_RS485_RTS_AFTER_SEND)) {
+-              dev_warn_ratelimited(port->dev,
+-                      "%s (%d): invalid RTS setting, using RTS_ON_SEND instead\n",
+-                      port->name, port->line);
+-              rs485->flags |= SER_RS485_RTS_ON_SEND;
+-              rs485->flags &= ~SER_RS485_RTS_AFTER_SEND;
+-              supported_flags |= SER_RS485_RTS_ON_SEND|SER_RS485_RTS_AFTER_SEND;
+-      }
++              if (supported_flags & SER_RS485_RTS_ON_SEND) {
++                      rs485->flags |= SER_RS485_RTS_ON_SEND;
++                      rs485->flags &= ~SER_RS485_RTS_AFTER_SEND;
+-      rs485->flags &= supported_flags;
++                      dev_warn_ratelimited(port->dev,
++                              "%s (%d): invalid RTS setting, using RTS_ON_SEND instead\n",
++                              port->name, port->line);
++              } else {
++                      rs485->flags |= SER_RS485_RTS_AFTER_SEND;
++                      rs485->flags &= ~SER_RS485_RTS_ON_SEND;
++
++                      dev_warn_ratelimited(port->dev,
++                              "%s (%d): invalid RTS setting, using RTS_AFTER_SEND instead\n",
++                              port->name, port->line);
++              }
++      }
+       uart_sanitize_serial_rs485_delays(port, rs485);
diff --git a/queue-6.1/serial-core-imx-do-not-set-rs485-enabled-if-it-is-not-supported.patch b/queue-6.1/serial-core-imx-do-not-set-rs485-enabled-if-it-is-not-supported.patch
new file mode 100644 (file)
index 0000000..451dd29
--- /dev/null
@@ -0,0 +1,85 @@
+From 74eab89b26ac433ad857292f4707b43c1a8f0209 Mon Sep 17 00:00:00 2001
+From: Lino Sanfilippo <l.sanfilippo@kunbus.com>
+Date: Wed, 3 Jan 2024 07:18:16 +0100
+Subject: serial: core, imx: do not set RS485 enabled if it is not supported
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Lino Sanfilippo <l.sanfilippo@kunbus.com>
+
+commit 74eab89b26ac433ad857292f4707b43c1a8f0209 upstream.
+
+If the imx driver cannot support RS485 it nullifies the ports
+rs485_supported structure. But it still calls uart_get_rs485_mode() which
+may set the RS485_ENABLED flag nevertheless.
+
+This may lead to an attempt to configure RS485 even if it is not supported
+when the flag is evaluated in uart_configure_port() at port startup.
+
+Avoid this by bailing out of uart_get_rs485_mode() if the RS485_ENABLED
+flag is not supported by the caller.
+
+With this fix a check for RTS availability is now obsolete in the imx
+driver, since it can not evaluate to true any more. So remove this check.
+
+Furthermore the explicit nullifcation of rs485_supported is not needed,
+since the memory has already been set to zeros at allocation. So remove
+this, too.
+
+Fixes: 00d7a00e2a6f ("serial: imx: Fill in rs485_supported")
+Cc: Shawn Guo <shawnguo@kernel.org>
+Cc: Sascha Hauer <s.hauer@pengutronix.de>
+Cc:  <stable@vger.kernel.org>
+Suggested-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+Signed-off-by: Lino Sanfilippo <l.sanfilippo@kunbus.com>
+Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Link: https://lore.kernel.org/r/20240103061818.564-6-l.sanfilippo@kunbus.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/tty/serial/imx.c         |    7 -------
+ drivers/tty/serial/serial_core.c |    3 +++
+ 2 files changed, 3 insertions(+), 7 deletions(-)
+
+--- a/drivers/tty/serial/imx.c
++++ b/drivers/tty/serial/imx.c
+@@ -2229,7 +2229,6 @@ static enum hrtimer_restart imx_trigger_
+       return HRTIMER_NORESTART;
+ }
+-static const struct serial_rs485 imx_no_rs485 = {};   /* No RS485 if no RTS */
+ static const struct serial_rs485 imx_rs485_supported = {
+       .flags = SER_RS485_ENABLED | SER_RS485_RTS_ON_SEND | SER_RS485_RTS_AFTER_SEND |
+                SER_RS485_RX_DURING_TX,
+@@ -2319,8 +2318,6 @@ static int imx_uart_probe(struct platfor
+       /* RTS is required to control the RS485 transmitter */
+       if (sport->have_rtscts || sport->have_rtsgpio)
+               sport->port.rs485_supported = imx_rs485_supported;
+-      else
+-              sport->port.rs485_supported = imx_no_rs485;
+       sport->port.flags = UPF_BOOT_AUTOCONF;
+       timer_setup(&sport->timer, imx_uart_timeout, 0);
+@@ -2364,10 +2361,6 @@ static int imx_uart_probe(struct platfor
+               return ret;
+       }
+-      if (sport->port.rs485.flags & SER_RS485_ENABLED &&
+-          (!sport->have_rtscts && !sport->have_rtsgpio))
+-              dev_err(&pdev->dev, "no RTS control, disabling rs485\n");
+-
+       /*
+        * If using the i.MX UART RTS/CTS control then the RTS (CTS_B)
+        * signal cannot be set low during transmission in case the
+--- a/drivers/tty/serial/serial_core.c
++++ b/drivers/tty/serial/serial_core.c
+@@ -3428,6 +3428,9 @@ int uart_get_rs485_mode(struct uart_port
+       u32 rs485_delay[2];
+       int ret;
++      if (!(port->rs485_supported.flags & SER_RS485_ENABLED))
++              return 0;
++
+       ret = device_property_read_u32_array(dev, "rs485-rts-delay",
+                                            rs485_delay, 2);
+       if (!ret) {
diff --git a/queue-6.1/serial-core-make-sure-rs485-cannot-be-enabled-when-it-is-not-supported.patch b/queue-6.1/serial-core-make-sure-rs485-cannot-be-enabled-when-it-is-not-supported.patch
new file mode 100644 (file)
index 0000000..152abb1
--- /dev/null
@@ -0,0 +1,52 @@
+From c73986913fa47e71e0b1ad7f039f6444915e8810 Mon Sep 17 00:00:00 2001
+From: Lino Sanfilippo <l.sanfilippo@kunbus.com>
+Date: Wed, 3 Jan 2024 07:18:15 +0100
+Subject: serial: core: make sure RS485 cannot be enabled when it is not supported
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Lino Sanfilippo <l.sanfilippo@kunbus.com>
+
+commit c73986913fa47e71e0b1ad7f039f6444915e8810 upstream.
+
+Some uart drivers specify a rs485_config() function and then decide later
+to disable RS485 support for some reason (e.g. imx and ar933).
+
+In these cases userspace may be able to activate RS485 via TIOCSRS485
+nevertheless, since in uart_set_rs485_config() an existing rs485_config()
+function indicates that RS485 is supported.
+
+Make sure that this is not longer possible by checking the uarts
+rs485_supported.flags instead and bailing out if SER_RS485_ENABLED is not
+set.
+
+Furthermore instead of returning an empty structure return -ENOTTY if the
+RS485 configuration is requested via TIOCGRS485 but RS485 is not supported.
+This has a small impact on userspace visibility but it is consistent with
+the -ENOTTY error for TIOCGRS485.
+
+Fixes: e849145e1fdd ("serial: ar933x: Fill in rs485_supported")
+Fixes: 55e18c6b6d42 ("serial: imx: Remove serial_rs485 sanitization")
+Cc: Shawn Guo <shawnguo@kernel.org>
+Cc: Sascha Hauer <s.hauer@pengutronix.de>
+Cc:  <stable@vger.kernel.org>
+Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Signed-off-by: Lino Sanfilippo <l.sanfilippo@kunbus.com>
+Link: https://lore.kernel.org/r/20240103061818.564-5-l.sanfilippo@kunbus.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/tty/serial/serial_core.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/tty/serial/serial_core.c
++++ b/drivers/tty/serial/serial_core.c
+@@ -1436,7 +1436,7 @@ static int uart_set_rs485_config(struct
+       int ret;
+       unsigned long flags;
+-      if (!port->rs485_config)
++      if (!(port->rs485_supported.flags & SER_RS485_ENABLED))
+               return -ENOTTY;
+       if (copy_from_user(&rs485, rs485_user, sizeof(*rs485_user)))
diff --git a/queue-6.1/serial-imx-ensure-that-imx_uart_rs485_config-is-called-with-enabled-clock.patch b/queue-6.1/serial-imx-ensure-that-imx_uart_rs485_config-is-called-with-enabled-clock.patch
new file mode 100644 (file)
index 0000000..4c6ba05
--- /dev/null
@@ -0,0 +1,104 @@
+From 7c45eaa813476bd195ac1227a64b52f9cf2e2030 Mon Sep 17 00:00:00 2001
+From: Christoph Niedermaier <cniedermaier@dh-electronics.com>
+Date: Tue, 26 Dec 2023 12:36:47 +0100
+Subject: serial: imx: Ensure that imx_uart_rs485_config() is called with enabled clock
+
+From: Christoph Niedermaier <cniedermaier@dh-electronics.com>
+
+commit 7c45eaa813476bd195ac1227a64b52f9cf2e2030 upstream.
+
+There are register accesses in the function imx_uart_rs485_config(). The
+clock must be enabled for these accesses. This was ensured by calling it
+via the function uart_rs485_config() in the probe() function within the
+range where the clock is enabled. With the commit 7c7f9bc986e6 ("serial:
+Deassert Transmit Enable on probe in driver-specific way") it was removed
+from the probe() function and is now only called through the function
+uart_add_one_port() which is located at the end of the probe() function.
+But the clock is already switched off in this area. To ensure that the
+clock is enabled during register access, move the disabling of the clock
+to the very end of the probe() function. To avoid leaking enabled clocks
+on error also add an error path for exiting with disabling the clock.
+
+Fixes: 7c7f9bc986e6 ("serial: Deassert Transmit Enable on probe in driver-specific way")
+Cc: stable <stable@kernel.org>
+Signed-off-by: Christoph Niedermaier <cniedermaier@dh-electronics.com>
+Reviewed-by: Lukas Wunner <lukas@wunner.de>
+Link: https://lore.kernel.org/r/20231226113647.39376-1-cniedermaier@dh-electronics.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/tty/serial/imx.c |   23 ++++++++++++-----------
+ 1 file changed, 12 insertions(+), 11 deletions(-)
+
+--- a/drivers/tty/serial/imx.c
++++ b/drivers/tty/serial/imx.c
+@@ -2356,10 +2356,8 @@ static int imx_uart_probe(struct platfor
+       sport->ufcr = readl(sport->port.membase + UFCR);
+       ret = uart_get_rs485_mode(&sport->port);
+-      if (ret) {
+-              clk_disable_unprepare(sport->clk_ipg);
+-              return ret;
+-      }
++      if (ret)
++              goto err_clk;
+       /*
+        * If using the i.MX UART RTS/CTS control then the RTS (CTS_B)
+@@ -2439,8 +2437,6 @@ static int imx_uart_probe(struct platfor
+               imx_uart_writel(sport, ucr3, UCR3);
+       }
+-      clk_disable_unprepare(sport->clk_ipg);
+-
+       hrtimer_init(&sport->trigger_start_tx, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
+       hrtimer_init(&sport->trigger_stop_tx, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
+       sport->trigger_start_tx.function = imx_trigger_start_tx;
+@@ -2456,7 +2452,7 @@ static int imx_uart_probe(struct platfor
+               if (ret) {
+                       dev_err(&pdev->dev, "failed to request rx irq: %d\n",
+                               ret);
+-                      return ret;
++                      goto err_clk;
+               }
+               ret = devm_request_irq(&pdev->dev, txirq, imx_uart_txint, 0,
+@@ -2464,7 +2460,7 @@ static int imx_uart_probe(struct platfor
+               if (ret) {
+                       dev_err(&pdev->dev, "failed to request tx irq: %d\n",
+                               ret);
+-                      return ret;
++                      goto err_clk;
+               }
+               ret = devm_request_irq(&pdev->dev, rtsirq, imx_uart_rtsint, 0,
+@@ -2472,14 +2468,14 @@ static int imx_uart_probe(struct platfor
+               if (ret) {
+                       dev_err(&pdev->dev, "failed to request rts irq: %d\n",
+                               ret);
+-                      return ret;
++                      goto err_clk;
+               }
+       } else {
+               ret = devm_request_irq(&pdev->dev, rxirq, imx_uart_int, 0,
+                                      dev_name(&pdev->dev), sport);
+               if (ret) {
+                       dev_err(&pdev->dev, "failed to request irq: %d\n", ret);
+-                      return ret;
++                      goto err_clk;
+               }
+       }
+@@ -2487,7 +2483,12 @@ static int imx_uart_probe(struct platfor
+       platform_set_drvdata(pdev, sport);
+-      return uart_add_one_port(&imx_uart_uart_driver, &sport->port);
++      ret = uart_add_one_port(&imx_uart_uart_driver, &sport->port);
++
++err_clk:
++      clk_disable_unprepare(sport->clk_ipg);
++
++      return ret;
+ }
+ static int imx_uart_remove(struct platform_device *pdev)
diff --git a/queue-6.1/serial-omap-do-not-override-settings-for-rs485-support.patch b/queue-6.1/serial-omap-do-not-override-settings-for-rs485-support.patch
new file mode 100644 (file)
index 0000000..ab9100a
--- /dev/null
@@ -0,0 +1,104 @@
+From 51f93776b84dee23e44a7be880736669a01cec2b Mon Sep 17 00:00:00 2001
+From: Lino Sanfilippo <l.sanfilippo@kunbus.com>
+Date: Wed, 3 Jan 2024 07:18:17 +0100
+Subject: serial: omap: do not override settings for RS485 support
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Lino Sanfilippo <l.sanfilippo@kunbus.com>
+
+commit 51f93776b84dee23e44a7be880736669a01cec2b upstream.
+
+The drivers RS485 support is deactivated if there is no RTS GPIO available.
+This is done by nullifying the ports rs485_supported struct. After that
+however the settings in serial_omap_rs485_supported are assigned to the
+same structure unconditionally, which results in an unintended reactivation
+of RS485 support.
+
+Fix this by moving the assignment to the beginning of
+serial_omap_probe_rs485() and thus before uart_get_rs485_mode() gets
+called.
+
+Also replace the assignment of rs485_config() to have the complete RS485
+setup in one function.
+
+Fixes: e2752ae3cfc9 ("serial: omap: Disallow RS-485 if rts-gpio is not specified")
+Cc:  <stable@vger.kernel.org>
+Signed-off-by: Lino Sanfilippo <l.sanfilippo@kunbus.com>
+Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Link: https://lore.kernel.org/r/20240103061818.564-7-l.sanfilippo@kunbus.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/tty/serial/omap-serial.c |   27 ++++++++++++++-------------
+ 1 file changed, 14 insertions(+), 13 deletions(-)
+
+--- a/drivers/tty/serial/omap-serial.c
++++ b/drivers/tty/serial/omap-serial.c
+@@ -1512,6 +1512,13 @@ static struct omap_uart_port_info *of_ge
+       return omap_up_info;
+ }
++static const struct serial_rs485 serial_omap_rs485_supported = {
++      .flags = SER_RS485_ENABLED | SER_RS485_RTS_ON_SEND | SER_RS485_RTS_AFTER_SEND |
++               SER_RS485_RX_DURING_TX,
++      .delay_rts_before_send = 1,
++      .delay_rts_after_send = 1,
++};
++
+ static int serial_omap_probe_rs485(struct uart_omap_port *up,
+                                  struct device *dev)
+ {
+@@ -1526,6 +1533,9 @@ static int serial_omap_probe_rs485(struc
+       if (!np)
+               return 0;
++      up->port.rs485_config = serial_omap_config_rs485;
++      up->port.rs485_supported = serial_omap_rs485_supported;
++
+       ret = uart_get_rs485_mode(&up->port);
+       if (ret)
+               return ret;
+@@ -1560,13 +1570,6 @@ static int serial_omap_probe_rs485(struc
+       return 0;
+ }
+-static const struct serial_rs485 serial_omap_rs485_supported = {
+-      .flags = SER_RS485_ENABLED | SER_RS485_RTS_ON_SEND | SER_RS485_RTS_AFTER_SEND |
+-               SER_RS485_RX_DURING_TX,
+-      .delay_rts_before_send = 1,
+-      .delay_rts_after_send = 1,
+-};
+-
+ static int serial_omap_probe(struct platform_device *pdev)
+ {
+       struct omap_uart_port_info *omap_up_info = dev_get_platdata(&pdev->dev);
+@@ -1634,17 +1637,11 @@ static int serial_omap_probe(struct plat
+               dev_info(up->port.dev, "no wakeirq for uart%d\n",
+                        up->port.line);
+-      ret = serial_omap_probe_rs485(up, &pdev->dev);
+-      if (ret < 0)
+-              goto err_rs485;
+-
+       sprintf(up->name, "OMAP UART%d", up->port.line);
+       up->port.mapbase = mem->start;
+       up->port.membase = base;
+       up->port.flags = omap_up_info->flags;
+       up->port.uartclk = omap_up_info->uartclk;
+-      up->port.rs485_config = serial_omap_config_rs485;
+-      up->port.rs485_supported = serial_omap_rs485_supported;
+       if (!up->port.uartclk) {
+               up->port.uartclk = DEFAULT_CLK_SPEED;
+               dev_warn(&pdev->dev,
+@@ -1652,6 +1649,10 @@ static int serial_omap_probe(struct plat
+                        DEFAULT_CLK_SPEED);
+       }
++      ret = serial_omap_probe_rs485(up, &pdev->dev);
++      if (ret < 0)
++              goto err_rs485;
++
+       up->latency = PM_QOS_CPU_LATENCY_DEFAULT_VALUE;
+       up->calc_latency = PM_QOS_CPU_LATENCY_DEFAULT_VALUE;
+       cpu_latency_qos_add_request(&up->pm_qos_request, up->latency);
index be458280e61b4e1e6ebb287774301f1cb4f301ae..17846e6e8e11fbe636fed660f9fa4f7663c12bfb 100644 (file)
@@ -251,3 +251,27 @@ binder-fix-async-space-check-for-0-sized-buffers.patch
 binder-fix-unused-alloc-free_async_space.patch
 mips-smp-call-rcutree_report_cpu_starting-earlier.patch
 input-atkbd-use-ab83-as-id-when-skipping-the-getid-command.patch
+xen-netback-don-t-produce-zero-size-skb-frags.patch
+binder-fix-race-between-mmput-and-do_exit.patch
+clocksource-drivers-timer-ti-dm-fix-make-w-n-kerneldoc-warnings.patch
+powerpc-64s-increase-default-stack-size-to-32kb.patch
+tick-sched-fix-idle-and-iowait-sleeptime-accounting-vs-cpu-hotplug.patch
+usb-phy-mxs-remove-config_usb_otg-condition-for-mxs_phy_is_otg_host.patch
+usb-dwc-ep0-update-request-status-in-dwc3_ep0_stall_restart.patch
+usb-dwc3-gadget-handle-ep0-request-dequeuing-properly.patch
+revert-usb-dwc3-soft-reset-phy-on-probe-for-host.patch
+revert-usb-dwc3-don-t-reset-device-side-if-dwc3-was-configured-as-host-only.patch
+usb-chipidea-wait-controller-resume-finished-for-wakeup-irq.patch
+usb-cdns3-fix-uvc-failure-work-since-sg-support-enabled.patch
+usb-cdns3-fix-iso-transfer-error-when-mult-is-not-zero.patch
+usb-cdns3-fix-uvc-fail-when-dma-cross-4k-boundery-since-sg-enabled.patch
+revert-usb-typec-class-fix-typec_altmode_put_partner-to-put-plugs.patch
+usb-typec-class-fix-typec_altmode_put_partner-to-put-plugs.patch
+usb-mon-fix-atomicity-violation-in-mon_bin_vma_fault.patch
+serial-core-fix-sanitizing-check-for-rts-settings.patch
+serial-core-make-sure-rs485-cannot-be-enabled-when-it-is-not-supported.patch
+serial-8250_bcm2835aux-restore-clock-error-handling.patch
+serial-core-imx-do-not-set-rs485-enabled-if-it-is-not-supported.patch
+serial-imx-ensure-that-imx_uart_rs485_config-is-called-with-enabled-clock.patch
+serial-8250_exar-set-missing-rs485_supported-flag.patch
+serial-omap-do-not-override-settings-for-rs485-support.patch
diff --git a/queue-6.1/tick-sched-fix-idle-and-iowait-sleeptime-accounting-vs-cpu-hotplug.patch b/queue-6.1/tick-sched-fix-idle-and-iowait-sleeptime-accounting-vs-cpu-hotplug.patch
new file mode 100644 (file)
index 0000000..0546645
--- /dev/null
@@ -0,0 +1,85 @@
+From 71fee48fb772ac4f6cfa63dbebc5629de8b4cc09 Mon Sep 17 00:00:00 2001
+From: Heiko Carstens <hca@linux.ibm.com>
+Date: Mon, 15 Jan 2024 17:35:55 +0100
+Subject: tick-sched: Fix idle and iowait sleeptime accounting vs CPU hotplug
+
+From: Heiko Carstens <hca@linux.ibm.com>
+
+commit 71fee48fb772ac4f6cfa63dbebc5629de8b4cc09 upstream.
+
+When offlining and onlining CPUs the overall reported idle and iowait
+times as reported by /proc/stat jump backward and forward:
+
+cpu  132 0 176 225249 47 6 6 21 0 0
+cpu0 80 0 115 112575 33 3 4 18 0 0
+cpu1 52 0 60 112673 13 3 1 2 0 0
+
+cpu  133 0 177 226681 47 6 6 21 0 0
+cpu0 80 0 116 113387 33 3 4 18 0 0
+
+cpu  133 0 178 114431 33 6 6 21 0 0 <---- jump backward
+cpu0 80 0 116 114247 33 3 4 18 0 0
+cpu1 52 0 61 183 0 3 1 2 0 0        <---- idle + iowait start with 0
+
+cpu  133 0 178 228956 47 6 6 21 0 0 <---- jump forward
+cpu0 81 0 117 114929 33 3 4 18 0 0
+
+Reason for this is that get_idle_time() in fs/proc/stat.c has different
+sources for both values depending on if a CPU is online or offline:
+
+- if a CPU is online the values may be taken from its per cpu
+  tick_cpu_sched structure
+
+- if a CPU is offline the values are taken from its per cpu cpustat
+  structure
+
+The problem is that the per cpu tick_cpu_sched structure is set to zero on
+CPU offline. See tick_cancel_sched_timer() in kernel/time/tick-sched.c.
+
+Therefore when a CPU is brought offline and online afterwards both its idle
+and iowait sleeptime will be zero, causing a jump backward in total system
+idle and iowait sleeptime. In a similar way if a CPU is then brought
+offline again the total idle and iowait sleeptimes will jump forward.
+
+It looks like this behavior was introduced with commit 4b0c0f294f60
+("tick: Cleanup NOHZ per cpu data on cpu down").
+
+This was only noticed now on s390, since we switched to generic idle time
+reporting with commit be76ea614460 ("s390/idle: remove arch_cpu_idle_time()
+and corresponding code").
+
+Fix this by preserving the values of idle_sleeptime and iowait_sleeptime
+members of the per-cpu tick_sched structure on CPU hotplug.
+
+Fixes: 4b0c0f294f60 ("tick: Cleanup NOHZ per cpu data on cpu down")
+Reported-by: Gerald Schaefer <gerald.schaefer@linux.ibm.com>
+Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Reviewed-by: Frederic Weisbecker <frederic@kernel.org>
+Link: https://lore.kernel.org/r/20240115163555.1004144-1-hca@linux.ibm.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ kernel/time/tick-sched.c |    5 +++++
+ 1 file changed, 5 insertions(+)
+
+--- a/kernel/time/tick-sched.c
++++ b/kernel/time/tick-sched.c
+@@ -1556,13 +1556,18 @@ void tick_setup_sched_timer(void)
+ void tick_cancel_sched_timer(int cpu)
+ {
+       struct tick_sched *ts = &per_cpu(tick_cpu_sched, cpu);
++      ktime_t idle_sleeptime, iowait_sleeptime;
+ # ifdef CONFIG_HIGH_RES_TIMERS
+       if (ts->sched_timer.base)
+               hrtimer_cancel(&ts->sched_timer);
+ # endif
++      idle_sleeptime = ts->idle_sleeptime;
++      iowait_sleeptime = ts->iowait_sleeptime;
+       memset(ts, 0, sizeof(*ts));
++      ts->idle_sleeptime = idle_sleeptime;
++      ts->iowait_sleeptime = iowait_sleeptime;
+ }
+ #endif
diff --git a/queue-6.1/usb-cdns3-fix-iso-transfer-error-when-mult-is-not-zero.patch b/queue-6.1/usb-cdns3-fix-iso-transfer-error-when-mult-is-not-zero.patch
new file mode 100644 (file)
index 0000000..0ae2915
--- /dev/null
@@ -0,0 +1,172 @@
+From 92f02efa1d86d7dcaef7f38a5fe3396c4e88a93c Mon Sep 17 00:00:00 2001
+From: Frank Li <Frank.Li@nxp.com>
+Date: Sun, 24 Dec 2023 10:38:14 -0500
+Subject: usb: cdns3: fix iso transfer error when mult is not zero
+
+From: Frank Li <Frank.Li@nxp.com>
+
+commit 92f02efa1d86d7dcaef7f38a5fe3396c4e88a93c upstream.
+
+ISO basic transfer is
+       ITP(SOF) Package_0 Package_1 ... Package_n
+
+CDNS3 DMA start dma transfer from memmory to internal FIFO when get SOF,
+controller will transfer data to usb bus from internal FIFO when get IN
+token.
+
+According USB spec defination:
+       Maximum number of packets = (bMaxBurst + 1) * (Mult + 1)
+
+Internal memory should be the same as (bMaxBurst + 1) * (Mult + 1). DMA
+don't fetch data advance when ISO transfer, so only reserve
+(bMaxBurst + 1) * (Mult + 1) internal memory for ISO transfer.
+
+Need save Mult and bMaxBurst information and set it into EP_CFG register,
+otherwise only 1 package is sent by controller, other package will be
+lost.
+
+Cc:  <stable@vger.kernel.org>
+Fixes: 7733f6c32e36 ("usb: cdns3: Add Cadence USB3 DRD Driver")
+Signed-off-by: Frank Li <Frank.Li@nxp.com>
+Link: https://lore.kernel.org/r/20231224153816.1664687-3-Frank.Li@nxp.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/cdns3/cdns3-gadget.c |   59 +++++++++++++++++++++++----------------
+ drivers/usb/cdns3/cdns3-gadget.h |    3 +
+ 2 files changed, 39 insertions(+), 23 deletions(-)
+
+--- a/drivers/usb/cdns3/cdns3-gadget.c
++++ b/drivers/usb/cdns3/cdns3-gadget.c
+@@ -2062,11 +2062,10 @@ int cdns3_ep_config(struct cdns3_endpoin
+       bool is_iso_ep = (priv_ep->type == USB_ENDPOINT_XFER_ISOC);
+       struct cdns3_device *priv_dev = priv_ep->cdns3_dev;
+       u32 bEndpointAddress = priv_ep->num | priv_ep->dir;
+-      u32 max_packet_size = 0;
+-      u8 maxburst = 0;
++      u32 max_packet_size = priv_ep->wMaxPacketSize;
++      u8 maxburst = priv_ep->bMaxBurst;
+       u32 ep_cfg = 0;
+       u8 buffering;
+-      u8 mult = 0;
+       int ret;
+       buffering = priv_dev->ep_buf_size - 1;
+@@ -2088,8 +2087,7 @@ int cdns3_ep_config(struct cdns3_endpoin
+               break;
+       default:
+               ep_cfg = EP_CFG_EPTYPE(USB_ENDPOINT_XFER_ISOC);
+-              mult = priv_dev->ep_iso_burst - 1;
+-              buffering = mult + 1;
++              buffering = (priv_ep->bMaxBurst + 1) * (priv_ep->mult + 1) - 1;
+       }
+       switch (priv_dev->gadget.speed) {
+@@ -2100,17 +2098,8 @@ int cdns3_ep_config(struct cdns3_endpoin
+               max_packet_size = is_iso_ep ? 1024 : 512;
+               break;
+       case USB_SPEED_SUPER:
+-              /* It's limitation that driver assumes in driver. */
+-              mult = 0;
+-              max_packet_size = 1024;
+-              if (priv_ep->type == USB_ENDPOINT_XFER_ISOC) {
+-                      maxburst = priv_dev->ep_iso_burst - 1;
+-                      buffering = (mult + 1) *
+-                                  (maxburst + 1);
+-
+-                      if (priv_ep->interval > 1)
+-                              buffering++;
+-              } else {
++              if (priv_ep->type != USB_ENDPOINT_XFER_ISOC) {
++                      max_packet_size = 1024;
+                       maxburst = priv_dev->ep_buf_size - 1;
+               }
+               break;
+@@ -2139,7 +2128,6 @@ int cdns3_ep_config(struct cdns3_endpoin
+       if (priv_dev->dev_ver < DEV_VER_V2)
+               priv_ep->trb_burst_size = 16;
+-      mult = min_t(u8, mult, EP_CFG_MULT_MAX);
+       buffering = min_t(u8, buffering, EP_CFG_BUFFERING_MAX);
+       maxburst = min_t(u8, maxburst, EP_CFG_MAXBURST_MAX);
+@@ -2173,7 +2161,7 @@ int cdns3_ep_config(struct cdns3_endpoin
+       }
+       ep_cfg |= EP_CFG_MAXPKTSIZE(max_packet_size) |
+-                EP_CFG_MULT(mult) |
++                EP_CFG_MULT(priv_ep->mult) |                  /* must match EP setting */
+                 EP_CFG_BUFFERING(buffering) |
+                 EP_CFG_MAXBURST(maxburst);
+@@ -2263,6 +2251,13 @@ usb_ep *cdns3_gadget_match_ep(struct usb
+       priv_ep->type = usb_endpoint_type(desc);
+       priv_ep->flags |= EP_CLAIMED;
+       priv_ep->interval = desc->bInterval ? BIT(desc->bInterval - 1) : 0;
++      priv_ep->wMaxPacketSize =  usb_endpoint_maxp(desc);
++      priv_ep->mult = USB_EP_MAXP_MULT(priv_ep->wMaxPacketSize);
++      priv_ep->wMaxPacketSize &= USB_ENDPOINT_MAXP_MASK;
++      if (priv_ep->type == USB_ENDPOINT_XFER_ISOC && comp_desc) {
++              priv_ep->mult =  USB_SS_MULT(comp_desc->bmAttributes) - 1;
++              priv_ep->bMaxBurst = comp_desc->bMaxBurst;
++      }
+       spin_unlock_irqrestore(&priv_dev->lock, flags);
+       return &priv_ep->endpoint;
+@@ -3044,22 +3039,40 @@ static int cdns3_gadget_check_config(str
+       struct cdns3_endpoint *priv_ep;
+       struct usb_ep *ep;
+       int n_in = 0;
++      int iso = 0;
++      int out = 1;
+       int total;
++      int n;
+       list_for_each_entry(ep, &gadget->ep_list, ep_list) {
+               priv_ep = ep_to_cdns3_ep(ep);
+-              if ((priv_ep->flags & EP_CLAIMED) && (ep->address & USB_DIR_IN))
+-                      n_in++;
++              if (!(priv_ep->flags & EP_CLAIMED))
++                      continue;
++
++              n = (priv_ep->mult + 1) * (priv_ep->bMaxBurst + 1);
++              if (ep->address & USB_DIR_IN) {
++                      /*
++                       * ISO transfer: DMA start move data when get ISO, only transfer
++                       * data as min(TD size, iso). No benefit for allocate bigger
++                       * internal memory than 'iso'.
++                       */
++                      if (priv_ep->type == USB_ENDPOINT_XFER_ISOC)
++                              iso += n;
++                      else
++                              n_in++;
++              } else {
++                      if (priv_ep->type == USB_ENDPOINT_XFER_ISOC)
++                              out = max_t(int, out, n);
++              }
+       }
+       /* 2KB are reserved for EP0, 1KB for out*/
+-      total = 2 + n_in + 1;
++      total = 2 + n_in + out + iso;
+       if (total > priv_dev->onchip_buffers)
+               return -ENOMEM;
+-      priv_dev->ep_buf_size = priv_dev->ep_iso_burst =
+-                      (priv_dev->onchip_buffers - 2) / (n_in + 1);
++      priv_dev->ep_buf_size = (priv_dev->onchip_buffers - 2 - iso) / (n_in + out);
+       return 0;
+ }
+--- a/drivers/usb/cdns3/cdns3-gadget.h
++++ b/drivers/usb/cdns3/cdns3-gadget.h
+@@ -1168,6 +1168,9 @@ struct cdns3_endpoint {
+       u8                      dir;
+       u8                      num;
+       u8                      type;
++      u8                      mult;
++      u8                      bMaxBurst;
++      u16                     wMaxPacketSize;
+       int                     interval;
+       int                     free_trbs;
diff --git a/queue-6.1/usb-cdns3-fix-uvc-fail-when-dma-cross-4k-boundery-since-sg-enabled.patch b/queue-6.1/usb-cdns3-fix-uvc-fail-when-dma-cross-4k-boundery-since-sg-enabled.patch
new file mode 100644 (file)
index 0000000..74c8c16
--- /dev/null
@@ -0,0 +1,85 @@
+From 40c304109e866a7dc123661a5c8ca72f6b5e14e0 Mon Sep 17 00:00:00 2001
+From: Frank Li <Frank.Li@nxp.com>
+Date: Sun, 24 Dec 2023 10:38:15 -0500
+Subject: usb: cdns3: Fix uvc fail when DMA cross 4k boundery since sg enabled
+
+From: Frank Li <Frank.Li@nxp.com>
+
+commit 40c304109e866a7dc123661a5c8ca72f6b5e14e0 upstream.
+
+Supposed DMA cross 4k bounder problem should be fixed at DEV_VER_V2, but
+still met problem when do ISO transfer if sg enabled.
+
+Data pattern likes below when sg enabled, package size is 1k and mult is 2
+       [UVC Header(8B) ] [data(3k - 8)] ...
+
+The received data at offset 0xd000 will get 0xc000 data, len 0x70. Error
+happen position as below pattern:
+       0xd000: wrong
+       0xe000: wrong
+       0xf000: correct
+       0x10000: wrong
+       0x11000: wrong
+       0x12000: correct
+       ...
+
+To avoid DMA cross 4k bounder at ISO transfer, reduce burst len according
+to start DMA address's alignment.
+
+Cc:  <stable@vger.kernel.org>
+Fixes: 7733f6c32e36 ("usb: cdns3: Add Cadence USB3 DRD Driver")
+Signed-off-by: Frank Li <Frank.Li@nxp.com>
+Link: https://lore.kernel.org/r/20231224153816.1664687-4-Frank.Li@nxp.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/cdns3/cdns3-gadget.c |   32 +++++++++++++++++++++++++++++++-
+ 1 file changed, 31 insertions(+), 1 deletion(-)
+
+--- a/drivers/usb/cdns3/cdns3-gadget.c
++++ b/drivers/usb/cdns3/cdns3-gadget.c
+@@ -1118,6 +1118,7 @@ static int cdns3_ep_run_transfer(struct
+       u32 togle_pcs = 1;
+       int sg_iter = 0;
+       int num_trb_req;
++      int trb_burst;
+       int num_trb;
+       int address;
+       u32 control;
+@@ -1240,7 +1241,36 @@ static int cdns3_ep_run_transfer(struct
+                       total_tdl += DIV_ROUND_UP(length,
+                                              priv_ep->endpoint.maxpacket);
+-              trb->length |= cpu_to_le32(TRB_BURST_LEN(priv_ep->trb_burst_size) |
++              trb_burst = priv_ep->trb_burst_size;
++
++              /*
++               * Supposed DMA cross 4k bounder problem should be fixed at DEV_VER_V2, but still
++               * met problem when do ISO transfer if sg enabled.
++               *
++               * Data pattern likes below when sg enabled, package size is 1k and mult is 2
++               *       [UVC Header(8B) ] [data(3k - 8)] ...
++               *
++               * The received data at offset 0xd000 will get 0xc000 data, len 0x70. Error happen
++               * as below pattern:
++               *      0xd000: wrong
++               *      0xe000: wrong
++               *      0xf000: correct
++               *      0x10000: wrong
++               *      0x11000: wrong
++               *      0x12000: correct
++               *      ...
++               *
++               * But it is still unclear about why error have not happen below 0xd000, it should
++               * cross 4k bounder. But anyway, the below code can fix this problem.
++               *
++               * To avoid DMA cross 4k bounder at ISO transfer, reduce burst len according to 16.
++               */
++              if (priv_ep->type == USB_ENDPOINT_XFER_ISOC && priv_dev->dev_ver <= DEV_VER_V2)
++                      if (ALIGN_DOWN(trb->buffer, SZ_4K) !=
++                          ALIGN_DOWN(trb->buffer + length, SZ_4K))
++                              trb_burst = 16;
++
++              trb->length |= cpu_to_le32(TRB_BURST_LEN(trb_burst) |
+                                       TRB_LEN(length));
+               pcs = priv_ep->pcs ? TRB_CYCLE : 0;
diff --git a/queue-6.1/usb-cdns3-fix-uvc-failure-work-since-sg-support-enabled.patch b/queue-6.1/usb-cdns3-fix-uvc-failure-work-since-sg-support-enabled.patch
new file mode 100644 (file)
index 0000000..49951c5
--- /dev/null
@@ -0,0 +1,153 @@
+From 1b8be5ecff26201bafb0a554c74e91571299fb94 Mon Sep 17 00:00:00 2001
+From: Frank Li <Frank.Li@nxp.com>
+Date: Sun, 24 Dec 2023 10:38:13 -0500
+Subject: usb: cdns3: fix uvc failure work since sg support enabled
+
+From: Frank Li <Frank.Li@nxp.com>
+
+commit 1b8be5ecff26201bafb0a554c74e91571299fb94 upstream.
+
+When IP version >= DEV_VER_V2, gadget:sg_supported is true. So uvc gadget
+function driver will use sg to equeue data, first is 8bytes header, the
+second is 1016bytes data.
+
+    cdns3_prepare_trb: ep2in: trb 0000000000ac755f, dma buf: 0xbf455000, size: 8, burst: 128 ctrl: 0x00000415 (C=1, T=0, ISP, CHAIN, Normal)
+    cdns3_prepare_trb: ep2in: trb 00000000a574e693, dma buf: 0xc0200fe0, size: 1016, burst: 128 ctrl: 0x00000405 (C=1, T=0, ISP, Normal)
+
+But cdns3_ep_run_transfer() can't correctly handle this case, which only
+support one TRB for ISO transfer.
+
+The controller requires duplicate the TD for each SOF if priv_ep->interval
+is not 1. DMA will read data from DDR to internal FIFO when get SOF. Send
+data to bus when receive IN token. DMA always refill FIFO when get SOF
+regardless host send IN token or not. If host send IN token later, some
+frames data will be lost.
+
+Fixed it by below major steps:
+
+1. Calculate numembers of TRB base on sg_nums and priv_ep->interval.
+2. Remove CHAIN flags for each end TRB of TD when duplicate TD.
+3. The controller requires LINK TRB must be first TRB of TD. When check
+there are not enough TRBs lefts, just fill LINK TRB for left TRBs.
+
+.... CHAIN_TRB DATA_TRB, CHAIN_TRB DATA_TRB,  LINK_TRB ... LINK_TRB
+                                                           ^End of TRB List
+
+Cc:  <stable@vger.kernel.org>
+Fixes: 7733f6c32e36 ("usb: cdns3: Add Cadence USB3 DRD Driver")
+Signed-off-by: Frank Li <Frank.Li@nxp.com>
+Link: https://lore.kernel.org/r/20231224153816.1664687-2-Frank.Li@nxp.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/cdns3/cdns3-gadget.c |   51 ++++++++++++++++++++++++++++++---------
+ 1 file changed, 40 insertions(+), 11 deletions(-)
+
+--- a/drivers/usb/cdns3/cdns3-gadget.c
++++ b/drivers/usb/cdns3/cdns3-gadget.c
+@@ -1117,6 +1117,7 @@ static int cdns3_ep_run_transfer(struct
+       dma_addr_t trb_dma;
+       u32 togle_pcs = 1;
+       int sg_iter = 0;
++      int num_trb_req;
+       int num_trb;
+       int address;
+       u32 control;
+@@ -1125,15 +1126,13 @@ static int cdns3_ep_run_transfer(struct
+       struct scatterlist *s = NULL;
+       bool sg_supported = !!(request->num_mapped_sgs);
++      num_trb_req = sg_supported ? request->num_mapped_sgs : 1;
++
++      /* ISO transfer require each SOF have a TD, each TD include some TRBs */
+       if (priv_ep->type == USB_ENDPOINT_XFER_ISOC)
+-              num_trb = priv_ep->interval;
++              num_trb = priv_ep->interval * num_trb_req;
+       else
+-              num_trb = sg_supported ? request->num_mapped_sgs : 1;
+-
+-      if (num_trb > priv_ep->free_trbs) {
+-              priv_ep->flags |= EP_RING_FULL;
+-              return -ENOBUFS;
+-      }
++              num_trb = num_trb_req;
+       priv_req = to_cdns3_request(request);
+       address = priv_ep->endpoint.desc->bEndpointAddress;
+@@ -1182,14 +1181,31 @@ static int cdns3_ep_run_transfer(struct
+               link_trb->control = cpu_to_le32(((priv_ep->pcs) ? TRB_CYCLE : 0) |
+                                   TRB_TYPE(TRB_LINK) | TRB_TOGGLE | ch_bit);
++
++              if (priv_ep->type == USB_ENDPOINT_XFER_ISOC) {
++                      /*
++                       * ISO require LINK TRB must be first one of TD.
++                       * Fill LINK TRBs for left trb space to simply software process logic.
++                       */
++                      while (priv_ep->enqueue) {
++                              *trb = *link_trb;
++                              trace_cdns3_prepare_trb(priv_ep, trb);
++
++                              cdns3_ep_inc_enq(priv_ep);
++                              trb = priv_ep->trb_pool + priv_ep->enqueue;
++                              priv_req->trb = trb;
++                      }
++              }
++      }
++
++      if (num_trb > priv_ep->free_trbs) {
++              priv_ep->flags |= EP_RING_FULL;
++              return -ENOBUFS;
+       }
+       if (priv_dev->dev_ver <= DEV_VER_V2)
+               togle_pcs = cdns3_wa1_update_guard(priv_ep, trb);
+-      if (sg_supported)
+-              s = request->sg;
+-
+       /* set incorrect Cycle Bit for first trb*/
+       control = priv_ep->pcs ? 0 : TRB_CYCLE;
+       trb->length = 0;
+@@ -1207,6 +1223,9 @@ static int cdns3_ep_run_transfer(struct
+       do {
+               u32 length;
++              if (!(sg_iter % num_trb_req) && sg_supported)
++                      s = request->sg;
++
+               /* fill TRB */
+               control |= TRB_TYPE(TRB_NORMAL);
+               if (sg_supported) {
+@@ -1248,7 +1267,7 @@ static int cdns3_ep_run_transfer(struct
+               if (sg_supported) {
+                       trb->control |= cpu_to_le32(TRB_ISP);
+                       /* Don't set chain bit for last TRB */
+-                      if (sg_iter < num_trb - 1)
++                      if ((sg_iter % num_trb_req) < num_trb_req - 1)
+                               trb->control |= cpu_to_le32(TRB_CHAIN);
+                       s = sg_next(s);
+@@ -1506,6 +1525,12 @@ static void cdns3_transfer_completed(str
+               /* The TRB was changed as link TRB, and the request was handled at ep_dequeue */
+               while (TRB_FIELD_TO_TYPE(le32_to_cpu(trb->control)) == TRB_LINK) {
++
++                      /* ISO ep_traddr may stop at LINK TRB */
++                      if (priv_ep->dequeue == cdns3_get_dma_pos(priv_dev, priv_ep) &&
++                          priv_ep->type == USB_ENDPOINT_XFER_ISOC)
++                              break;
++
+                       trace_cdns3_complete_trb(priv_ep, trb);
+                       cdns3_ep_inc_deq(priv_ep);
+                       trb = priv_ep->trb_pool + priv_ep->dequeue;
+@@ -1538,6 +1563,10 @@ static void cdns3_transfer_completed(str
+                       }
+                       if (request_handled) {
++                              /* TRBs are duplicated by priv_ep->interval time for ISO IN */
++                              if (priv_ep->type == USB_ENDPOINT_XFER_ISOC && priv_ep->dir)
++                                      request->actual /= priv_ep->interval;
++
+                               cdns3_gadget_giveback(priv_ep, priv_req, 0);
+                               request_handled = false;
+                               transfer_end = false;
diff --git a/queue-6.1/usb-chipidea-wait-controller-resume-finished-for-wakeup-irq.patch b/queue-6.1/usb-chipidea-wait-controller-resume-finished-for-wakeup-irq.patch
new file mode 100644 (file)
index 0000000..98a0a34
--- /dev/null
@@ -0,0 +1,46 @@
+From 128d849074d05545becf86e713715ce7676fc074 Mon Sep 17 00:00:00 2001
+From: Xu Yang <xu.yang_2@nxp.com>
+Date: Thu, 28 Dec 2023 19:07:52 +0800
+Subject: usb: chipidea: wait controller resume finished for wakeup irq
+
+From: Xu Yang <xu.yang_2@nxp.com>
+
+commit 128d849074d05545becf86e713715ce7676fc074 upstream.
+
+After the chipidea driver introduce extcon for id and vbus, it's able
+to wakeup from another irq source, in case the system with extcon ID
+cable, wakeup from usb ID cable and device removal, the usb device
+disconnect irq may come firstly before the extcon notifier while system
+resume, so we will get 2 "wakeup" irq, one for usb device disconnect;
+and one for extcon ID cable change(real wakeup event), current driver
+treat them as 2 successive wakeup irq so can't handle it correctly, then
+finally the usb irq can't be enabled. This patch adds a check to bypass
+further usb events before controller resume finished to fix it.
+
+Fixes: 1f874edcb731 ("usb: chipidea: add runtime power management support")
+cc:  <stable@vger.kernel.org>
+Acked-by: Peter Chen <peter.chen@kernel.org>
+Signed-off-by: Xu Yang <xu.yang_2@nxp.com>
+Signed-off-by: Li Jun <jun.li@nxp.com>
+Link: https://lore.kernel.org/r/20231228110753.1755756-2-xu.yang_2@nxp.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/chipidea/core.c |    7 +++++++
+ 1 file changed, 7 insertions(+)
+
+--- a/drivers/usb/chipidea/core.c
++++ b/drivers/usb/chipidea/core.c
+@@ -523,6 +523,13 @@ static irqreturn_t ci_irq_handler(int ir
+       u32 otgsc = 0;
+       if (ci->in_lpm) {
++              /*
++               * If we already have a wakeup irq pending there,
++               * let's just return to wait resume finished firstly.
++               */
++              if (ci->wakeup_int)
++                      return IRQ_HANDLED;
++
+               disable_irq_nosync(irq);
+               ci->wakeup_int = true;
+               pm_runtime_get(ci->dev);
diff --git a/queue-6.1/usb-dwc-ep0-update-request-status-in-dwc3_ep0_stall_restart.patch b/queue-6.1/usb-dwc-ep0-update-request-status-in-dwc3_ep0_stall_restart.patch
new file mode 100644 (file)
index 0000000..daafd5e
--- /dev/null
@@ -0,0 +1,57 @@
+From e9d40b215e38480fd94c66b06d79045717a59e9c Mon Sep 17 00:00:00 2001
+From: Uttkarsh Aggarwal <quic_uaggarwa@quicinc.com>
+Date: Fri, 22 Dec 2023 15:17:04 +0530
+Subject: usb: dwc: ep0: Update request status in dwc3_ep0_stall_restart
+
+From: Uttkarsh Aggarwal <quic_uaggarwa@quicinc.com>
+
+commit e9d40b215e38480fd94c66b06d79045717a59e9c upstream.
+
+Current implementation blocks the running operations when Plug-out and
+Plug-In is performed continuously, process gets stuck in
+dwc3_thread_interrupt().
+
+Code Flow:
+
+       CPU1
+
+       ->Gadget_start
+       ->dwc3_interrupt
+       ->dwc3_thread_interrupt
+       ->dwc3_process_event_buf
+       ->dwc3_process_event_entry
+       ->dwc3_endpoint_interrupt
+       ->dwc3_ep0_interrupt
+       ->dwc3_ep0_inspect_setup
+       ->dwc3_ep0_stall_and_restart
+
+By this time if pending_list is not empty, it will get the next request
+on the given list and calls dwc3_gadget_giveback which will unmap request
+and call its complete() callback to notify upper layers that it has
+completed. Currently dwc3_gadget_giveback status is set to -ECONNRESET,
+whereas it should be -ESHUTDOWN based on condition if not dwc->connected
+is true.
+
+Cc:  <stable@vger.kernel.org>
+Fixes: d742220b3577 ("usb: dwc3: ep0: giveback requests on stall_and_restart")
+Signed-off-by: Uttkarsh Aggarwal <quic_uaggarwa@quicinc.com>
+Link: https://lore.kernel.org/r/20231222094704.20276-1-quic_uaggarwa@quicinc.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/dwc3/ep0.c |    5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+--- a/drivers/usb/dwc3/ep0.c
++++ b/drivers/usb/dwc3/ep0.c
+@@ -236,7 +236,10 @@ void dwc3_ep0_stall_and_restart(struct d
+               struct dwc3_request     *req;
+               req = next_request(&dep->pending_list);
+-              dwc3_gadget_giveback(dep, req, -ECONNRESET);
++              if (!dwc->connected)
++                      dwc3_gadget_giveback(dep, req, -ESHUTDOWN);
++              else
++                      dwc3_gadget_giveback(dep, req, -ECONNRESET);
+       }
+       dwc->eps[0]->trb_enqueue = 0;
diff --git a/queue-6.1/usb-dwc3-gadget-handle-ep0-request-dequeuing-properly.patch b/queue-6.1/usb-dwc3-gadget-handle-ep0-request-dequeuing-properly.patch
new file mode 100644 (file)
index 0000000..c9ce30b
--- /dev/null
@@ -0,0 +1,67 @@
+From 730e12fbec53ab59dd807d981a204258a4cfb29a Mon Sep 17 00:00:00 2001
+From: Wesley Cheng <quic_wcheng@quicinc.com>
+Date: Wed, 6 Dec 2023 12:18:14 -0800
+Subject: usb: dwc3: gadget: Handle EP0 request dequeuing properly
+
+From: Wesley Cheng <quic_wcheng@quicinc.com>
+
+commit 730e12fbec53ab59dd807d981a204258a4cfb29a upstream.
+
+Current EP0 dequeue path will share the same as other EPs.  However, there
+are some special considerations that need to be made for EP0 transfers:
+
+  - EP0 transfers never transition into the started_list
+  - EP0 only has one active request at a time
+
+In case there is a vendor specific control message for a function over USB
+FFS, then there is no guarantee on the timeline which the DATA/STATUS stage
+is responded to.  While this occurs, any attempt to end transfers on
+non-control EPs will end up having the DWC3_EP_DELAY_STOP flag set, and
+defer issuing of the end transfer command.  If the USB FFS application
+decides to timeout the control transfer, or if USB FFS AIO path exits, the
+USB FFS driver will issue a call to usb_ep_dequeue() for the ep0 request.
+
+In case of the AIO exit path, the AIO FS blocks until all pending USB
+requests utilizing the AIO path is completed.  However, since the dequeue
+of ep0 req does not happen properly, all non-control EPs with the
+DWC3_EP_DELAY_STOP flag set will not be handled, and the AIO exit path will
+be stuck waiting for the USB FFS data endpoints to receive a completion
+callback.
+
+Fix is to utilize dwc3_ep0_reset_state() in the dequeue API to ensure EP0
+is brought back to the SETUP state, and ensures that any deferred end
+transfer commands are handled.  This also will end any active transfers
+on EP0, compared to the previous implementation which directly called
+giveback only.
+
+Fixes: fcd2def66392 ("usb: dwc3: gadget: Refactor dwc3_gadget_ep_dequeue")
+Cc: stable <stable@kernel.org>
+Signed-off-by: Wesley Cheng <quic_wcheng@quicinc.com>
+Acked-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
+Link: https://lore.kernel.org/r/20231206201814.32664-1-quic_wcheng@quicinc.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/dwc3/gadget.c |   12 +++++++++++-
+ 1 file changed, 11 insertions(+), 1 deletion(-)
+
+--- a/drivers/usb/dwc3/gadget.c
++++ b/drivers/usb/dwc3/gadget.c
+@@ -2075,7 +2075,17 @@ static int dwc3_gadget_ep_dequeue(struct
+       list_for_each_entry(r, &dep->pending_list, list) {
+               if (r == req) {
+-                      dwc3_gadget_giveback(dep, req, -ECONNRESET);
++                      /*
++                       * Explicitly check for EP0/1 as dequeue for those
++                       * EPs need to be handled differently.  Control EP
++                       * only deals with one USB req, and giveback will
++                       * occur during dwc3_ep0_stall_and_restart().  EP0
++                       * requests are never added to started_list.
++                       */
++                      if (dep->number > 1)
++                              dwc3_gadget_giveback(dep, req, -ECONNRESET);
++                      else
++                              dwc3_ep0_reset_state(dwc);
+                       goto out;
+               }
+       }
diff --git a/queue-6.1/usb-mon-fix-atomicity-violation-in-mon_bin_vma_fault.patch b/queue-6.1/usb-mon-fix-atomicity-violation-in-mon_bin_vma_fault.patch
new file mode 100644 (file)
index 0000000..27ba6a6
--- /dev/null
@@ -0,0 +1,90 @@
+From 2dd23cc4d0e6aa55cf9fb3b05f2f4165b01de81c Mon Sep 17 00:00:00 2001
+From: Gui-Dong Han <2045gemini@gmail.com>
+Date: Fri, 5 Jan 2024 13:24:12 +0800
+Subject: usb: mon: Fix atomicity violation in mon_bin_vma_fault
+
+From: Gui-Dong Han <2045gemini@gmail.com>
+
+commit 2dd23cc4d0e6aa55cf9fb3b05f2f4165b01de81c upstream.
+
+In mon_bin_vma_fault():
+    offset = vmf->pgoff << PAGE_SHIFT;
+    if (offset >= rp->b_size)
+        return VM_FAULT_SIGBUS;
+    chunk_idx = offset / CHUNK_SIZE;
+    pageptr = rp->b_vec[chunk_idx].pg;
+The code is executed without holding any lock.
+
+In mon_bin_vma_close():
+    spin_lock_irqsave(&rp->b_lock, flags);
+    rp->mmap_active--;
+    spin_unlock_irqrestore(&rp->b_lock, flags);
+
+In mon_bin_ioctl():
+    spin_lock_irqsave(&rp->b_lock, flags);
+    if (rp->mmap_active) {
+        ...
+    } else {
+        ...
+        kfree(rp->b_vec);
+        rp->b_vec  = vec;
+        rp->b_size = size;
+        ...
+    }
+    spin_unlock_irqrestore(&rp->b_lock, flags);
+
+Concurrent execution of mon_bin_vma_fault() with mon_bin_vma_close() and
+mon_bin_ioctl() could lead to atomicity violations. mon_bin_vma_fault()
+accesses rp->b_size and rp->b_vec without locking, risking array
+out-of-bounds access or use-after-free bugs due to possible modifications
+in mon_bin_ioctl().
+
+This possible bug is found by an experimental static analysis tool
+developed by our team, BassCheck[1]. This tool analyzes the locking APIs
+to extract function pairs that can be concurrently executed, and then
+analyzes the instructions in the paired functions to identify possible
+concurrency bugs including data races and atomicity violations. The above
+possible bug is reported when our tool analyzes the source code of
+Linux 6.2.
+
+To address this issue, it is proposed to add a spin lock pair in
+mon_bin_vma_fault() to ensure atomicity. With this patch applied, our tool
+never reports the possible bug, with the kernel configuration allyesconfig
+for x86_64. Due to the lack of associated hardware, we cannot test the
+patch in runtime testing, and just verify it according to the code logic.
+
+[1] https://sites.google.com/view/basscheck/
+
+Fixes: 19e6317d24c2 ("usb: mon: Fix a deadlock in usbmon between ...")
+Cc:  <stable@vger.kernel.org>
+Signed-off-by: Gui-Dong Han <2045gemini@gmail.com>
+Link: https://lore.kernel.org/r/20240105052412.9377-1-2045gemini@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/mon/mon_bin.c |    7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+--- a/drivers/usb/mon/mon_bin.c
++++ b/drivers/usb/mon/mon_bin.c
+@@ -1247,14 +1247,19 @@ static vm_fault_t mon_bin_vma_fault(stru
+       struct mon_reader_bin *rp = vmf->vma->vm_private_data;
+       unsigned long offset, chunk_idx;
+       struct page *pageptr;
++      unsigned long flags;
++      spin_lock_irqsave(&rp->b_lock, flags);
+       offset = vmf->pgoff << PAGE_SHIFT;
+-      if (offset >= rp->b_size)
++      if (offset >= rp->b_size) {
++              spin_unlock_irqrestore(&rp->b_lock, flags);
+               return VM_FAULT_SIGBUS;
++      }
+       chunk_idx = offset / CHUNK_SIZE;
+       pageptr = rp->b_vec[chunk_idx].pg;
+       get_page(pageptr);
+       vmf->page = pageptr;
++      spin_unlock_irqrestore(&rp->b_lock, flags);
+       return 0;
+ }
diff --git a/queue-6.1/usb-phy-mxs-remove-config_usb_otg-condition-for-mxs_phy_is_otg_host.patch b/queue-6.1/usb-phy-mxs-remove-config_usb_otg-condition-for-mxs_phy_is_otg_host.patch
new file mode 100644 (file)
index 0000000..ee2ce07
--- /dev/null
@@ -0,0 +1,36 @@
+From ff2b89de471da942a4d853443688113a44fd35ed Mon Sep 17 00:00:00 2001
+From: Xu Yang <xu.yang_2@nxp.com>
+Date: Thu, 28 Dec 2023 19:07:53 +0800
+Subject: usb: phy: mxs: remove CONFIG_USB_OTG condition for mxs_phy_is_otg_host()
+
+From: Xu Yang <xu.yang_2@nxp.com>
+
+commit ff2b89de471da942a4d853443688113a44fd35ed upstream.
+
+When CONFIG_USB_OTG is not set, mxs_phy_is_otg_host() will always return
+false. This behaviour is wrong. Since phy.last_event will always be set
+for either host or device mode. Therefore, CONFIG_USB_OTG condition
+can be removed.
+
+Fixes: 5eda42aebb76 ("usb: phy: mxs: fix getting wrong state with mxs_phy_is_otg_host()")
+cc:  <stable@vger.kernel.org>
+Acked-by: Peter Chen <peter.chen@kernel.org>
+Signed-off-by: Xu Yang <xu.yang_2@nxp.com>
+Link: https://lore.kernel.org/r/20231228110753.1755756-3-xu.yang_2@nxp.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/phy/phy-mxs-usb.c |    3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+--- a/drivers/usb/phy/phy-mxs-usb.c
++++ b/drivers/usb/phy/phy-mxs-usb.c
+@@ -388,8 +388,7 @@ static void __mxs_phy_disconnect_line(st
+ static bool mxs_phy_is_otg_host(struct mxs_phy *mxs_phy)
+ {
+-      return IS_ENABLED(CONFIG_USB_OTG) &&
+-              mxs_phy->phy.last_event == USB_EVENT_ID;
++      return mxs_phy->phy.last_event == USB_EVENT_ID;
+ }
+ static void mxs_phy_disconnect_line(struct mxs_phy *mxs_phy, bool on)
diff --git a/queue-6.1/usb-typec-class-fix-typec_altmode_put_partner-to-put-plugs.patch b/queue-6.1/usb-typec-class-fix-typec_altmode_put_partner-to-put-plugs.patch
new file mode 100644 (file)
index 0000000..2b09bf2
--- /dev/null
@@ -0,0 +1,71 @@
+From 5962ded777d689cd8bf04454273e32228d7fb71f Mon Sep 17 00:00:00 2001
+From: RD Babiera <rdbabiera@google.com>
+Date: Wed, 3 Jan 2024 18:17:55 +0000
+Subject: usb: typec: class: fix typec_altmode_put_partner to put plugs
+
+From: RD Babiera <rdbabiera@google.com>
+
+commit 5962ded777d689cd8bf04454273e32228d7fb71f upstream.
+
+When typec_altmode_put_partner is called by a plug altmode upon release,
+the port altmode the plug belongs to will not remove its reference to the
+plug. The check to see if the altmode being released is a plug evaluates
+against the released altmode's partner instead of the calling altmode, so
+change adev in typec_altmode_put_partner to properly refer to the altmode
+being released.
+
+Because typec_altmode_set_partner calls get_device() on the port altmode,
+add partner_adev that points to the port altmode in typec_put_partner to
+call put_device() on. typec_altmode_set_partner is not called for port
+altmodes, so add a check in typec_altmode_release to prevent
+typec_altmode_put_partner() calls on port altmode release.
+
+Fixes: 8a37d87d72f0 ("usb: typec: Bus type for alternate modes")
+Cc:  <stable@vger.kernel.org>
+Co-developed-by: Christian A. Ehrhardt <lk@c--e.de>
+Signed-off-by: Christian A. Ehrhardt <lk@c--e.de>
+Signed-off-by: RD Babiera <rdbabiera@google.com>
+Tested-by: Christian A. Ehrhardt <lk@c--e.de>
+Acked-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
+Link: https://lore.kernel.org/r/20240103181754.2492492-2-rdbabiera@google.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/typec/class.c |    9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+--- a/drivers/usb/typec/class.c
++++ b/drivers/usb/typec/class.c
+@@ -263,11 +263,13 @@ static void typec_altmode_put_partner(st
+ {
+       struct altmode *partner = altmode->partner;
+       struct typec_altmode *adev;
++      struct typec_altmode *partner_adev;
+       if (!partner)
+               return;
+-      adev = &partner->adev;
++      adev = &altmode->adev;
++      partner_adev = &partner->adev;
+       if (is_typec_plug(adev->dev.parent)) {
+               struct typec_plug *plug = to_typec_plug(adev->dev.parent);
+@@ -276,7 +278,7 @@ static void typec_altmode_put_partner(st
+       } else {
+               partner->partner = NULL;
+       }
+-      put_device(&adev->dev);
++      put_device(&partner_adev->dev);
+ }
+ /**
+@@ -497,7 +499,8 @@ static void typec_altmode_release(struct
+ {
+       struct altmode *alt = to_altmode(to_typec_altmode(dev));
+-      typec_altmode_put_partner(alt);
++      if (!is_typec_port(dev->parent))
++              typec_altmode_put_partner(alt);
+       altmode_id_remove(alt->adev.dev.parent, alt->id);
+       kfree(alt);
diff --git a/queue-6.1/xen-netback-don-t-produce-zero-size-skb-frags.patch b/queue-6.1/xen-netback-don-t-produce-zero-size-skb-frags.patch
new file mode 100644 (file)
index 0000000..89148fa
--- /dev/null
@@ -0,0 +1,106 @@
+From 17cdf40efb77e8a0ea68205c207098b179c5c08f Mon Sep 17 00:00:00 2001
+From: Jan Beulich <jbeulich@suse.com>
+Date: Mon, 8 Jan 2024 10:17:16 +0100
+Subject: xen-netback: don't produce zero-size SKB frags
+
+From: Jan Beulich <jbeulich@suse.com>
+
+commit c7ec4f2d684e17d69bbdd7c4324db0ef5daac26a upstream.
+
+While frontends may submit zero-size requests (wasting a precious slot),
+core networking code as of at least 3ece782693c4b ("sock: skb_copy_ubufs
+support for compound pages") can't deal with SKBs when they have all
+zero-size fragments. Respond to empty requests right when populating
+fragments; all further processing is fragment based and hence won't
+encounter these empty requests anymore.
+
+In a way this should have been that way from the beginning: When no data
+is to be transferred for a particular request, there's not even a point
+in validating the respective grant ref. That's no different from e.g.
+passing NULL into memcpy() when at the same time the size is 0.
+
+This is XSA-448 / CVE-2023-46838.
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Jan Beulich <jbeulich@suse.com>
+Reviewed-by: Juergen Gross <jgross@suse.com>
+Reviewed-by: Paul Durrant <paul@xen.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/xen-netback/netback.c |   44 ++++++++++++++++++++++++++++++++------
+ 1 file changed, 38 insertions(+), 6 deletions(-)
+
+--- a/drivers/net/xen-netback/netback.c
++++ b/drivers/net/xen-netback/netback.c
+@@ -463,12 +463,25 @@ static void xenvif_get_requests(struct x
+       }
+       for (shinfo->nr_frags = 0; nr_slots > 0 && shinfo->nr_frags < MAX_SKB_FRAGS;
+-           shinfo->nr_frags++, gop++, nr_slots--) {
++           nr_slots--) {
++              if (unlikely(!txp->size)) {
++                      unsigned long flags;
++
++                      spin_lock_irqsave(&queue->response_lock, flags);
++                      make_tx_response(queue, txp, 0, XEN_NETIF_RSP_OKAY);
++                      push_tx_responses(queue);
++                      spin_unlock_irqrestore(&queue->response_lock, flags);
++                      ++txp;
++                      continue;
++              }
++
+               index = pending_index(queue->pending_cons++);
+               pending_idx = queue->pending_ring[index];
+               xenvif_tx_create_map_op(queue, pending_idx, txp,
+                                       txp == first ? extra_count : 0, gop);
+               frag_set_pending_idx(&frags[shinfo->nr_frags], pending_idx);
++              ++shinfo->nr_frags;
++              ++gop;
+               if (txp == first)
+                       txp = txfrags;
+@@ -481,20 +494,39 @@ static void xenvif_get_requests(struct x
+               shinfo = skb_shinfo(nskb);
+               frags = shinfo->frags;
+-              for (shinfo->nr_frags = 0; shinfo->nr_frags < nr_slots;
+-                   shinfo->nr_frags++, txp++, gop++) {
++              for (shinfo->nr_frags = 0; shinfo->nr_frags < nr_slots; ++txp) {
++                      if (unlikely(!txp->size)) {
++                              unsigned long flags;
++
++                              spin_lock_irqsave(&queue->response_lock, flags);
++                              make_tx_response(queue, txp, 0,
++                                               XEN_NETIF_RSP_OKAY);
++                              push_tx_responses(queue);
++                              spin_unlock_irqrestore(&queue->response_lock,
++                                                     flags);
++                              continue;
++                      }
++
+                       index = pending_index(queue->pending_cons++);
+                       pending_idx = queue->pending_ring[index];
+                       xenvif_tx_create_map_op(queue, pending_idx, txp, 0,
+                                               gop);
+                       frag_set_pending_idx(&frags[shinfo->nr_frags],
+                                            pending_idx);
++                      ++shinfo->nr_frags;
++                      ++gop;
+               }
+-              skb_shinfo(skb)->frag_list = nskb;
+-      } else if (nskb) {
++              if (shinfo->nr_frags) {
++                      skb_shinfo(skb)->frag_list = nskb;
++                      nskb = NULL;
++              }
++      }
++
++      if (nskb) {
+               /* A frag_list skb was allocated but it is no longer needed
+-               * because enough slots were converted to copy ops above.
++               * because enough slots were converted to copy ops above or some
++               * were empty.
+                */
+               kfree_skb(nskb);
+       }