Messages in this thread |  | | From | yunhui cui <> | | Date | Wed, 21 May 2025 14:21:06 +0800 | | Subject | Re: [PATCH v6 1/4] serial: 8250: fix panic due to PSLVERR |
| |
Hi All,
Gentle ping. Any comments on this patchset?
On Tue, May 13, 2025 at 10:42 AM Yunhui Cui <cuiyunhui@bytedance.com> wrote: > > When the PSLVERR_RESP_EN parameter is set to 1, the device generates > an error response if an attempt is made to read an empty RBR (Receive > Buffer Register) while the FIFO is enabled. > > In serial8250_do_startup(), calling serial_port_out(port, UART_LCR, > UART_LCR_WLEN8) triggers dw8250_check_lcr(), which invokes > dw8250_force_idle() and serial8250_clear_and_reinit_fifos(). The latter > function enables the FIFO via serial_out(p, UART_FCR, p->fcr). > Execution proceeds to the serial_port_in(port, UART_RX). > This satisfies the PSLVERR trigger condition. > > When another CPU (e.g., using printk()) is accessing the UART (UART > is busy), the current CPU fails the check (value & ~UART_LCR_SPAR) == > (lcr & ~UART_LCR_SPAR) in dw8250_check_lcr(), causing it to enter > dw8250_force_idle(). > > Put serial_port_out(port, UART_LCR, UART_LCR_WLEN8) under the port->lock > to fix this issue. > > Panic backtrace: > [ 0.442336] Oops - unknown exception [#1] > [ 0.442343] epc : dw8250_serial_in32+0x1e/0x4a > [ 0.442351] ra : serial8250_do_startup+0x2c8/0x88e > ... > [ 0.442416] console_on_rootfs+0x26/0x70 > > Fixes: c49436b657d0 ("serial: 8250_dw: Improve unwritable LCR workaround") > Link: https://lore.kernel.org/all/84cydt5peu.fsf@jogness.linutronix.de/T/ > Signed-off-by: Yunhui Cui <cuiyunhui@bytedance.com> > --- > drivers/tty/serial/8250/8250_port.c | 3 ++- > 1 file changed, 2 insertions(+), 1 deletion(-) > > diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c > index 6d7b8c4667c9c..07fe818dffa34 100644 > --- a/drivers/tty/serial/8250/8250_port.c > +++ b/drivers/tty/serial/8250/8250_port.c > @@ -2376,9 +2376,10 @@ int serial8250_do_startup(struct uart_port *port) > /* > * Now, initialize the UART > */ > - serial_port_out(port, UART_LCR, UART_LCR_WLEN8); > > uart_port_lock_irqsave(port, &flags); > + serial_port_out(port, UART_LCR, UART_LCR_WLEN8); > + > if (up->port.flags & UPF_FOURPORT) { > if (!up->port.irq) > up->port.mctrl |= TIOCM_OUT1; > -- > 2.39.2 >
Thanks, Yunhui
|  |