diff options
author | John Ogness <john.ogness@linutronix.de> | 2023-05-25 11:31:57 +0200 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2023-05-30 12:45:42 +0200 |
commit | 8b45503776b6e2c53abbb217970236ed54bd261b (patch) | |
tree | 175700887bd91e1e4cb81706b39e0e0c46601e48 | |
parent | serial: 8250: lock port for rx_dma() callback (diff) | |
download | linux-8b45503776b6e2c53abbb217970236ed54bd261b.tar.xz linux-8b45503776b6e2c53abbb217970236ed54bd261b.zip |
serial: 8250: lock port for omap8250_restore_regs()
omap8250_restore_regs() accesses UART_IER. This register is
modified twice by each console write (serial8250_console_write())
under the port lock. However, not all calls to omap8250_restore_regs()
are under the port lock.
Add the missing port locking around omap8250_restore_regs() calls. Add
lockdep notation to the omap8250_restore_regs().
Note that this is not fixing a real problem because the serial devices
are resumed before console printing is enabled.
However, adding this locking allows for clean locking semantics
for omap8250_restore_regs() so that lockdep can be used to identify
possible problems in the future. It also simplifies synchronization
of UART_IER in general by not needing to rely on such implementation
details.
Signed-off-by: John Ogness <john.ogness@linutronix.de>
Link: https://lore.kernel.org/r/20230525093159.223817-7-john.ogness@linutronix.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r-- | drivers/tty/serial/8250/8250_omap.c | 8 |
1 files changed, 7 insertions, 1 deletions
diff --git a/drivers/tty/serial/8250/8250_omap.c b/drivers/tty/serial/8250/8250_omap.c index 3cb9cfa62331..34939462fd69 100644 --- a/drivers/tty/serial/8250/8250_omap.c +++ b/drivers/tty/serial/8250/8250_omap.c @@ -309,6 +309,9 @@ static void omap8250_restore_regs(struct uart_8250_port *up) struct uart_8250_dma *dma = up->dma; u8 mcr = serial8250_in_MCR(up); + /* Port locked to synchronize UART_IER access against the console. */ + lockdep_assert_held_once(&up->port.lock); + if (dma && dma->tx_running) { /* * TCSANOW requests the change to occur immediately however if @@ -1739,8 +1742,11 @@ static int omap8250_runtime_resume(struct device *dev) if (priv->line >= 0) up = serial8250_get_port(priv->line); - if (up && omap8250_lost_context(up)) + if (up && omap8250_lost_context(up)) { + spin_lock_irq(&up->port.lock); omap8250_restore_regs(up); + spin_unlock_irq(&up->port.lock); + } if (up && up->dma && up->dma->rxchan && !(priv->habit & UART_HAS_EFR2)) { spin_lock_irq(&up->port.lock); |