]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 18 Feb 2025 12:06:15 +0000 (13:06 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 18 Feb 2025 12:06:15 +0000 (13:06 +0100)
added patches:
alpha-align-stack-for-page-fault-and-user-unaligned-trap-handlers.patch
serial-8250-fix-fifo-underflow-on-flush.patch

queue-5.4/alpha-align-stack-for-page-fault-and-user-unaligned-trap-handlers.patch [new file with mode: 0644]
queue-5.4/serial-8250-fix-fifo-underflow-on-flush.patch [new file with mode: 0644]
queue-5.4/series

diff --git a/queue-5.4/alpha-align-stack-for-page-fault-and-user-unaligned-trap-handlers.patch b/queue-5.4/alpha-align-stack-for-page-fault-and-user-unaligned-trap-handlers.patch
new file mode 100644 (file)
index 0000000..3e37103
--- /dev/null
@@ -0,0 +1,129 @@
+From 3b35a171060f846b08b48646b38c30b5d57d17ff Mon Sep 17 00:00:00 2001
+From: Ivan Kokshaysky <ink@unseen.parts>
+Date: Tue, 4 Feb 2025 23:35:24 +0100
+Subject: alpha: align stack for page fault and user unaligned trap handlers
+
+From: Ivan Kokshaysky <ink@unseen.parts>
+
+commit 3b35a171060f846b08b48646b38c30b5d57d17ff upstream.
+
+do_page_fault() and do_entUna() are special because they use
+non-standard stack frame layout. Fix them manually.
+
+Cc: stable@vger.kernel.org
+Tested-by: Maciej W. Rozycki <macro@orcam.me.uk>
+Tested-by: Magnus Lindholm <linmag7@gmail.com>
+Tested-by: Matt Turner <mattst88@gmail.com>
+Reviewed-by: Maciej W. Rozycki <macro@orcam.me.uk>
+Suggested-by: Maciej W. Rozycki <macro@orcam.me.uk>
+Signed-off-by: Ivan Kokshaysky <ink@unseen.parts>
+Signed-off-by: Matt Turner <mattst88@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/alpha/kernel/entry.S |   20 ++++++++++----------
+ arch/alpha/kernel/traps.c |    2 +-
+ arch/alpha/mm/fault.c     |    4 ++--
+ 3 files changed, 13 insertions(+), 13 deletions(-)
+
+--- a/arch/alpha/kernel/entry.S
++++ b/arch/alpha/kernel/entry.S
+@@ -199,8 +199,8 @@ CFI_END_OSF_FRAME entArith
+ CFI_START_OSF_FRAME entMM
+       SAVE_ALL
+ /* save $9 - $15 so the inline exception code can manipulate them.  */
+-      subq    $sp, 56, $sp
+-      .cfi_adjust_cfa_offset  56
++      subq    $sp, 64, $sp
++      .cfi_adjust_cfa_offset  64
+       stq     $9, 0($sp)
+       stq     $10, 8($sp)
+       stq     $11, 16($sp)
+@@ -215,7 +215,7 @@ CFI_START_OSF_FRAME entMM
+       .cfi_rel_offset $13, 32
+       .cfi_rel_offset $14, 40
+       .cfi_rel_offset $15, 48
+-      addq    $sp, 56, $19
++      addq    $sp, 64, $19
+ /* handle the fault */
+       lda     $8, 0x3fff
+       bic     $sp, $8, $8
+@@ -228,7 +228,7 @@ CFI_START_OSF_FRAME entMM
+       ldq     $13, 32($sp)
+       ldq     $14, 40($sp)
+       ldq     $15, 48($sp)
+-      addq    $sp, 56, $sp
++      addq    $sp, 64, $sp
+       .cfi_restore    $9
+       .cfi_restore    $10
+       .cfi_restore    $11
+@@ -236,7 +236,7 @@ CFI_START_OSF_FRAME entMM
+       .cfi_restore    $13
+       .cfi_restore    $14
+       .cfi_restore    $15
+-      .cfi_adjust_cfa_offset  -56
++      .cfi_adjust_cfa_offset  -64
+ /* finish up the syscall as normal.  */
+       br      ret_from_sys_call
+ CFI_END_OSF_FRAME entMM
+@@ -383,8 +383,8 @@ entUnaUser:
+       .cfi_restore    $0
+       .cfi_adjust_cfa_offset  -256
+       SAVE_ALL                /* setup normal kernel stack */
+-      lda     $sp, -56($sp)
+-      .cfi_adjust_cfa_offset  56
++      lda     $sp, -64($sp)
++      .cfi_adjust_cfa_offset  64
+       stq     $9, 0($sp)
+       stq     $10, 8($sp)
+       stq     $11, 16($sp)
+@@ -400,7 +400,7 @@ entUnaUser:
+       .cfi_rel_offset $14, 40
+       .cfi_rel_offset $15, 48
+       lda     $8, 0x3fff
+-      addq    $sp, 56, $19
++      addq    $sp, 64, $19
+       bic     $sp, $8, $8
+       jsr     $26, do_entUnaUser
+       ldq     $9, 0($sp)
+@@ -410,7 +410,7 @@ entUnaUser:
+       ldq     $13, 32($sp)
+       ldq     $14, 40($sp)
+       ldq     $15, 48($sp)
+-      lda     $sp, 56($sp)
++      lda     $sp, 64($sp)
+       .cfi_restore    $9
+       .cfi_restore    $10
+       .cfi_restore    $11
+@@ -418,7 +418,7 @@ entUnaUser:
+       .cfi_restore    $13
+       .cfi_restore    $14
+       .cfi_restore    $15
+-      .cfi_adjust_cfa_offset  -56
++      .cfi_adjust_cfa_offset  -64
+       br      ret_from_sys_call
+ CFI_END_OSF_FRAME entUna
+--- a/arch/alpha/kernel/traps.c
++++ b/arch/alpha/kernel/traps.c
+@@ -709,7 +709,7 @@ s_reg_to_mem (unsigned long s_reg)
+ static int unauser_reg_offsets[32] = {
+       R(r0), R(r1), R(r2), R(r3), R(r4), R(r5), R(r6), R(r7), R(r8),
+       /* r9 ... r15 are stored in front of regs.  */
+-      -56, -48, -40, -32, -24, -16, -8,
++      -64, -56, -48, -40, -32, -24, -16,      /* padding at -8 */
+       R(r16), R(r17), R(r18),
+       R(r19), R(r20), R(r21), R(r22), R(r23), R(r24), R(r25), R(r26),
+       R(r27), R(r28), R(gp),
+--- a/arch/alpha/mm/fault.c
++++ b/arch/alpha/mm/fault.c
+@@ -77,8 +77,8 @@ __load_new_mm_context(struct mm_struct *
+ /* Macro for exception fixup code to access integer registers.  */
+ #define dpf_reg(r)                                                    \
+-      (((unsigned long *)regs)[(r) <= 8 ? (r) : (r) <= 15 ? (r)-16 :  \
+-                               (r) <= 18 ? (r)+10 : (r)-10])
++      (((unsigned long *)regs)[(r) <= 8 ? (r) : (r) <= 15 ? (r)-17 :  \
++                               (r) <= 18 ? (r)+11 : (r)-10])
+ asmlinkage void
+ do_page_fault(unsigned long address, unsigned long mmcsr,
diff --git a/queue-5.4/serial-8250-fix-fifo-underflow-on-flush.patch b/queue-5.4/serial-8250-fix-fifo-underflow-on-flush.patch
new file mode 100644 (file)
index 0000000..4127b36
--- /dev/null
@@ -0,0 +1,114 @@
+From 9e512eaaf8f4008c44ede3dfc0fbc9d9c5118583 Mon Sep 17 00:00:00 2001
+From: John Keeping <jkeeping@inmusicbrands.com>
+Date: Sat, 8 Feb 2025 12:41:44 +0000
+Subject: serial: 8250: Fix fifo underflow on flush
+
+From: John Keeping <jkeeping@inmusicbrands.com>
+
+commit 9e512eaaf8f4008c44ede3dfc0fbc9d9c5118583 upstream.
+
+When flushing the serial port's buffer, uart_flush_buffer() calls
+kfifo_reset() but if there is an outstanding DMA transfer then the
+completion function will consume data from the kfifo via
+uart_xmit_advance(), underflowing and leading to ongoing DMA as the
+driver tries to transmit another 2^32 bytes.
+
+This is readily reproduced with serial-generic and amidi sending even
+short messages as closing the device on exit will wait for the fifo to
+drain and in the underflow case amidi hangs for 30 seconds on exit in
+tty_wait_until_sent().  A trace of that gives:
+
+     kworker/1:1-84    [001]    51.769423: bprint:               serial8250_tx_dma: tx_size=3 fifo_len=3
+           amidi-763   [001]    51.769460: bprint:               uart_flush_buffer: resetting fifo
+ irq/21-fe530000-76    [000]    51.769474: bprint:               __dma_tx_complete: tx_size=3
+ irq/21-fe530000-76    [000]    51.769479: bprint:               serial8250_tx_dma: tx_size=4096 fifo_len=4294967293
+ irq/21-fe530000-76    [000]    51.781295: bprint:               __dma_tx_complete: tx_size=4096
+ irq/21-fe530000-76    [000]    51.781301: bprint:               serial8250_tx_dma: tx_size=4096 fifo_len=4294963197
+ irq/21-fe530000-76    [000]    51.793131: bprint:               __dma_tx_complete: tx_size=4096
+ irq/21-fe530000-76    [000]    51.793135: bprint:               serial8250_tx_dma: tx_size=4096 fifo_len=4294959101
+ irq/21-fe530000-76    [000]    51.804949: bprint:               __dma_tx_complete: tx_size=4096
+
+Since the port lock is held in when the kfifo is reset in
+uart_flush_buffer() and in __dma_tx_complete(), adding a flush_buffer
+hook to adjust the outstanding DMA byte count is sufficient to avoid the
+kfifo underflow.
+
+Fixes: 9ee4b83e51f74 ("serial: 8250: Add support for dmaengine")
+Cc: stable <stable@kernel.org>
+Signed-off-by: John Keeping <jkeeping@inmusicbrands.com>
+Link: https://lore.kernel.org/r/20250208124148.1189191-1-jkeeping@inmusicbrands.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/tty/serial/8250/8250.h      |    2 ++
+ drivers/tty/serial/8250/8250_dma.c  |   16 ++++++++++++++++
+ drivers/tty/serial/8250/8250_port.c |    9 +++++++++
+ 3 files changed, 27 insertions(+)
+
+--- a/drivers/tty/serial/8250/8250.h
++++ b/drivers/tty/serial/8250/8250.h
+@@ -300,6 +300,7 @@ static inline int is_omap1510_8250(struc
+ #ifdef CONFIG_SERIAL_8250_DMA
+ extern int serial8250_tx_dma(struct uart_8250_port *);
++extern void serial8250_tx_dma_flush(struct uart_8250_port *);
+ extern int serial8250_rx_dma(struct uart_8250_port *);
+ extern void serial8250_rx_dma_flush(struct uart_8250_port *);
+ extern int serial8250_request_dma(struct uart_8250_port *);
+@@ -316,6 +317,7 @@ static inline int serial8250_tx_dma(stru
+ {
+       return -1;
+ }
++static inline void serial8250_tx_dma_flush(struct uart_8250_port *p) { }
+ static inline int serial8250_rx_dma(struct uart_8250_port *p)
+ {
+       return -1;
+--- a/drivers/tty/serial/8250/8250_dma.c
++++ b/drivers/tty/serial/8250/8250_dma.c
+@@ -126,6 +126,22 @@ err:
+       return ret;
+ }
++void serial8250_tx_dma_flush(struct uart_8250_port *p)
++{
++      struct uart_8250_dma *dma = p->dma;
++
++      if (!dma->tx_running)
++              return;
++
++      /*
++       * kfifo_reset() has been called by the serial core, avoid
++       * advancing and underflowing in __dma_tx_complete().
++       */
++      dma->tx_size = 0;
++
++      dmaengine_terminate_async(dma->rxchan);
++}
++
+ int serial8250_rx_dma(struct uart_8250_port *p)
+ {
+       struct uart_8250_dma            *dma = p->dma;
+--- a/drivers/tty/serial/8250/8250_port.c
++++ b/drivers/tty/serial/8250/8250_port.c
+@@ -2473,6 +2473,14 @@ static unsigned int npcm_get_divisor(str
+       return DIV_ROUND_CLOSEST(port->uartclk, 16 * baud + 2) - 2;
+ }
++static void serial8250_flush_buffer(struct uart_port *port)
++{
++      struct uart_8250_port *up = up_to_u8250p(port);
++
++      if (up->dma)
++              serial8250_tx_dma_flush(up);
++}
++
+ static unsigned int serial8250_do_get_divisor(struct uart_port *port,
+                                             unsigned int baud,
+                                             unsigned int *frac)
+@@ -3119,6 +3127,7 @@ static const struct uart_ops serial8250_
+       .break_ctl      = serial8250_break_ctl,
+       .startup        = serial8250_startup,
+       .shutdown       = serial8250_shutdown,
++      .flush_buffer   = serial8250_flush_buffer,
+       .set_termios    = serial8250_set_termios,
+       .set_ldisc      = serial8250_set_ldisc,
+       .pm             = serial8250_pm,
index d3c3ef0e1578545dc2d90e1fd857fb74735843f1..0ee7bbca0effaa6ec3f3c1e4343342828151c890 100644 (file)
@@ -185,3 +185,5 @@ usb-serial-option-drop-meig-smart-defines.patch
 can-c_can-fix-unbalanced-runtime-pm-disable-in-error-path.patch
 can-j1939-j1939_sk_send_loop-fix-unable-to-send-messages-with-data-length-zero.patch
 alpha-make-stack-16-byte-aligned-most-cases.patch
+serial-8250-fix-fifo-underflow-on-flush.patch
+alpha-align-stack-for-page-fault-and-user-unaligned-trap-handlers.patch