diff options
| author | Ryo Takakura <ryotkkr98@gmail.com> | 2025-04-12 09:18:47 +0900 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2025-05-02 07:50:49 +0200 |
| commit | 3b377f805e97be62041cfca8dba669b91ab0c882 (patch) | |
| tree | f9819e6c6b81d542c790d067f933648371765ec1 /drivers/tty | |
| parent | c2af265beab7fc480880aade4fae818dba96a589 (diff) | |
| download | linux-3b377f805e97be62041cfca8dba669b91ab0c882.tar.gz linux-3b377f805e97be62041cfca8dba669b91ab0c882.tar.bz2 linux-3b377f805e97be62041cfca8dba669b91ab0c882.zip | |
serial: sifive: lock port in startup()/shutdown() callbacks
commit e1ca3ff28ab1e2c1e70713ef3fa7943c725742c3 upstream.
startup()/shutdown() callbacks access SIFIVE_SERIAL_IE_OFFS.
The register is also accessed from write() callback.
If console were printing and startup()/shutdown() callback
gets called, its access to the register could be overwritten.
Add port->lock to startup()/shutdown() callbacks to make sure
their access to SIFIVE_SERIAL_IE_OFFS is synchronized against
write() callback.
Fixes: 45c054d0815b ("tty: serial: add driver for the SiFive UART")
Signed-off-by: Ryo Takakura <ryotkkr98@gmail.com>
Reviewed-by: Petr Mladek <pmladek@suse.com>
Cc: stable@vger.kernel.org
Reviewed-by: John Ogness <john.ogness@linutronix.de>
Rule: add
Link: https://lore.kernel.org/stable/20250330003522.386632-1-ryotkkr98%40gmail.com
Link: https://lore.kernel.org/r/20250412001847.183221-1-ryotkkr98@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/tty')
| -rw-r--r-- | drivers/tty/serial/sifive.c | 6 |
1 files changed, 6 insertions, 0 deletions
diff --git a/drivers/tty/serial/sifive.c b/drivers/tty/serial/sifive.c index d195c5de52e7..e86b00873d0e 100644 --- a/drivers/tty/serial/sifive.c +++ b/drivers/tty/serial/sifive.c @@ -562,8 +562,11 @@ static void sifive_serial_break_ctl(struct uart_port *port, int break_state) static int sifive_serial_startup(struct uart_port *port) { struct sifive_serial_port *ssp = port_to_sifive_serial_port(port); + unsigned long flags; + uart_port_lock_irqsave(&ssp->port, &flags); __ssp_enable_rxwm(ssp); + uart_port_unlock_irqrestore(&ssp->port, flags); return 0; } @@ -571,9 +574,12 @@ static int sifive_serial_startup(struct uart_port *port) static void sifive_serial_shutdown(struct uart_port *port) { struct sifive_serial_port *ssp = port_to_sifive_serial_port(port); + unsigned long flags; + uart_port_lock_irqsave(&ssp->port, &flags); __ssp_disable_rxwm(ssp); __ssp_disable_txwm(ssp); + uart_port_unlock_irqrestore(&ssp->port, flags); } /** |
