From: Greg Kroah-Hartman Date: Tue, 18 Feb 2025 12:06:15 +0000 (+0100) Subject: 5.4-stable patches X-Git-Tag: v6.1.129~67 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=f295b97a107692ebc51cbbdf573a15f42157c0ca;p=thirdparty%2Fkernel%2Fstable-queue.git 5.4-stable patches added patches: alpha-align-stack-for-page-fault-and-user-unaligned-trap-handlers.patch serial-8250-fix-fifo-underflow-on-flush.patch --- 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 index 0000000000..3e371031b1 --- /dev/null +++ b/queue-5.4/alpha-align-stack-for-page-fault-and-user-unaligned-trap-handlers.patch @@ -0,0 +1,129 @@ +From 3b35a171060f846b08b48646b38c30b5d57d17ff Mon Sep 17 00:00:00 2001 +From: Ivan Kokshaysky +Date: Tue, 4 Feb 2025 23:35:24 +0100 +Subject: alpha: align stack for page fault and user unaligned trap handlers + +From: Ivan Kokshaysky + +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 +Tested-by: Magnus Lindholm +Tested-by: Matt Turner +Reviewed-by: Maciej W. Rozycki +Suggested-by: Maciej W. Rozycki +Signed-off-by: Ivan Kokshaysky +Signed-off-by: Matt Turner +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 0000000000..4127b362f8 --- /dev/null +++ b/queue-5.4/serial-8250-fix-fifo-underflow-on-flush.patch @@ -0,0 +1,114 @@ +From 9e512eaaf8f4008c44ede3dfc0fbc9d9c5118583 Mon Sep 17 00:00:00 2001 +From: John Keeping +Date: Sat, 8 Feb 2025 12:41:44 +0000 +Subject: serial: 8250: Fix fifo underflow on flush + +From: John Keeping + +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 +Signed-off-by: John Keeping +Link: https://lore.kernel.org/r/20250208124148.1189191-1-jkeeping@inmusicbrands.com +Signed-off-by: Greg Kroah-Hartman +--- + 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, diff --git a/queue-5.4/series b/queue-5.4/series index d3c3ef0e15..0ee7bbca0e 100644 --- a/queue-5.4/series +++ b/queue-5.4/series @@ -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