* [PATCH 1/3] serial: 8250: fix racy uartclk update [not found] <20211015111422.1027-1-johan@kernel.org> @ 2021-10-15 11:14 ` Johan Hovold 2021-10-15 14:23 ` Andy Shevchenko 0 siblings, 1 reply; 2+ messages in thread From: Johan Hovold @ 2021-10-15 11:14 UTC (permalink / raw) To: Greg Kroah-Hartman Cc: Jiri Slaby, Andy Shevchenko, Serge Semin, linux-serial, linux-kernel, Johan Hovold, stable Commit 868f3ee6e452 ("serial: 8250: Add 8250 port clock update method") added a hack to support SoCs where the UART reference clock can change behind the back of the driver but failed to add the proper locking. First, make sure to take a reference to the tty struct to avoid dereferencing a NULL pointer if the clock change races with a hangup. Second, the termios semaphore must be held during the update to prevent a racing termios change. Fixes: 868f3ee6e452 ("serial: 8250: Add 8250 port clock update method") Fixes: c8dff3aa8241 ("serial: 8250: Skip uninitialized TTY port baud rate update") Cc: stable@vger.kernel.org # 5.9 Cc: Serge Semin <Sergey.Semin@baikalelectronics.ru> Signed-off-by: Johan Hovold <johan@kernel.org> --- drivers/tty/serial/8250/8250_port.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c index 66374704747e..e4dd82fd7c2a 100644 --- a/drivers/tty/serial/8250/8250_port.c +++ b/drivers/tty/serial/8250/8250_port.c @@ -2696,21 +2696,32 @@ static unsigned int serial8250_get_baud_rate(struct uart_port *port, void serial8250_update_uartclk(struct uart_port *port, unsigned int uartclk) { struct uart_8250_port *up = up_to_u8250p(port); + struct tty_port *tport = &port->state->port; unsigned int baud, quot, frac = 0; struct ktermios *termios; + struct tty_struct *tty; unsigned long flags; - mutex_lock(&port->state->port.mutex); + tty = tty_port_tty_get(tport); + if (!tty) { + mutex_lock(&tport->mutex); + port->uartclk = uartclk; + mutex_unlock(&tport->mutex); + return; + } + + down_write(&tty->termios_rwsem); + mutex_lock(&tport->mutex); if (port->uartclk == uartclk) goto out_lock; port->uartclk = uartclk; - if (!tty_port_initialized(&port->state->port)) + if (!tty_port_initialized(tport)) goto out_lock; - termios = &port->state->port.tty->termios; + termios = &tty->termios; baud = serial8250_get_baud_rate(port, termios, NULL); quot = serial8250_get_divisor(port, baud, &frac); @@ -2727,7 +2738,9 @@ void serial8250_update_uartclk(struct uart_port *port, unsigned int uartclk) serial8250_rpm_put(up); out_lock: - mutex_unlock(&port->state->port.mutex); + mutex_unlock(&tport->mutex); + up_write(&tty->termios_rwsem); + tty_kref_put(tty); } EXPORT_SYMBOL_GPL(serial8250_update_uartclk); -- 2.32.0 ^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [PATCH 1/3] serial: 8250: fix racy uartclk update 2021-10-15 11:14 ` [PATCH 1/3] serial: 8250: fix racy uartclk update Johan Hovold @ 2021-10-15 14:23 ` Andy Shevchenko 0 siblings, 0 replies; 2+ messages in thread From: Andy Shevchenko @ 2021-10-15 14:23 UTC (permalink / raw) To: Johan Hovold Cc: Greg Kroah-Hartman, Jiri Slaby, Serge Semin, linux-serial, linux-kernel, stable On Fri, Oct 15, 2021 at 01:14:20PM +0200, Johan Hovold wrote: > Commit 868f3ee6e452 ("serial: 8250: Add 8250 port clock update method") > added a hack to support SoCs where the UART reference clock can > change behind the back of the driver but failed to add the proper > locking. > > First, make sure to take a reference to the tty struct to avoid > dereferencing a NULL pointer if the clock change races with a hangup. > > Second, the termios semaphore must be held during the update to prevent > a racing termios change. Nice catch! Thanks, Johan, for fixing this! Acked-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> > Fixes: 868f3ee6e452 ("serial: 8250: Add 8250 port clock update method") > Fixes: c8dff3aa8241 ("serial: 8250: Skip uninitialized TTY port baud rate update") > Cc: stable@vger.kernel.org # 5.9 > Cc: Serge Semin <Sergey.Semin@baikalelectronics.ru> > Signed-off-by: Johan Hovold <johan@kernel.org> > --- > drivers/tty/serial/8250/8250_port.c | 21 +++++++++++++++++---- > 1 file changed, 17 insertions(+), 4 deletions(-) > > diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c > index 66374704747e..e4dd82fd7c2a 100644 > --- a/drivers/tty/serial/8250/8250_port.c > +++ b/drivers/tty/serial/8250/8250_port.c > @@ -2696,21 +2696,32 @@ static unsigned int serial8250_get_baud_rate(struct uart_port *port, > void serial8250_update_uartclk(struct uart_port *port, unsigned int uartclk) > { > struct uart_8250_port *up = up_to_u8250p(port); > + struct tty_port *tport = &port->state->port; > unsigned int baud, quot, frac = 0; > struct ktermios *termios; > + struct tty_struct *tty; > unsigned long flags; > > - mutex_lock(&port->state->port.mutex); > + tty = tty_port_tty_get(tport); > + if (!tty) { > + mutex_lock(&tport->mutex); > + port->uartclk = uartclk; > + mutex_unlock(&tport->mutex); > + return; > + } > + > + down_write(&tty->termios_rwsem); > + mutex_lock(&tport->mutex); > > if (port->uartclk == uartclk) > goto out_lock; > > port->uartclk = uartclk; > > - if (!tty_port_initialized(&port->state->port)) > + if (!tty_port_initialized(tport)) > goto out_lock; > > - termios = &port->state->port.tty->termios; > + termios = &tty->termios; > > baud = serial8250_get_baud_rate(port, termios, NULL); > quot = serial8250_get_divisor(port, baud, &frac); > @@ -2727,7 +2738,9 @@ void serial8250_update_uartclk(struct uart_port *port, unsigned int uartclk) > serial8250_rpm_put(up); > > out_lock: > - mutex_unlock(&port->state->port.mutex); > + mutex_unlock(&tport->mutex); > + up_write(&tty->termios_rwsem); > + tty_kref_put(tty); > } > EXPORT_SYMBOL_GPL(serial8250_update_uartclk); > > -- > 2.32.0 > -- With Best Regards, Andy Shevchenko ^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2021-10-15 11:23 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <20211015111422.1027-1-johan@kernel.org>
2021-10-15 11:14 ` [PATCH 1/3] serial: 8250: fix racy uartclk update Johan Hovold
2021-10-15 14:23 ` Andy Shevchenko
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).