]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
serial: 8250: Protect LCR write in shutdown
authorIlpo Järvinen <ilpo.jarvinen@linux.intel.com>
Tue, 3 Feb 2026 17:10:43 +0000 (19:10 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 12 Mar 2026 14:34:07 +0000 (15:34 +0100)
The 8250_dw driver needs to potentially perform very complex operations
during LCR writes because its BUSY handling prevents updates to LCR
while UART is BUSY (which is not fully under our control without those
complex operations). Thus, LCR writes should occur under port's lock.

Move LCR write under port's lock in serial8250_do_shutdown(). Also
split the LCR RMW so that the logic is on a separate line for clarity.

Reported-by: Bandal, Shankar <shankar.bandal@intel.com>
Tested-by: Bandal, Shankar <shankar.bandal@intel.com>
Tested-by: Murthy, Shanth <shanth.murthy@intel.com>
Cc: stable <stable@kernel.org>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Link: https://patch.msgid.link/20260203171049.4353-2-ilpo.jarvinen@linux.intel.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/tty/serial/8250/8250_port.c

index a743964c9d22740d762b7c466e83e6c9a4fa89a4..20cf123a05401ae0a62e2ff23dfdf876235a57bb 100644 (file)
@@ -2348,6 +2348,7 @@ static int serial8250_startup(struct uart_port *port)
 void serial8250_do_shutdown(struct uart_port *port)
 {
        struct uart_8250_port *up = up_to_u8250p(port);
+       u32 lcr;
 
        serial8250_rpm_get(up);
        /*
@@ -2374,13 +2375,13 @@ void serial8250_do_shutdown(struct uart_port *port)
                        port->mctrl &= ~TIOCM_OUT2;
 
                serial8250_set_mctrl(port, port->mctrl);
+
+               /* Disable break condition */
+               lcr = serial_port_in(port, UART_LCR);
+               lcr &= ~UART_LCR_SBC;
+               serial_port_out(port, UART_LCR, lcr);
        }
 
-       /*
-        * Disable break condition and FIFOs
-        */
-       serial_port_out(port, UART_LCR,
-                       serial_port_in(port, UART_LCR) & ~UART_LCR_SBC);
        serial8250_clear_fifos(up);
 
        rsa_disable(up);