diff options
author | John Ogness <john.ogness@linutronix.de> | 2023-05-25 12:31:52 +0300 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2023-05-30 13:45:42 +0300 |
commit | b1207d86169d16581101f93b2906cefd0e940ff1 (patch) | |
tree | 572329b64cbd9612b6b1d3f945f08c6a5d59389b /drivers/tty/serial/8250/8250_bcm7271.c | |
parent | 0e4daea31d8312dd9f957a62717d4b5f31ef494c (diff) | |
download | linux-b1207d86169d16581101f93b2906cefd0e940ff1.tar.xz |
serial: 8250: lock port in startup() callbacks
uart_ops startup() callback is called without interrupts
disabled and without port->lock locked, relatively late during the
boot process (from the call path of console_on_rootfs()). If the
device is a console, it was already previously registered and could
be actively printing messages.
The console printing function serial8250_console_write() modifies
the interrupt register (UART_IER) under the port->lock with the
pattern: read, clear, restore.
Since some startup() callbacks are modifying UART_IER without the
port->lock locked, it is possible that the value intended to be
written by the startup() callback will get overwritten and be
lost.
CPU0 CPU1
serial8250_console_write omap_8250_startup
-------------------------- -----------------
spin_lock(port->lock)
oldval = read(UART_IER)
uart_console_write()
write(newval, UART_IER)
write(oldval, UART_IER)
spin_unlock(port->lock)
Add port->lock synchronization to the 8250 startup() callbacks
where they need to access UART_IER. This avoids racing with
serial8250_console_write().
Signed-off-by: John Ogness <john.ogness@linutronix.de>
Link: https://lore.kernel.org/r/20230525093159.223817-2-john.ogness@linutronix.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/tty/serial/8250/8250_bcm7271.c')
-rw-r--r-- | drivers/tty/serial/8250/8250_bcm7271.c | 4 |
1 files changed, 4 insertions, 0 deletions
diff --git a/drivers/tty/serial/8250/8250_bcm7271.c b/drivers/tty/serial/8250/8250_bcm7271.c index af0e1c070187..d4b05d7ad9e8 100644 --- a/drivers/tty/serial/8250/8250_bcm7271.c +++ b/drivers/tty/serial/8250/8250_bcm7271.c @@ -605,9 +605,13 @@ static int brcmuart_startup(struct uart_port *port) /* * Disable the Receive Data Interrupt because the DMA engine * will handle this. + * + * Synchronize UART_IER access against the console. */ + spin_lock_irq(&port->lock); up->ier &= ~UART_IER_RDI; serial_port_out(port, UART_IER, up->ier); + spin_unlock_irq(&port->lock); priv->tx_running = false; priv->dma.rx_dma = NULL; |