From: Greg Kroah-Hartman Date: Sun, 21 Sep 2025 17:33:32 +0000 (+0200) Subject: 5.4-stable patches X-Git-Tag: v6.1.154~17 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=45a4b0e727460487c7cb7d0dacd644c24dc2c50e;p=thirdparty%2Fkernel%2Fstable-queue.git 5.4-stable patches added patches: serial-sc16is7xx-fix-bug-in-flow-control-levels-init.patch usb-gadget-dummy-hcd-fix-locking-bug-in-rt-enabled-kernels.patch usb-gadget-dummy_hcd-remove-usage-of-list-iterator-past-the-loop-body.patch --- diff --git a/queue-5.4/serial-sc16is7xx-fix-bug-in-flow-control-levels-init.patch b/queue-5.4/serial-sc16is7xx-fix-bug-in-flow-control-levels-init.patch new file mode 100644 index 0000000000..63c0cbbc32 --- /dev/null +++ b/queue-5.4/serial-sc16is7xx-fix-bug-in-flow-control-levels-init.patch @@ -0,0 +1,88 @@ +From sashal@kernel.org Wed Sep 17 15:03:27 2025 +From: Sasha Levin +Date: Wed, 17 Sep 2025 09:03:19 -0400 +Subject: serial: sc16is7xx: fix bug in flow control levels init +To: stable@vger.kernel.org +Cc: Hugo Villeneuve , Greg Kroah-Hartman , Sasha Levin +Message-ID: <20250917130319.535006-1-sashal@kernel.org> + +From: Hugo Villeneuve + +[ Upstream commit 535fd4c98452c87537a40610abba45daf5761ec6 ] + +When trying to set MCR[2], XON1 is incorrectly accessed instead. And when +writing to the TCR register to configure flow control levels, we are +incorrectly writing to the MSR register. The default value of $00 is then +used for TCR, which means that selectable trigger levels in FCR are used +in place of TCR. + +TCR/TLR access requires EFR[4] (enable enhanced functions) and MCR[2] +to be set. EFR[4] is already set in probe(). + +MCR access requires LCR[7] to be zero. + +Since LCR is set to $BF when trying to set MCR[2], XON1 is incorrectly +accessed instead because MCR shares the same address space as XON1. + +Since MCR[2] is unmodified and still zero, when writing to TCR we are in +fact writing to MSR because TCR/TLR registers share the same address space +as MSR/SPR. + +Fix by first removing useless reconfiguration of EFR[4] (enable enhanced +functions), as it is already enabled in sc16is7xx_probe() since commit +43c51bb573aa ("sc16is7xx: make sure device is in suspend once probed"). +Now LCR is $00, which means that MCR access is enabled. + +Also remove regcache_cache_bypass() calls since we no longer access the +enhanced registers set, and TCR is already declared as volatile (in fact +by declaring MSR as volatile, which shares the same address). + +Finally disable access to TCR/TLR registers after modifying them by +clearing MCR[2]. + +Note: the comment about "... and internal clock div" is wrong and can be + ignored/removed as access to internal clock div registers (DLL/DLH) + is permitted only when LCR[7] is logic 1, not when enhanced features + is enabled. And DLL/DLH access is not needed in sc16is7xx_startup(). + +Fixes: dfeae619d781 ("serial: sc16is7xx") +Cc: stable@vger.kernel.org +Signed-off-by: Hugo Villeneuve +Link: https://lore.kernel.org/r/20250731124451.1108864-1-hugo@hugovil.com +Signed-off-by: Greg Kroah-Hartman +[ s->regmap renames + context ] +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/tty/serial/sc16is7xx.c | 13 ++----------- + 1 file changed, 2 insertions(+), 11 deletions(-) + +--- a/drivers/tty/serial/sc16is7xx.c ++++ b/drivers/tty/serial/sc16is7xx.c +@@ -1032,16 +1032,6 @@ static int sc16is7xx_startup(struct uart + sc16is7xx_port_write(port, SC16IS7XX_FCR_REG, + SC16IS7XX_FCR_FIFO_BIT); + +- /* Enable EFR */ +- sc16is7xx_port_write(port, SC16IS7XX_LCR_REG, +- SC16IS7XX_LCR_CONF_MODE_B); +- +- regcache_cache_bypass(s->regmap, true); +- +- /* Enable write access to enhanced features and internal clock div */ +- sc16is7xx_port_write(port, SC16IS7XX_EFR_REG, +- SC16IS7XX_EFR_ENABLE_BIT); +- + /* Enable TCR/TLR */ + sc16is7xx_port_update(port, SC16IS7XX_MCR_REG, + SC16IS7XX_MCR_TCRTLR_BIT, +@@ -1053,7 +1043,8 @@ static int sc16is7xx_startup(struct uart + SC16IS7XX_TCR_RX_RESUME(24) | + SC16IS7XX_TCR_RX_HALT(48)); + +- regcache_cache_bypass(s->regmap, false); ++ /* Disable TCR/TLR access */ ++ sc16is7xx_port_update(port, SC16IS7XX_MCR_REG, SC16IS7XX_MCR_TCRTLR_BIT, 0); + + /* Now, initialize the UART */ + sc16is7xx_port_write(port, SC16IS7XX_LCR_REG, SC16IS7XX_LCR_WORD_LEN_8); diff --git a/queue-5.4/series b/queue-5.4/series index 33f8c31f90..fc6d083712 100644 --- a/queue-5.4/series +++ b/queue-5.4/series @@ -46,3 +46,6 @@ rds-ib-increment-i_fastreg_wrs-before-bailing-out.patch asoc-wm8940-correct-typo-in-control-name.patch asoc-wm8974-correct-pll-rate-rounding.patch asoc-sof-intel-hda-stream-fix-incorrect-variable-use.patch +usb-gadget-dummy_hcd-remove-usage-of-list-iterator-past-the-loop-body.patch +usb-gadget-dummy-hcd-fix-locking-bug-in-rt-enabled-kernels.patch +serial-sc16is7xx-fix-bug-in-flow-control-levels-init.patch diff --git a/queue-5.4/usb-gadget-dummy-hcd-fix-locking-bug-in-rt-enabled-kernels.patch b/queue-5.4/usb-gadget-dummy-hcd-fix-locking-bug-in-rt-enabled-kernels.patch new file mode 100644 index 0000000000..26429540b2 --- /dev/null +++ b/queue-5.4/usb-gadget-dummy-hcd-fix-locking-bug-in-rt-enabled-kernels.patch @@ -0,0 +1,95 @@ +From sashal@kernel.org Wed Sep 17 15:30:07 2025 +From: Sasha Levin +Date: Wed, 17 Sep 2025 09:30:03 -0400 +Subject: USB: gadget: dummy-hcd: Fix locking bug in RT-enabled kernels +To: stable@vger.kernel.org +Cc: Alan Stern , stable , Yunseong Kim , syzbot+8baacc4139f12fa77909@syzkaller.appspotmail.com, Sebastian Andrzej Siewior , Greg Kroah-Hartman , Sasha Levin +Message-ID: <20250917133003.551232-2-sashal@kernel.org> + +From: Alan Stern + +[ Upstream commit 8d63c83d8eb922f6c316320f50c82fa88d099bea ] + +Yunseong Kim and the syzbot fuzzer both reported a problem in +RT-enabled kernels caused by the way dummy-hcd mixes interrupt +management and spin-locking. The pattern was: + + local_irq_save(flags); + spin_lock(&dum->lock); + ... + spin_unlock(&dum->lock); + ... // calls usb_gadget_giveback_request() + local_irq_restore(flags); + +The code was written this way because usb_gadget_giveback_request() +needs to be called with interrupts disabled and the private lock not +held. + +While this pattern works fine in non-RT kernels, it's not good when RT +is enabled. RT kernels handle spinlocks much like mutexes; in particular, +spin_lock() may sleep. But sleeping is not allowed while local +interrupts are disabled. + +To fix the problem, rewrite the code to conform to the pattern used +elsewhere in dummy-hcd and other UDC drivers: + + spin_lock_irqsave(&dum->lock, flags); + ... + spin_unlock(&dum->lock); + usb_gadget_giveback_request(...); + spin_lock(&dum->lock); + ... + spin_unlock_irqrestore(&dum->lock, flags); + +This approach satisfies the RT requirements. + +Signed-off-by: Alan Stern +Cc: stable +Fixes: b4dbda1a22d2 ("USB: dummy-hcd: disable interrupts during req->complete") +Reported-by: Yunseong Kim +Closes: +Reported-by: syzbot+8baacc4139f12fa77909@syzkaller.appspotmail.com +Closes: +Tested-by: syzbot+8baacc4139f12fa77909@syzkaller.appspotmail.com +CC: Sebastian Andrzej Siewior +CC: stable@vger.kernel.org +Reviewed-by: Sebastian Andrzej Siewior +Link: https://lore.kernel.org/r/bb192ae2-4eee-48ee-981f-3efdbbd0d8f0@rowland.harvard.edu +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/gadget/udc/dummy_hcd.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/drivers/usb/gadget/udc/dummy_hcd.c ++++ b/drivers/usb/gadget/udc/dummy_hcd.c +@@ -758,8 +758,7 @@ static int dummy_dequeue(struct usb_ep * + if (!dum->driver) + return -ESHUTDOWN; + +- local_irq_save(flags); +- spin_lock(&dum->lock); ++ spin_lock_irqsave(&dum->lock, flags); + list_for_each_entry(iter, &ep->queue, queue) { + if (&iter->req != _req) + continue; +@@ -769,15 +768,16 @@ static int dummy_dequeue(struct usb_ep * + retval = 0; + break; + } +- spin_unlock(&dum->lock); + + if (retval == 0) { + dev_dbg(udc_dev(dum), + "dequeued req %p from %s, len %d buf %p\n", + req, _ep->name, _req->length, _req->buf); ++ spin_unlock(&dum->lock); + usb_gadget_giveback_request(_ep, _req); ++ spin_lock(&dum->lock); + } +- local_irq_restore(flags); ++ spin_unlock_irqrestore(&dum->lock, flags); + return retval; + } + diff --git a/queue-5.4/usb-gadget-dummy_hcd-remove-usage-of-list-iterator-past-the-loop-body.patch b/queue-5.4/usb-gadget-dummy_hcd-remove-usage-of-list-iterator-past-the-loop-body.patch new file mode 100644 index 0000000000..e91e29132b --- /dev/null +++ b/queue-5.4/usb-gadget-dummy_hcd-remove-usage-of-list-iterator-past-the-loop-body.patch @@ -0,0 +1,63 @@ +From sashal@kernel.org Wed Sep 17 15:30:06 2025 +From: Sasha Levin +Date: Wed, 17 Sep 2025 09:30:02 -0400 +Subject: usb: gadget: dummy_hcd: remove usage of list iterator past the loop body +To: stable@vger.kernel.org +Cc: Jakob Koschel , Greg Kroah-Hartman , Sasha Levin +Message-ID: <20250917133003.551232-1-sashal@kernel.org> + +From: Jakob Koschel + +[ Upstream commit 7975f080d3557725160a878b1a64339043ba3d91 ] + +To move the list iterator variable into the list_for_each_entry_*() +macro in the future it should be avoided to use the list iterator +variable after the loop body. + +To *never* use the list iterator variable after the loop it was +concluded to use a separate iterator variable [1]. + +Link: https://lore.kernel.org/all/YhdfEIwI4EdtHdym@kroah.com/ +Signed-off-by: Jakob Koschel +Link: https://lore.kernel.org/r/20220308171818.384491-26-jakobkoschel@gmail.com +Signed-off-by: Greg Kroah-Hartman +Stable-dep-of: 8d63c83d8eb9 ("USB: gadget: dummy-hcd: Fix locking bug in RT-enabled kernels") +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/gadget/udc/dummy_hcd.c | 17 +++++++++-------- + 1 file changed, 9 insertions(+), 8 deletions(-) + +--- a/drivers/usb/gadget/udc/dummy_hcd.c ++++ b/drivers/usb/gadget/udc/dummy_hcd.c +@@ -748,7 +748,7 @@ static int dummy_dequeue(struct usb_ep * + struct dummy *dum; + int retval = -EINVAL; + unsigned long flags; +- struct dummy_request *req = NULL; ++ struct dummy_request *req = NULL, *iter; + + if (!_ep || !_req) + return retval; +@@ -760,13 +760,14 @@ static int dummy_dequeue(struct usb_ep * + + local_irq_save(flags); + spin_lock(&dum->lock); +- list_for_each_entry(req, &ep->queue, queue) { +- if (&req->req == _req) { +- list_del_init(&req->queue); +- _req->status = -ECONNRESET; +- retval = 0; +- break; +- } ++ list_for_each_entry(iter, &ep->queue, queue) { ++ if (&iter->req != _req) ++ continue; ++ list_del_init(&iter->queue); ++ _req->status = -ECONNRESET; ++ req = iter; ++ retval = 0; ++ break; + } + spin_unlock(&dum->lock); +