Linux Serial subsystem development
 help / color / mirror / Atom feed
* [PATCH 4/5] serial: core: simplify clipping logic in uart_get_baud_rate()
From: Hugo Villeneuve @ 2026-04-10 15:20 UTC (permalink / raw)
  To: gregkh, jirislaby
  Cc: hugo, biju.das.jz, linux-kernel, linux-serial, Hugo Villeneuve
In-Reply-To: <20260410152022.2146488-1-hugo@hugovil.com>

From: Hugo Villeneuve <hvilleneuve@dimonoff.com>

Simplify the clipping logic in uart_get_baud_rate() to improve code
readability.

Signed-off-by: Hugo Villeneuve <hvilleneuve@dimonoff.com>
---
 drivers/tty/serial/serial_core.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c
index e6a8ab40442d9..f89c0dc295163 100644
--- a/drivers/tty/serial/serial_core.c
+++ b/drivers/tty/serial/serial_core.c
@@ -543,11 +543,11 @@ uart_get_baud_rate(struct uart_port *port, struct ktermios *termios,
 		 */
 		if (!hung_up) {
 			if (baud <= min)
-				tty_termios_encode_baud_rate(termios,
-							min + 1, min + 1);
+				baud = min + 1;
 			else
-				tty_termios_encode_baud_rate(termios,
-							max - 1, max - 1);
+				baud = max - 1;
+
+			tty_termios_encode_baud_rate(termios, baud, baud);
 		}
 	}
 	return 0;
-- 
2.47.3


^ permalink raw reply related

* [PATCH 3/5] serial: core: update uart_get_baud_rate() obsolete comments
From: Hugo Villeneuve @ 2026-04-10 15:20 UTC (permalink / raw)
  To: gregkh, jirislaby
  Cc: hugo, biju.das.jz, linux-kernel, linux-serial, Hugo Villeneuve
In-Reply-To: <20260410152022.2146488-1-hugo@hugovil.com>

From: Hugo Villeneuve <hvilleneuve@dimonoff.com>

Update obsolete comments to match the actual code.

Signed-off-by: Hugo Villeneuve <hvilleneuve@dimonoff.com>
---
 drivers/tty/serial/serial_core.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c
index 89cebdd278410..e6a8ab40442d9 100644
--- a/drivers/tty/serial/serial_core.c
+++ b/drivers/tty/serial/serial_core.c
@@ -465,7 +465,8 @@ EXPORT_SYMBOL(uart_update_timeout);
  * baud.
  *
  * If the new baud rate is invalid, try the @old termios setting. If it's still
- * invalid, we try 9600 baud. If that is also invalid 0 is returned.
+ * invalid, clip to the nearest chip supported rate.
+ * If that is also invalid 0 is returned.
  *
  * The @termios structure is updated to reflect the baud rate we're actually
  * going to be using. Don't do this for the case where B0 is requested ("hang
@@ -523,7 +524,7 @@ uart_get_baud_rate(struct uart_port *port, struct ktermios *termios,
 			return baud;
 
 		/*
-		 * Oops, the quotient was zero.  Try again with
+		 * If the range cannot be met then try again with
 		 * the old baud rate if possible.
 		 */
 		termios->c_cflag &= ~CBAUD;
-- 
2.47.3


^ permalink raw reply related

* [PATCH 2/5] serial: apbuart: remove check for zero baud rate from uart_get_baud_rate()
From: Hugo Villeneuve @ 2026-04-10 15:20 UTC (permalink / raw)
  To: gregkh, jirislaby
  Cc: hugo, biju.das.jz, linux-kernel, linux-serial, Hugo Villeneuve
In-Reply-To: <20260410152022.2146488-1-hugo@hugovil.com>

From: Hugo Villeneuve <hvilleneuve@dimonoff.com>

The minimum baud rate supported by this driver is 0, so even for the B0
case, uart_get_baud_rate() will return 9600, not zero. This check predates
commit 16ae2a877bf4 ("serial: Fix crash if the minimum rate of the device
is > 9600 baud") and is no longer necessary so remove it.

Signed-off-by: Hugo Villeneuve <hvilleneuve@dimonoff.com>
---
 drivers/tty/serial/apbuart.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/tty/serial/apbuart.c b/drivers/tty/serial/apbuart.c
index 3e46341cfff8a..afb04d727203e 100644
--- a/drivers/tty/serial/apbuart.c
+++ b/drivers/tty/serial/apbuart.c
@@ -210,8 +210,6 @@ static void apbuart_set_termios(struct uart_port *port,
 
 	/* Ask the core to calculate the divisor for us. */
 	baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk / 16);
-	if (baud == 0)
-		panic("invalid baudrate %i\n", port->uartclk / 16);
 
 	/* uart_get_divisor calc a *16 uart freq, apbuart is *8 */
 	quot = (uart_get_divisor(port, baud)) * 2;
-- 
2.47.3


^ permalink raw reply related

* [PATCH 5/5] serial: core: prevent division by zero by always returning non-zero baud rate
From: Hugo Villeneuve @ 2026-04-10 15:20 UTC (permalink / raw)
  To: gregkh, jirislaby
  Cc: hugo, biju.das.jz, linux-kernel, linux-serial, Hugo Villeneuve
In-Reply-To: <20260410152022.2146488-1-hugo@hugovil.com>

From: Hugo Villeneuve <hvilleneuve@dimonoff.com>

If a device has a minimum baud rate > 9600 bauds, and a new termios baud
rate of 0 (hang up) is requested, uart_get_baud_rate() will return 0.
Most drivers do not check this return value and call uart_update_timeout()
with this zero baud rate, which will trigger a "Division by zero in kernel"
fault:

  stty -F /dev/ttySC0 0

  Division by zero in kernel.
  ...

Fix by returning the larger of 9600 or min for the B0 case. This now
ensures that a non-zero baud rate is returned, and greatly simplifies the
code.

Signed-off-by: Hugo Villeneuve <hvilleneuve@dimonoff.com>
---
Tested with the sc16is7xx driver by setting the minimum baudrate to 19200.

If a "Fixes" tag is needed, this would probably be:
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
This would also imply, probably, to merge this patch with the previous ones
(touching serial_core.c) to make porting easier to stable trees...
---
 drivers/tty/serial/serial_core.c | 29 ++++++++++++-----------------
 1 file changed, 12 insertions(+), 17 deletions(-)

diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c
index f89c0dc295163..075a69164aa7c 100644
--- a/drivers/tty/serial/serial_core.c
+++ b/drivers/tty/serial/serial_core.c
@@ -462,11 +462,10 @@ EXPORT_SYMBOL(uart_update_timeout);
  *
  * Decode the termios structure into a numeric baud rate, taking account of the
  * magic 38400 baud rate (with spd_* flags), and mapping the %B0 rate to 9600
- * baud.
+ * baud or min argument, whichever is greater.
  *
  * If the new baud rate is invalid, try the @old termios setting. If it's still
  * invalid, clip to the nearest chip supported rate.
- * If that is also invalid 0 is returned.
  *
  * The @termios structure is updated to reflect the baud rate we're actually
  * going to be using. Don't do this for the case where B0 is requested ("hang
@@ -481,7 +480,6 @@ uart_get_baud_rate(struct uart_port *port, struct ktermios *termios,
 	unsigned int try;
 	unsigned int baud;
 	unsigned int altbaud;
-	int hung_up = 0;
 	upf_t flags = port->flags & UPF_SPD_MASK;
 
 	switch (flags) {
@@ -515,10 +513,8 @@ uart_get_baud_rate(struct uart_port *port, struct ktermios *termios,
 		/*
 		 * Special case: B0 rate.
 		 */
-		if (baud == 0) {
-			hung_up = 1;
-			baud = 9600;
-		}
+		if (baud == 0)
+			return max(min, 9600);
 
 		if (baud >= min && baud <= max)
 			return baud;
@@ -530,9 +526,7 @@ uart_get_baud_rate(struct uart_port *port, struct ktermios *termios,
 		termios->c_cflag &= ~CBAUD;
 		if (old) {
 			baud = tty_termios_baud_rate(old);
-			if (!hung_up)
-				tty_termios_encode_baud_rate(termios,
-								baud, baud);
+			tty_termios_encode_baud_rate(termios, baud, baud);
 			old = NULL;
 			continue;
 		}
@@ -541,15 +535,16 @@ uart_get_baud_rate(struct uart_port *port, struct ktermios *termios,
 		 * As a last resort, if the range cannot be met then clip to
 		 * the nearest chip supported rate.
 		 */
-		if (!hung_up) {
-			if (baud <= min)
-				baud = min + 1;
-			else
-				baud = max - 1;
+		if (baud <= min)
+			baud = min + 1;
+		else
+			baud = max - 1;
 
-			tty_termios_encode_baud_rate(termios, baud, baud);
-		}
+		tty_termios_encode_baud_rate(termios, baud, baud);
 	}
+
+	/* Should never happen */
+	WARN_ON(1);
 	return 0;
 }
 EXPORT_SYMBOL(uart_get_baud_rate);
-- 
2.47.3


^ permalink raw reply related

* [PATCH 1/5] serial: icom: remove check for zero baud rate from uart_get_baud_rate()
From: Hugo Villeneuve @ 2026-04-10 15:20 UTC (permalink / raw)
  To: gregkh, jirislaby
  Cc: hugo, biju.das.jz, linux-kernel, linux-serial, Hugo Villeneuve
In-Reply-To: <20260410152022.2146488-1-hugo@hugovil.com>

From: Hugo Villeneuve <hvilleneuve@dimonoff.com>

The minimum baud rate supported by this driver is 300, so even for the B0
case, uart_get_baud_rate() will return 9600, not zero. This check predates
commit 16ae2a877bf4 ("serial: Fix crash if the minimum rate of the device
is > 9600 baud") and is no longer necessary so remove it.

Signed-off-by: Hugo Villeneuve <hvilleneuve@dimonoff.com>
---
 drivers/tty/serial/icom.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/tty/serial/icom.c b/drivers/tty/serial/icom.c
index bcdc072084860..b6399d86a0bc3 100644
--- a/drivers/tty/serial/icom.c
+++ b/drivers/tty/serial/icom.c
@@ -1396,8 +1396,6 @@ static void icom_set_termios(struct uart_port *port, struct ktermios *termios,
 	baud = uart_get_baud_rate(port, termios, old_termios,
 				  icom_acfg_baud[0],
 				  icom_acfg_baud[BAUD_TABLE_LIMIT]);
-	if (!baud)
-		baud = 9600;	/* B0 transition handled in rs_set_termios */
 
 	for (index = 0; index < BAUD_TABLE_LIMIT; index++) {
 		if (icom_acfg_baud[index] == baud) {
-- 
2.47.3


^ permalink raw reply related

* [PATCH 0/5] serial: core: improve safety of uart_get_baud_rate()
From: Hugo Villeneuve @ 2026-04-10 15:20 UTC (permalink / raw)
  To: gregkh, jirislaby
  Cc: hugo, biju.das.jz, linux-kernel, linux-serial, Hugo Villeneuve

From: Hugo Villeneuve <hvilleneuve@dimonoff.com>

serial: core: improve safety of uart_get_baud_rate()

Hello,
this patch series brings some improvements to uart_get_baud_rate() by
making it safer.

This originate from a review and discussions of a patch by Biju Das [1] to
fix a potential division by zero bug in the Renesas serial drivers
sh-sci and rsci.

First the comments in uart_get_baud_rate() are extremely outdated and no
longer match what the code does, which does not help when trying to fully
understand what the function does. One of the patch in this series updates
them.

All drivers, except apbuart and icom, call uart_get_baud_rate() and do not
check the returned baud rate, because it is assumed that it cannot return a
zero value. However, not all devices support a speed of 9600, and for these
uart_get_baud_rate() could return zero for the B0 case. This in turn
could trigger a "Division by zero in kernel" fault.

To be clear, this doesn't originate from a crash report, but from analyzing
the code during the above mentioned review. To test this potential bug, I
simply modified the "min" baud rate passed as argument to
uart_get_baud_rate() to 19200 for the sc16is7xx driver, and was able to
trigger the fault with "stty /dev/ttySC0 0" set to a zero baud rate
(hang up).

Historically, there was commit 16ae2a877bf4 ("serial: Fix crash if the minimum rate of the device is > 9600 baud")
in 2010 to try to prevent a zero value being returned, and added a warning
to that effect.

Then commit 23bf72faaebd ("serial: core: tidy invalid baudrate handling in uart_get_baud_rate")
in 2023 removed the warning:

  uart_get_baud_rate has input parameters 'min' and 'max' limiting the
  range of acceptable baud rates from the caller's perspective. If neither
  current or old termios structures have acceptable baud rate setting and
  9600 is not in the min/max range either the function returns 0 and
  issues a warning.
  However for a UART that does not support speed of 9600 baud this is
  expected behavior.
  Clarify that 0 can be (and always could be) returned from the
  uart_get_baud_rate. Don't issue a warning in that case.

To remove any ambiguity, and to make sure all drivers handle the returned
value the same, make sure uart_get_baud_rate() will always return a
non-zero value in all scenarios.

This ensures that for devices that do not support a speed of 9600, and B0
is the desired baud rate specified in termios, then the returned value will
be 9600 or the input parameters 'min', whichever is the greatest.

Tested on a custom board with a VAR-SOM-6UL SOM and a sc16is752 DUART.

Thank you.

Link [1] https://lore.kernel.org/all/20260408142105.310210-1-biju.das.jz@bp.renesas.com/raw

Hugo Villeneuve (5):
  serial: icom: remove check for zero baud rate from
    uart_get_baud_rate()
  serial: apbuart: remove check for zero baud rate from
    uart_get_baud_rate()
  serial: core: update uart_get_baud_rate() obsolete comments
  serial: core: simplify clipping logic in uart_get_baud_rate()
  serial: core: prevent division by zero by always returning non-zero
    baud rate

 drivers/tty/serial/apbuart.c     |  2 --
 drivers/tty/serial/icom.c        |  2 --
 drivers/tty/serial/serial_core.c | 34 ++++++++++++++------------------
 3 files changed, 15 insertions(+), 23 deletions(-)


base-commit: a1a81aef99e853dec84241d701fbf587d713eb5b
-- 
2.47.3


^ permalink raw reply

* [PATCH tty v2 2/2] serial: 8250: Add support for console hardware flow control
From: John Ogness @ 2026-04-10 14:48 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Jiri Slaby
  Cc: linux-kernel, Ilpo Järvinen, Ingo Molnar, Thomas Gleixner,
	Osama Abdelkader, Andy Shevchenko, Jiayuan Chen, Gerhard Engleder,
	Dr. David Alan Gilbert, Joseph Tilahun, linux-serial
In-Reply-To: <20260410144949.16581-1-john.ogness@linutronix.de>

The kernel documentation specifies that the console option 'r' can
be used to enable hardware flow control for console writes. The 8250
driver does include code for hardware flow control on the console if
the UPF_CONS_FLOW flag is set, but there is no code path that sets
this flag. However, that is not the only issue. The problems are:

1. Specifying the console option 'r' does not lead to UPF_CONS_FLOW
   being set.

2. Even if UPF_CONS_FLOW would be set, serial8250_register_8250_port()
   clears it.

3. When the console option 'r' is specified, uart_set_options()
   attempts to initialize the port for CRTSCTS. However, afterwards
   it does not set the UPSTAT_CTS_ENABLE status bit and therefore on
   boot, uart_cts_enabled() is always false. This policy bit is
   important for console drivers as a criteria if they may poll CTS.

4. Even though uart_set_options() attempts to initialize the port
   for CRTSCTS, the 8250 set_termios() callback does not enable the
   RTS signal (TIOCM_RTS) and thus the hardware is not properly
   initialized for CTS polling.

5. Even if modem control was properly setup for CTS polling
   (TIOCM_RTS), uart_configure_port() clears TIOCM_RTS, thus
   breaking CTS polling.

6. wait_for_xmitr() and serial8250_console_write() use the
   UPF_CONS_FLOW bit to decide if CTS polling should occur. However,
   the condition should also include a check that it is not in RS485
   mode and CRTSCTS is actually enabled in the hardware.

Address all these issues as conservatively as possible by gating them
behind checks focussed on the user specifying console hardware flow
control support and the hardware being configured for CTS polling
at the time of the write to the UART.

Since checking the UPSTAT_CTS_ENABLE status bit is a part of the new
condition gate, these changes also support runtime termios updates to
disable/enable CRTSCTS.

Signed-off-by: John Ogness <john.ogness@linutronix.de>
---
 drivers/tty/serial/8250/8250_core.c |  6 +++++-
 drivers/tty/serial/8250/8250_port.c | 14 ++++++++++++--
 drivers/tty/serial/serial_core.c    | 21 ++++++++++++++++++++-
 include/linux/serial_core.h         |  8 ++++++++
 4 files changed, 45 insertions(+), 4 deletions(-)

diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c
index a428e88938eb7..ff4c9972d4576 100644
--- a/drivers/tty/serial/8250/8250_core.c
+++ b/drivers/tty/serial/8250/8250_core.c
@@ -693,6 +693,7 @@ static void serial_8250_overrun_backoff_work(struct work_struct *work)
 int serial8250_register_8250_port(const struct uart_8250_port *up)
 {
 	struct uart_8250_port *uart;
+	upf_t console_hwflow;
 	int ret;
 
 	if (up->port.uartclk == 0)
@@ -716,6 +717,9 @@ int serial8250_register_8250_port(const struct uart_8250_port *up)
 	if (uart->port.type == PORT_8250_CIR)
 		return -ENODEV;
 
+	/* Preserve specified console hardware flow control. */
+	console_hwflow = uart->port.flags & UPF_CONS_FLOW;
+
 	if (uart->port.dev)
 		uart_remove_one_port(&serial8250_reg, &uart->port);
 
@@ -729,7 +733,7 @@ int serial8250_register_8250_port(const struct uart_8250_port *up)
 	uart->port.fifosize     = up->port.fifosize;
 	uart->port.regshift     = up->port.regshift;
 	uart->port.iotype       = up->port.iotype;
-	uart->port.flags        = up->port.flags | UPF_BOOT_AUTOCONF;
+	uart->port.flags        = up->port.flags | UPF_BOOT_AUTOCONF | console_hwflow;
 	uart->bugs		= up->bugs;
 	uart->port.mapbase      = up->port.mapbase;
 	uart->port.mapsize      = up->port.mapsize;
diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c
index a739350e634f9..6c8830943b0c0 100644
--- a/drivers/tty/serial/8250/8250_port.c
+++ b/drivers/tty/serial/8250/8250_port.c
@@ -1989,7 +1989,7 @@ static void wait_for_xmitr(struct uart_8250_port *up, int bits)
 	tx_ready = wait_for_lsr(up, bits);
 
 	/* Wait up to 1s for flow control if necessary */
-	if (up->port.flags & UPF_CONS_FLOW) {
+	if (uart_console_hwflow_active(&up->port)) {
 		for (tmout = 1000000; tmout; tmout--) {
 			unsigned int msr = serial_in(up, UART_MSR);
 			up->msr_saved_flags |= msr & MSR_SAVE_FLAGS;
@@ -2786,6 +2786,12 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios,
 		serial8250_set_efr(port, termios);
 		serial8250_set_divisor(port, baud, quot, frac);
 		serial8250_set_fcr(port, termios);
+		/* Consoles manually poll CTS for hardware flow control. */
+		if (uart_console(port) &&
+		    !(port->rs485.flags & SER_RS485_ENABLED)
+		    && termios->c_cflag & CRTSCTS) {
+			port->mctrl |= TIOCM_RTS;
+		}
 		serial8250_set_mctrl(port, port->mctrl);
 	}
 
@@ -3355,7 +3361,7 @@ void serial8250_console_write(struct uart_8250_port *up, const char *s,
 		 * it regardless of the CTS state. Therefore, only use fifo
 		 * if we don't use control flow.
 		 */
-		!(up->port.flags & UPF_CONS_FLOW);
+		!uart_console_hwflow_active(&up->port);
 
 	if (likely(use_fifo))
 		serial8250_console_fifo_write(up, s, count);
@@ -3425,6 +3431,10 @@ int serial8250_console_setup(struct uart_port *port, char *options, bool probe)
 	if (ret)
 		return ret;
 
+	/* Allow user-specified hardware flow control. */
+	if (flow == 'r')
+		port->flags |= UPF_CONS_FLOW;
+
 	if (port->dev)
 		pm_runtime_get_sync(port->dev);
 
diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c
index 89cebdd278410..a9ea10df4fb8b 100644
--- a/drivers/tty/serial/serial_core.c
+++ b/drivers/tty/serial/serial_core.c
@@ -2235,6 +2235,18 @@ uart_set_options(struct uart_port *port, struct console *co,
 	port->mctrl |= TIOCM_DTR;
 
 	port->ops->set_termios(port, &termios, &dummy);
+
+	/*
+	 * If console hardware flow control was specified and is supported,
+	 * the related policy UPSTAT_CTS_ENABLE must be set to allow console
+	 * drivers to identify if CTS should be used for polling.
+	 */
+	if (flow == 'r' && (termios.c_cflag & CRTSCTS)) {
+		/* Synchronize @status RMW update against the console. */
+		guard(uart_port_lock_irq)(port);
+		port->status |= UPSTAT_CTS_ENABLE;
+	}
+
 	/*
 	 * Allow the setting of the UART parameters with a NULL console
 	 * too:
@@ -2541,7 +2553,14 @@ uart_configure_port(struct uart_driver *drv, struct uart_state *state,
 		 * We probably don't need a spinlock around this, but
 		 */
 		scoped_guard(uart_port_lock_irqsave, port) {
-			port->mctrl &= TIOCM_DTR;
+			unsigned int mask = TIOCM_DTR;
+
+			/* Console hardware flow control polls CTS. */
+			if (uart_console_hwflow_active(port))
+				mask |= TIOCM_RTS;
+
+			port->mctrl &= mask;
+
 			if (!(port->rs485.flags & SER_RS485_ENABLED))
 				port->ops->set_mctrl(port, port->mctrl);
 		}
diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h
index 666430b478997..07bd3bd6c8355 100644
--- a/include/linux/serial_core.h
+++ b/include/linux/serial_core.h
@@ -1163,6 +1163,14 @@ static inline bool uart_softcts_mode(struct uart_port *uport)
 	return ((uport->status & mask) == UPSTAT_CTS_ENABLE);
 }
 
+static inline bool uart_console_hwflow_active(struct uart_port *uport)
+{
+	return uart_console(uport) &&
+	       !(uport->rs485.flags & SER_RS485_ENABLED) &&
+	       (uport->flags & UPF_CONS_FLOW) &&
+	       uart_cts_enabled(uport);
+}
+
 /*
  * The following are helper functions for the low level drivers.
  */
-- 
2.47.3


^ permalink raw reply related

* [PATCH tty v2 1/2] serial: 8250: Check LSR timeout on console flow control
From: John Ogness @ 2026-04-10 14:48 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Jiri Slaby
  Cc: linux-kernel, Ilpo Järvinen, Andy Shevchenko, linux-serial
In-Reply-To: <20260410144949.16581-1-john.ogness@linutronix.de>

wait_for_xmitr() calls wait_for_lsr() to wait for the transmission
registers to be empty. wait_for_lsr() can timeout after a reasonable
amount of time.

When console flow control is active (UPF_CONS_FLOW), wait_for_xmitr()
additionally polls CTS, waiting for the peer to signal that it is
ready to receive more data.

If hardware flow control is enabled (auto CTS) and the peer deasserts
CTS, wait_for_lsr() will timeout. If additionally console flow
control is active and while polling CTS the peer asserts CTS, the
console will assume it can immediately transmit, even though the
transmission registers may not be empty. This can lead to data loss.

Avoid this problem by performing an extra wait_for_lsr() upon CTS
assertion if wait_for_lsr() previously timed out.

Signed-off-by: John Ogness <john.ogness@linutronix.de>
---
 drivers/tty/serial/8250/8250_port.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c
index af78cc02f38e7..a739350e634f9 100644
--- a/drivers/tty/serial/8250/8250_port.c
+++ b/drivers/tty/serial/8250/8250_port.c
@@ -1984,16 +1984,20 @@ static bool wait_for_lsr(struct uart_8250_port *up, int bits)
 static void wait_for_xmitr(struct uart_8250_port *up, int bits)
 {
 	unsigned int tmout;
+	bool tx_ready;
 
-	wait_for_lsr(up, bits);
+	tx_ready = wait_for_lsr(up, bits);
 
 	/* Wait up to 1s for flow control if necessary */
 	if (up->port.flags & UPF_CONS_FLOW) {
 		for (tmout = 1000000; tmout; tmout--) {
 			unsigned int msr = serial_in(up, UART_MSR);
 			up->msr_saved_flags |= msr & MSR_SAVE_FLAGS;
-			if (msr & UART_MSR_CTS)
+			if (msr & UART_MSR_CTS) {
+				if (!tx_ready)
+					wait_for_lsr(up, bits);
 				break;
+			}
 			udelay(1);
 			touch_nmi_watchdog();
 		}
-- 
2.47.3


^ permalink raw reply related

* [PATCH tty v2 0/2] 8250: Add console flow control
From: John Ogness @ 2026-04-10 14:48 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Jiri Slaby
  Cc: linux-kernel, Ilpo Järvinen, Andy Shevchenko, linux-serial,
	Ingo Molnar, Thomas Gleixner, Osama Abdelkader, Andy Shevchenko,
	Jiayuan Chen, Gerhard Engleder, Dr. David Alan Gilbert,
	Joseph Tilahun

Hi,

This is v2 of a series to implement console flow control for the
8250 serial driver. v1 is here [0].

The 8250 driver already has code in place to support console flow
control. However, there is no way to activate it and it is
incomplete. This series provides the necessary missing pieces while
attempting to be as conservative as possible, so as not to introduce
any side effects into the many 8250 variants or other non-8250 serial
drivers.

Changes since v1:

- Prepend a patch to perform an extra LSR wait after CTS assertion if
  the initial LSR wait timed out.

- Close a window in serial8250_register_8250_port() where console
  flow control was briefly disabled.

- Add port lock synchronization to the port->status RMW update in
  uart_set_options().

John Ogness

[0] https://lore.kernel.org/lkml/20260331141502.6233-1-john.ogness@linutronix.de

John Ogness (2):
  serial: 8250: Check LSR timeout on console flow control
  serial: 8250: Add support for console hardware flow control

 drivers/tty/serial/8250/8250_core.c |  6 +++++-
 drivers/tty/serial/8250/8250_port.c | 22 ++++++++++++++++++----
 drivers/tty/serial/serial_core.c    | 21 ++++++++++++++++++++-
 include/linux/serial_core.h         |  8 ++++++++
 4 files changed, 51 insertions(+), 6 deletions(-)


base-commit: a1a81aef99e853dec84241d701fbf587d713eb5b
-- 
2.47.3


^ permalink raw reply

* Re: [PATCH] serial: sh-sci: fix memory region release in error path
From: Greg KH @ 2026-04-10 10:46 UTC (permalink / raw)
  To: zenghongling
  Cc: jirislaby, geert+renesas, biju.das.jz, wsa+renesas,
	thierry.bultel.yh, prabhakar.mahadev-lad.rj, linux-kernel,
	linux-serial, zhongling0719, kernel test robot
In-Reply-To: <20260410092143.30971-1-zenghongling@kylinos.cn>

On Fri, Apr 10, 2026 at 05:21:43PM +0800, zenghongling wrote:
> The sci_request_port() function uses request_mem_region() to reserve
> I/O memory, but in the error path when sci_remap_port() fails, it
> incorrectly calls release_resource() instead of release_mem_region().
> 
> This mismatch can cause resource accounting issues. Fix it by using
> the correct release function, consistent with sci_release_port().
> 
> Reported-by: kernel test robot <lkp@intel.com>

The kernel test robot reported this?  Where is that report?

> Signed-off-by: zenghongling <zenghongling@kylinos.cn>

Can you use your name please, not your email alias.

thanks,

greg k-h

^ permalink raw reply

* [PATCH] serial: sh-sci: fix memory region release in error path
From: zenghongling @ 2026-04-10  9:21 UTC (permalink / raw)
  To: gregkh, jirislaby, geert+renesas, biju.das.jz, wsa+renesas,
	thierry.bultel.yh, prabhakar.mahadev-lad.rj
  Cc: linux-kernel, linux-serial, zhongling0719, zenghongling,
	kernel test robot

The sci_request_port() function uses request_mem_region() to reserve
I/O memory, but in the error path when sci_remap_port() fails, it
incorrectly calls release_resource() instead of release_mem_region().

This mismatch can cause resource accounting issues. Fix it by using
the correct release function, consistent with sci_release_port().

Reported-by: kernel test robot <lkp@intel.com>
Signed-off-by: zenghongling <zenghongling@kylinos.cn>
---
 drivers/tty/serial/sh-sci.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
index bd7486315338..9e619db27237 100644
--- a/drivers/tty/serial/sh-sci.c
+++ b/drivers/tty/serial/sh-sci.c
@@ -3024,7 +3024,7 @@ int sci_request_port(struct uart_port *port)
 
 	ret = sci_remap_port(port);
 	if (unlikely(ret != 0)) {
-		release_resource(res);
+		release_mem_region(port->mapbase, sport->reg_size);
 		return ret;
 	}
 
-- 
2.25.1


^ permalink raw reply related

* [PATCH RFC] vt: tty: use krefs to fix a potential UAF between kbd_keycode and con_shutdown
From: Wentao Guan @ 2026-04-10  6:55 UTC (permalink / raw)
  To: syzbot+098cefc0911c68db5dab
  Cc: gregkh, jirislaby, linux-kernel, linux-serial, syzkaller-bugs,
	Wentao Guan, stable, syzbot+702b7f311487703dbb18
In-Reply-To: <69d56a91.050a0220.28fc4.0003.GAE@google.com>

syzbot report an KASAN: slab-use-after-free Read in kbd_event (2),
which allocated by alloc_tty_struct->tty_init_dev, accessed by kbd_keycode,
released by tty_release_struct:
tty_release_struct->release_tty->tty->ops->shutdown->con_shutdown.
accessed by
kbd_keycode drivers/tty/vt/keyboard.c:1435
kbd_event+0x3330/0x40d0 drivers/tty/vt/keyboard.c:1515

Use tty_port_tty_get to get a tty ref in kbd_keycode to prevent the UAF,
tty_release_struct use console_lock not protect access tty_struct from
kbd_keycode or another function, so convert it to tty_port_tty_set in
con_install, con_shutdown.

The change is similar as
commit 4a90f09b20f4622dcbff1f0e1e6bae1704f8ad8c ("tty: usb-serial krefs").

Maybe reproduce in:
CPU A		CPU B		CPU C
open /dev/tty
		close /dev/tty
				tty!=NULL
		release_tty()
				access tty_struct

Cc: stable@kernel.org
Reported-by: syzbot+098cefc0911c68db5dab@syzkaller.appspotmail.com
Closes: https://syzbot.org/bug?extid=098cefc0911c68db5dab
Reported-by: syzbot+702b7f311487703dbb18@syzkaller.appspotmail.com
Closes: https://syzbot.org/bug?extid=702b7f311487703dbb18
Signed-off-by: Wentao Guan <guanwentao@uniontech.com>
---
 drivers/tty/vt/keyboard.c | 20 +++++++++++++-------
 drivers/tty/vt/vt.c       |  5 ++---
 2 files changed, 15 insertions(+), 10 deletions(-)

diff --git a/drivers/tty/vt/keyboard.c b/drivers/tty/vt/keyboard.c
index 13bc048f45e86..173c447525ff8 100644
--- a/drivers/tty/vt/keyboard.c
+++ b/drivers/tty/vt/keyboard.c
@@ -517,6 +517,10 @@ static void fn_hold(struct vc_data *vc)
 	 * Note: SCROLLOCK will be set (cleared) by stop_tty (start_tty);
 	 * these routines are also activated by ^S/^Q.
 	 * (And SCROLLOCK can also be set by the ioctl KDSKBLED.)
+	 *
+	 * kbd_keycode(), only from kbd_keycode via k_handler[], already holds a
+	 * reference to the tty via tty_port_tty_get(), so we can safely
+	 * access port->tty here without an extra kref.
 	 */
 	if (tty->flow.stopped)
 		start_tty(tty);
@@ -1378,7 +1382,7 @@ static void kbd_keycode(unsigned int keycode, int down, bool hw_raw)
 	struct keyboard_notifier_param param = { .vc = vc, .value = keycode, .down = down };
 	int rc;
 
-	tty = vc->port.tty;
+	tty = tty_port_tty_get(&vc->port);
 
 	if (tty && (!tty->driver_data)) {
 		/* No driver data? Strange. Okay we fix it then. */
@@ -1438,7 +1442,7 @@ static void kbd_keycode(unsigned int keycode, int down, bool hw_raw)
 		 * characters get aren't echoed locally. This makes key repeat
 		 * usable with slow applications and under heavy loads.
 		 */
-		return;
+		goto out;
 	}
 
 	param.shift = shift_final = (shift_state | kbd->slockstate) ^ kbd->lockstate;
@@ -1452,7 +1456,7 @@ static void kbd_keycode(unsigned int keycode, int down, bool hw_raw)
 					   KBD_UNBOUND_KEYCODE, &param);
 		do_compute_shiftstate();
 		kbd->slockstate = 0;
-		return;
+		goto out;
 	}
 
 	if (keycode < NR_KEYS)
@@ -1460,7 +1464,7 @@ static void kbd_keycode(unsigned int keycode, int down, bool hw_raw)
 	else if (keycode >= KEY_BRL_DOT1 && keycode <= KEY_BRL_DOT8)
 		keysym = U(K(KT_BRL, keycode - KEY_BRL_DOT1 + 1));
 	else
-		return;
+		goto out;
 
 	type = KTYP(keysym);
 
@@ -1471,7 +1475,7 @@ static void kbd_keycode(unsigned int keycode, int down, bool hw_raw)
 		if (rc != NOTIFY_STOP)
 			if (down && !(raw_mode || kbd->kbdmode == VC_OFF))
 				k_unicode(vc, keysym, !down);
-		return;
+		goto out;
 	}
 
 	type -= 0xf0;
@@ -1489,10 +1493,10 @@ static void kbd_keycode(unsigned int keycode, int down, bool hw_raw)
 	rc = atomic_notifier_call_chain(&keyboard_notifier_list,
 					KBD_KEYSYM, &param);
 	if (rc == NOTIFY_STOP)
-		return;
+		goto out;
 
 	if ((raw_mode || kbd->kbdmode == VC_OFF) && type != KT_SPEC && type != KT_SHIFT)
-		return;
+		goto out;
 
 	(*k_handler[type])(vc, KVAL(keysym), !down);
 
@@ -1501,6 +1505,8 @@ static void kbd_keycode(unsigned int keycode, int down, bool hw_raw)
 
 	if (type != KT_SLOCK)
 		kbd->slockstate = 0;
+out:
+	tty_kref_put(tty);
 }
 
 static void kbd_event(struct input_handle *handle, unsigned int event_type,
diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
index e2df99e3d4580..acded112cae2b 100644
--- a/drivers/tty/vt/vt.c
+++ b/drivers/tty/vt/vt.c
@@ -3661,7 +3661,7 @@ static int con_install(struct tty_driver *driver, struct tty_struct *tty)
 		return ret;
 
 	tty->driver_data = vc;
-	vc->port.tty = tty;
+	tty_port_tty_set(&vc->port, tty);
 	tty_port_get(&vc->port);
 
 	if (!tty->winsize.ws_row && !tty->winsize.ws_col) {
@@ -3693,8 +3693,7 @@ static void con_shutdown(struct tty_struct *tty)
 	struct vc_data *vc = tty->driver_data;
 	BUG_ON(vc == NULL);
 
-	guard(console_lock)();
-	vc->port.tty = NULL;
+	tty_port_tty_set(&vc->port, NULL);
 }
 
 static void con_cleanup(struct tty_struct *tty)
-- 
2.30.2


^ permalink raw reply related

* Re: [PATCH] tty: ipwireless: fix memory leak in do_go_offline()
From: Greg Kroah-Hartman @ 2026-04-10  4:54 UTC (permalink / raw)
  To: Qingfang Deng
  Cc: dsterba, Jiri Kosina, David Sterba, Jiri Slaby,
	Stephen Blackheath, Ben Martel, linux-kernel, linux-serial
In-Reply-To: <CALW65jY1qjiLNd_viqgiXodwGe1VzQx_qKUU2rRHMUp8TK7j_g@mail.gmail.com>

On Fri, Apr 10, 2026 at 12:01:23PM +0800, Qingfang Deng wrote:
> Hi, Greg and David,
> 
> On Thu, Mar 12, 2026 at 8:00 PM David Sterba <dsterba@suse.cz> wrote:
> >
> > Thanks, but the driver is going to be deleted.
> 
> Even if this is being removed from tty-next, the fix should be applied
> and backported to -stable.

We can just delete it from stable trees, as obviously no one is using
it.

thanks,

greg k-h

^ permalink raw reply

* Re: [PATCH] tty: ipwireless: fix memory leak in do_go_offline()
From: Qingfang Deng @ 2026-04-10  4:01 UTC (permalink / raw)
  To: dsterba
  Cc: Jiri Kosina, David Sterba, Greg Kroah-Hartman, Jiri Slaby,
	Stephen Blackheath, Ben Martel, linux-kernel, linux-serial
In-Reply-To: <20260312120036.GF5735@suse.cz>

Hi, Greg and David,

On Thu, Mar 12, 2026 at 8:00 PM David Sterba <dsterba@suse.cz> wrote:
>
> Thanks, but the driver is going to be deleted.

Even if this is being removed from tty-next, the fix should be applied
and backported to -stable.

Regards,
Qingfang

^ permalink raw reply

* Re: [PATCH v2 1/2] serial: sh-sci: Avoid divide-by-zero fault
From: Hugo Villeneuve @ 2026-04-09 14:16 UTC (permalink / raw)
  To: Biju Das
  Cc: biju.das.au, Greg Kroah-Hartman, Jiri Slaby, Geert Uytterhoeven,
	Thierry Bultel, wsa+renesas, Prabhakar Mahadev Lad,
	linux-kernel@vger.kernel.org, linux-serial@vger.kernel.org,
	linux-renesas-soc@vger.kernel.org
In-Reply-To: <TYCPR01MB113322203884106612468FB4286582@TYCPR01MB11332.jpnprd01.prod.outlook.com>

Hi Biju,

On Thu, 9 Apr 2026 07:40:02 +0000
Biju Das <biju.das.jz@bp.renesas.com> wrote:

> 
> 
> > -----Original Message-----
> > From: Biju Das
> > Sent: 08 April 2026 20:02
> > To: Hugo Villeneuve <hugo@hugovil.com>
> > Cc: biju.das.au <biju.das.au@gmail.com>; Greg Kroah-Hartman <gregkh@linuxfoundation.org>; Jiri Slaby
> > <jirislaby@kernel.org>; Geert Uytterhoeven <geert+renesas@glider.be>; Thierry Bultel
> > <thierry.bultel.yh@bp.renesas.com>; wsa+renesas <wsa+renesas@sang-engineering.com>; Prabhakar Mahadev
> > Lad <prabhakar.mahadev-lad.rj@bp.renesas.com>; linux-kernel@vger.kernel.org; linux-
> > serial@vger.kernel.org; linux-renesas-soc@vger.kernel.org
> > Subject: RE: [PATCH v2 1/2] serial: sh-sci: Avoid divide-by-zero fault
> > 
> > Hi Hugo,
> > 
> > > -----Original Message-----
> > > From: Hugo Villeneuve <hugo@hugovil.com>
> > > Sent: 08 April 2026 19:15
> > > Subject: Re: [PATCH v2 1/2] serial: sh-sci: Avoid divide-by-zero fault
> > >
> > > Hi Biju,
> > >
> > > On Wed, 8 Apr 2026 17:25:19 +0000
> > > Biju Das <biju.das.jz@bp.renesas.com> wrote:
> > >
> > > > Hi Hugo,
> > > >
> > > > > -----Original Message-----
> > > > > From: Hugo Villeneuve <hugo@hugovil.com>
> > > > > Sent: 08 April 2026 17:52
> > > > > Subject: Re: [PATCH v2 1/2] serial: sh-sci: Avoid divide-by-zero
> > > > > fault
> > > > >
> > > > > Hi Biju,
> > > > >
> > > > > On Wed, 8 Apr 2026 16:35:44 +0000
> > > > > Biju Das <biju.das.jz@bp.renesas.com> wrote:
> > > > >
> > > > > > Hi Hugo,
> > > > > >
> > > > > > Thanks for the feedback.
> > > > > >
> > > > > > > -----Original Message-----
> > > > > > > From: Hugo Villeneuve <hugo@hugovil.com>
> > > > > > > Sent: 08 April 2026 17:31
> > > > > > > Subject: Re: [PATCH v2 1/2] serial: sh-sci: Avoid
> > > > > > > divide-by-zero fault
> > > > > > >
> > > > > > > Hi Biju,
> > > > > > >
> > > > > > > On Wed,  8 Apr 2026 15:20:58 +0100 Biju
> > > > > > > <biju.das.au@gmail.com>
> > > > > > > wrote:
> > > > > > >
> > > > > > > > From: Biju Das <biju.das.jz@bp.renesas.com>
> > > > > > > >
> > > > > > > > uart_update_timeout() computes a timeout value by dividing
> > > > > > > > by the baud rate. If baud is zero — which can occur when the
> > > > > > > > hardware returns an unsupported or invalid rate — this results in a divide-by-zero fault.
> > > > > > >
> > > > > > > baud is returned by uart_get_baud_rate(), so this is not returned by the hardware?
> > > > > >
> > > > > > You are tight, Will update commit description.
> > > > >
> > > > > How can uart_get_baud_rate() return a zero value? If I am not
> > > > > mistaken even for the B0 case, it will return 9600?
> > > >
> > > > As per the comment and code, this API can return 0.
> > > >
> > > > * If the new baud rate is invalid, try the @old termios setting. If
> > > > it's still
> > > > * invalid, we try 9600 baud. If that is also invalid 0 is returned.
> > > >
> > > > In drives/tty currently only 1 driver is checking the return value
> > > > and it calls panic
> > > >
> > > > https://elixir.bootlin.com/linux/v7.0-rc7/source/drivers/tty/serial/
> > > > ap
> > > > buart.c#L214
> > >
> > > Hmmm, more than 1:
> > 
> > >
> > > icom.c:
> > >     if (!baud)
> > >          baud = 9600;    /* B0 transition handled in rs_set_termios */
> > 
> > A zero return from uart_get_baud_rate() is a normal, recoverable condition (unsupported rate requested
> > by userspace) and must not crash the kernel.
> > 
> > Or drop the check like other tty drivers, as SCIF/RSCI IP support 9600 baud rate.
> 
> May be setting a buadrate 115200 is safe in this cas like earlyprintk??
> I will send next version setting buad = 115200, if uart_get_baud_rate() returns 0.

Is it logical to proceed with configuration if it returned zero?

Also we still pass 0 as a minimum value in uart_get_baud_rate(), so
that a baud rate of 75, for example, would be valid, but would trigger a
fault later (division by zero). Wouldn't it be a good idea to also set a
proper minimum baud rate?

-- 
Hugo Villeneuve

^ permalink raw reply

* RE: [PATCH v2 1/2] serial: sh-sci: Avoid divide-by-zero fault
From: Biju Das @ 2026-04-09  7:40 UTC (permalink / raw)
  To: Hugo Villeneuve
  Cc: biju.das.au, Greg Kroah-Hartman, Jiri Slaby, Geert Uytterhoeven,
	Thierry Bultel, wsa+renesas, Prabhakar Mahadev Lad,
	linux-kernel@vger.kernel.org, linux-serial@vger.kernel.org,
	linux-renesas-soc@vger.kernel.org
In-Reply-To: <TYCPR01MB113326DDA1FC854689CE34A6C865B2@TYCPR01MB11332.jpnprd01.prod.outlook.com>



> -----Original Message-----
> From: Biju Das
> Sent: 08 April 2026 20:02
> To: Hugo Villeneuve <hugo@hugovil.com>
> Cc: biju.das.au <biju.das.au@gmail.com>; Greg Kroah-Hartman <gregkh@linuxfoundation.org>; Jiri Slaby
> <jirislaby@kernel.org>; Geert Uytterhoeven <geert+renesas@glider.be>; Thierry Bultel
> <thierry.bultel.yh@bp.renesas.com>; wsa+renesas <wsa+renesas@sang-engineering.com>; Prabhakar Mahadev
> Lad <prabhakar.mahadev-lad.rj@bp.renesas.com>; linux-kernel@vger.kernel.org; linux-
> serial@vger.kernel.org; linux-renesas-soc@vger.kernel.org
> Subject: RE: [PATCH v2 1/2] serial: sh-sci: Avoid divide-by-zero fault
> 
> Hi Hugo,
> 
> > -----Original Message-----
> > From: Hugo Villeneuve <hugo@hugovil.com>
> > Sent: 08 April 2026 19:15
> > Subject: Re: [PATCH v2 1/2] serial: sh-sci: Avoid divide-by-zero fault
> >
> > Hi Biju,
> >
> > On Wed, 8 Apr 2026 17:25:19 +0000
> > Biju Das <biju.das.jz@bp.renesas.com> wrote:
> >
> > > Hi Hugo,
> > >
> > > > -----Original Message-----
> > > > From: Hugo Villeneuve <hugo@hugovil.com>
> > > > Sent: 08 April 2026 17:52
> > > > Subject: Re: [PATCH v2 1/2] serial: sh-sci: Avoid divide-by-zero
> > > > fault
> > > >
> > > > Hi Biju,
> > > >
> > > > On Wed, 8 Apr 2026 16:35:44 +0000
> > > > Biju Das <biju.das.jz@bp.renesas.com> wrote:
> > > >
> > > > > Hi Hugo,
> > > > >
> > > > > Thanks for the feedback.
> > > > >
> > > > > > -----Original Message-----
> > > > > > From: Hugo Villeneuve <hugo@hugovil.com>
> > > > > > Sent: 08 April 2026 17:31
> > > > > > Subject: Re: [PATCH v2 1/2] serial: sh-sci: Avoid
> > > > > > divide-by-zero fault
> > > > > >
> > > > > > Hi Biju,
> > > > > >
> > > > > > On Wed,  8 Apr 2026 15:20:58 +0100 Biju
> > > > > > <biju.das.au@gmail.com>
> > > > > > wrote:
> > > > > >
> > > > > > > From: Biju Das <biju.das.jz@bp.renesas.com>
> > > > > > >
> > > > > > > uart_update_timeout() computes a timeout value by dividing
> > > > > > > by the baud rate. If baud is zero — which can occur when the
> > > > > > > hardware returns an unsupported or invalid rate — this results in a divide-by-zero fault.
> > > > > >
> > > > > > baud is returned by uart_get_baud_rate(), so this is not returned by the hardware?
> > > > >
> > > > > You are tight, Will update commit description.
> > > >
> > > > How can uart_get_baud_rate() return a zero value? If I am not
> > > > mistaken even for the B0 case, it will return 9600?
> > >
> > > As per the comment and code, this API can return 0.
> > >
> > > * If the new baud rate is invalid, try the @old termios setting. If
> > > it's still
> > > * invalid, we try 9600 baud. If that is also invalid 0 is returned.
> > >
> > > In drives/tty currently only 1 driver is checking the return value
> > > and it calls panic
> > >
> > > https://elixir.bootlin.com/linux/v7.0-rc7/source/drivers/tty/serial/
> > > ap
> > > buart.c#L214
> >
> > Hmmm, more than 1:
> 
> >
> > icom.c:
> >     if (!baud)
> >          baud = 9600;    /* B0 transition handled in rs_set_termios */
> 
> A zero return from uart_get_baud_rate() is a normal, recoverable condition (unsupported rate requested
> by userspace) and must not crash the kernel.
> 
> Or drop the check like other tty drivers, as SCIF/RSCI IP support 9600 baud rate.

May be setting a buadrate 115200 is safe in this cas like earlyprintk??
I will send next version setting buad = 115200, if uart_get_baud_rate() returns 0.

Cheers,
Biju

^ permalink raw reply

* [PATCH v2] tty: serial: pch_uart: add check for dma_alloc_coherent()
From: Zhaoyang Yu @ 2026-04-09  5:41 UTC (permalink / raw)
  To: andriy.shevchenko
  Cc: gregkh, jirislaby, kees, fourier.thomas, linux-serial,
	linux-kernel, gszhai, 23120469, Zhaoyang Yu, stable

Add a check for dma_alloc_coherent() failure to prevent a potential
NULL pointer dereference in dma_handle_rx(). Properly release DMA
channels and the PCI device reference using a goto ladder if the
allocation fails.

Fixes: 3c6a483275f4 ("Serial: EG20T: add PCH_UART driver")
Cc: stable@vger.kernel.org
Signed-off-by: Zhaoyang Yu <2426767509@qq.com>
---
Changes in v2:
- Added the Fixes tag for the initial PCH_UART driver commit, per Andy's review.

 drivers/tty/serial/pch_uart.c | 19 +++++++++++++------
 1 file changed, 13 insertions(+), 6 deletions(-)

diff --git a/drivers/tty/serial/pch_uart.c b/drivers/tty/serial/pch_uart.c
index 6729d8e83c3c..ba1fcd663fe2 100644
--- a/drivers/tty/serial/pch_uart.c
+++ b/drivers/tty/serial/pch_uart.c
@@ -689,8 +689,7 @@ static void pch_request_dma(struct uart_port *port)
 	if (!chan) {
 		dev_err(priv->port.dev, "%s:dma_request_channel FAILS(Tx)\n",
 			__func__);
-		pci_dev_put(dma_dev);
-		return;
+		goto err_pci_get;
 	}
 	priv->chan_tx = chan;
 
@@ -704,18 +703,26 @@ static void pch_request_dma(struct uart_port *port)
 	if (!chan) {
 		dev_err(priv->port.dev, "%s:dma_request_channel FAILS(Rx)\n",
 			__func__);
-		dma_release_channel(priv->chan_tx);
-		priv->chan_tx = NULL;
-		pci_dev_put(dma_dev);
-		return;
+		goto err_req_tx;
 	}
 
 	/* Get Consistent memory for DMA */
 	priv->rx_buf_virt = dma_alloc_coherent(port->dev, port->fifosize,
 				    &priv->rx_buf_dma, GFP_KERNEL);
+	if (!priv->rx_buf_virt)
+		goto err_req_rx;
 	priv->chan_rx = chan;
 
 	pci_dev_put(dma_dev);
+	return;
+
+err_req_rx:
+	dma_release_channel(chan);
+err_req_tx:
+	dma_release_channel(priv->chan_tx);
+	priv->chan_tx = NULL;
+err_pci_get:
+	pci_dev_put(dma_dev);
 }
 
 static void pch_dma_rx_complete(void *arg)
-- 
2.50.1


^ permalink raw reply related

* Re: [PATCH] tty: serial: pch_uart: add check for dma_alloc_coherent()
From: 俞朝阳 @ 2026-04-09  5:46 UTC (permalink / raw)
  To: Andy Shevchenko
  Cc: gregkh, jirislaby, kees, fourier.thomas, linux-serial,
	linux-kernel, gszhai, Zhaoyang Yu
In-Reply-To: <adZWm7GxCU_-T0zc@ashevche-desk.local>

Hi Andy,

Thank you for the review and the suggestions!

> Looks like it deserves a Fixes tag.

Agreed. I will find the original commit that introduced this issue and add the proper Fixes tag in the v2 patch. I'll send it out shortly.

> Also ideally this driver should be converted to one of 8250 cases.
> The latter has already DMA support. Note, if you are going this
> direction, I have the hardware to test.

Thank you very much for offering to test on the actual hardware! That is incredibly helpful. 

I agree that converting this driver to the 8250 framework is the right direction. Since that would be a larger refactoring effort, I think it might be best to apply this quick NULL pointer fix first so that the current driver is safe. 

After this fix is settled, I am very interested in taking a look at the 8250 conversion as a follow-up project. I might need some time to study the 8250 DMA framework, but I will definitely reach out with a patch series for you to test when I get there!

Best regards,
Zhaoyang Yu

^ permalink raw reply

* RE: [PATCH v2 1/2] serial: sh-sci: Avoid divide-by-zero fault
From: Biju Das @ 2026-04-08 19:02 UTC (permalink / raw)
  To: Hugo Villeneuve
  Cc: biju.das.au, Greg Kroah-Hartman, Jiri Slaby, Geert Uytterhoeven,
	Thierry Bultel, wsa+renesas, Prabhakar Mahadev Lad,
	linux-kernel@vger.kernel.org, linux-serial@vger.kernel.org,
	linux-renesas-soc@vger.kernel.org
In-Reply-To: <20260408141515.fc210b4b3c86f7a61f680dd1@hugovil.com>

Hi Hugo,

> -----Original Message-----
> From: Hugo Villeneuve <hugo@hugovil.com>
> Sent: 08 April 2026 19:15
> Subject: Re: [PATCH v2 1/2] serial: sh-sci: Avoid divide-by-zero fault
> 
> Hi Biju,
> 
> On Wed, 8 Apr 2026 17:25:19 +0000
> Biju Das <biju.das.jz@bp.renesas.com> wrote:
> 
> > Hi Hugo,
> >
> > > -----Original Message-----
> > > From: Hugo Villeneuve <hugo@hugovil.com>
> > > Sent: 08 April 2026 17:52
> > > Subject: Re: [PATCH v2 1/2] serial: sh-sci: Avoid divide-by-zero
> > > fault
> > >
> > > Hi Biju,
> > >
> > > On Wed, 8 Apr 2026 16:35:44 +0000
> > > Biju Das <biju.das.jz@bp.renesas.com> wrote:
> > >
> > > > Hi Hugo,
> > > >
> > > > Thanks for the feedback.
> > > >
> > > > > -----Original Message-----
> > > > > From: Hugo Villeneuve <hugo@hugovil.com>
> > > > > Sent: 08 April 2026 17:31
> > > > > Subject: Re: [PATCH v2 1/2] serial: sh-sci: Avoid divide-by-zero
> > > > > fault
> > > > >
> > > > > Hi Biju,
> > > > >
> > > > > On Wed,  8 Apr 2026 15:20:58 +0100 Biju <biju.das.au@gmail.com>
> > > > > wrote:
> > > > >
> > > > > > From: Biju Das <biju.das.jz@bp.renesas.com>
> > > > > >
> > > > > > uart_update_timeout() computes a timeout value by dividing by
> > > > > > the baud rate. If baud is zero — which can occur when the
> > > > > > hardware returns an unsupported or invalid rate — this results in a divide-by-zero fault.
> > > > >
> > > > > baud is returned by uart_get_baud_rate(), so this is not returned by the hardware?
> > > >
> > > > You are tight, Will update commit description.
> > >
> > > How can uart_get_baud_rate() return a zero value? If I am not
> > > mistaken even for the B0 case, it will return 9600?
> >
> > As per the comment and code, this API can return 0.
> >
> > * If the new baud rate is invalid, try the @old termios setting. If
> > it's still
> > * invalid, we try 9600 baud. If that is also invalid 0 is returned.
> >
> > In drives/tty currently only 1 driver is checking the return value and
> > it calls panic
> >
> > https://elixir.bootlin.com/linux/v7.0-rc7/source/drivers/tty/serial/ap
> > buart.c#L214
> 
> Hmmm, more than 1:

> 
> icom.c:
>     if (!baud)
>          baud = 9600;    /* B0 transition handled in rs_set_termios */

A zero return from uart_get_baud_rate() is a normal, recoverable condition
(unsupported rate requested by userspace) and must not crash the kernel.

Or drop the check like other tty drivers, as SCIF/RSCI IP support 9600 baud rate.

Cheers,
Biju

^ permalink raw reply

* Re: [PATCH v2 1/2] serial: sh-sci: Avoid divide-by-zero fault
From: Hugo Villeneuve @ 2026-04-08 18:15 UTC (permalink / raw)
  To: Biju Das
  Cc: biju.das.au, Greg Kroah-Hartman, Jiri Slaby, Geert Uytterhoeven,
	Thierry Bultel, wsa+renesas, Prabhakar Mahadev Lad,
	linux-kernel@vger.kernel.org, linux-serial@vger.kernel.org,
	linux-renesas-soc@vger.kernel.org
In-Reply-To: <TYCPR01MB11332859E901171C91C543061865B2@TYCPR01MB11332.jpnprd01.prod.outlook.com>

Hi Biju,

On Wed, 8 Apr 2026 17:25:19 +0000
Biju Das <biju.das.jz@bp.renesas.com> wrote:

> Hi Hugo,
> 
> > -----Original Message-----
> > From: Hugo Villeneuve <hugo@hugovil.com>
> > Sent: 08 April 2026 17:52
> > Subject: Re: [PATCH v2 1/2] serial: sh-sci: Avoid divide-by-zero fault
> > 
> > Hi Biju,
> > 
> > On Wed, 8 Apr 2026 16:35:44 +0000
> > Biju Das <biju.das.jz@bp.renesas.com> wrote:
> > 
> > > Hi Hugo,
> > >
> > > Thanks for the feedback.
> > >
> > > > -----Original Message-----
> > > > From: Hugo Villeneuve <hugo@hugovil.com>
> > > > Sent: 08 April 2026 17:31
> > > > Subject: Re: [PATCH v2 1/2] serial: sh-sci: Avoid divide-by-zero
> > > > fault
> > > >
> > > > Hi Biju,
> > > >
> > > > On Wed,  8 Apr 2026 15:20:58 +0100
> > > > Biju <biju.das.au@gmail.com> wrote:
> > > >
> > > > > From: Biju Das <biju.das.jz@bp.renesas.com>
> > > > >
> > > > > uart_update_timeout() computes a timeout value by dividing by the
> > > > > baud rate. If baud is zero — which can occur when the hardware
> > > > > returns an unsupported or invalid rate — this results in a divide-by-zero fault.
> > > >
> > > > baud is returned by uart_get_baud_rate(), so this is not returned by the hardware?
> > >
> > > You are tight, Will update commit description.
> > 
> > How can uart_get_baud_rate() return a zero value? If I am not mistaken even for the B0 case, it will
> > return 9600?
> 
> As per the comment and code, this API can return 0.
> 
> * If the new baud rate is invalid, try the @old termios setting. If it's still
> * invalid, we try 9600 baud. If that is also invalid 0 is returned.
> 
> In drives/tty currently only 1 driver is checking the return value
> and it calls panic
> 
> https://elixir.bootlin.com/linux/v7.0-rc7/source/drivers/tty/serial/apbuart.c#L214

Hmmm, more than 1:

icom.c:
    if (!baud)
         baud = 9600;    /* B0 transition handled in rs_set_termios */

8250/8250_fintek.c:
    if (!baud)
         goto exit;

> I believe we should call panic, if baud =0, instead of proceeding.
> Geert, any thoughts??

There once was a warning, removed by:

commit 23bf72faaebdf2cb199c0ef8cf96467b10904b35
Author: Max Filippov <jcmvbkbc@gmail.com>
Date:   Tue Oct 10 01:59:22 2023 -0700
    serial: core: tidy invalid baudrate handling in uart_get_baud_rate
    ...
    Clarify that 0 can be (and always could be) returned from the
    uart_get_baud_rate. Don't issue a warning in that case.
    ...

-- 
Hugo Villeneuve

^ permalink raw reply

* RE: [PATCH v2 1/2] serial: sh-sci: Avoid divide-by-zero fault
From: Biju Das @ 2026-04-08 17:25 UTC (permalink / raw)
  To: Hugo Villeneuve
  Cc: biju.das.au, Greg Kroah-Hartman, Jiri Slaby, Geert Uytterhoeven,
	Thierry Bultel, wsa+renesas, Prabhakar Mahadev Lad,
	linux-kernel@vger.kernel.org, linux-serial@vger.kernel.org,
	linux-renesas-soc@vger.kernel.org
In-Reply-To: <20260408125142.24cd94f094ba3ca512e7f346@hugovil.com>

Hi Hugo,

> -----Original Message-----
> From: Hugo Villeneuve <hugo@hugovil.com>
> Sent: 08 April 2026 17:52
> Subject: Re: [PATCH v2 1/2] serial: sh-sci: Avoid divide-by-zero fault
> 
> Hi Biju,
> 
> On Wed, 8 Apr 2026 16:35:44 +0000
> Biju Das <biju.das.jz@bp.renesas.com> wrote:
> 
> > Hi Hugo,
> >
> > Thanks for the feedback.
> >
> > > -----Original Message-----
> > > From: Hugo Villeneuve <hugo@hugovil.com>
> > > Sent: 08 April 2026 17:31
> > > Subject: Re: [PATCH v2 1/2] serial: sh-sci: Avoid divide-by-zero
> > > fault
> > >
> > > Hi Biju,
> > >
> > > On Wed,  8 Apr 2026 15:20:58 +0100
> > > Biju <biju.das.au@gmail.com> wrote:
> > >
> > > > From: Biju Das <biju.das.jz@bp.renesas.com>
> > > >
> > > > uart_update_timeout() computes a timeout value by dividing by the
> > > > baud rate. If baud is zero — which can occur when the hardware
> > > > returns an unsupported or invalid rate — this results in a divide-by-zero fault.
> > >
> > > baud is returned by uart_get_baud_rate(), so this is not returned by the hardware?
> >
> > You are tight, Will update commit description.
> 
> How can uart_get_baud_rate() return a zero value? If I am not mistaken even for the B0 case, it will
> return 9600?

As per the comment and code, this API can return 0.

* If the new baud rate is invalid, try the @old termios setting. If it's still
* invalid, we try 9600 baud. If that is also invalid 0 is returned.

In drives/tty currently only 1 driver is checking the return value
and it calls panic

https://elixir.bootlin.com/linux/v7.0-rc7/source/drivers/tty/serial/apbuart.c#L214


I believe we should call panic, if baud =0, instead of proceeding.

Geert, any thoughts??

Cheers,
Biju

^ permalink raw reply

* Re: [PATCH v2 1/2] serial: sh-sci: Avoid divide-by-zero fault
From: Hugo Villeneuve @ 2026-04-08 16:51 UTC (permalink / raw)
  To: Biju Das
  Cc: biju.das.au, Greg Kroah-Hartman, Jiri Slaby, Geert Uytterhoeven,
	Thierry Bultel, wsa+renesas, Prabhakar Mahadev Lad,
	linux-kernel@vger.kernel.org, linux-serial@vger.kernel.org,
	linux-renesas-soc@vger.kernel.org
In-Reply-To: <TYCPR01MB11332B594964DDF0763499184865B2@TYCPR01MB11332.jpnprd01.prod.outlook.com>

Hi Biju,

On Wed, 8 Apr 2026 16:35:44 +0000
Biju Das <biju.das.jz@bp.renesas.com> wrote:

> Hi Hugo,
> 
> Thanks for the feedback.
> 
> > -----Original Message-----
> > From: Hugo Villeneuve <hugo@hugovil.com>
> > Sent: 08 April 2026 17:31
> > Subject: Re: [PATCH v2 1/2] serial: sh-sci: Avoid divide-by-zero fault
> > 
> > Hi Biju,
> > 
> > On Wed,  8 Apr 2026 15:20:58 +0100
> > Biju <biju.das.au@gmail.com> wrote:
> > 
> > > From: Biju Das <biju.das.jz@bp.renesas.com>
> > >
> > > uart_update_timeout() computes a timeout value by dividing by the baud
> > > rate. If baud is zero — which can occur when the hardware returns an
> > > unsupported or invalid rate — this results in a divide-by-zero fault.
> > 
> > baud is returned by uart_get_baud_rate(), so this is not returned by the hardware?
> 
> You are tight, Will update commit description.

How can uart_get_baud_rate() return a zero value? If I am not mistaken
even for the B0 case, it will return 9600?

What are other consequences if a zero value is returned apart
from the division by zero fault? Is it ok (or logical) then to proceed
with the rest of the configuration?

> > 
> > 
> > >
> > > Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
> > 
> > Missing Fixes tag?
> 
> I will split patch into 2 adding Fixes tag.
> 
> > 
> > 
> > > ---
> > > v2:
> > >  * New patch
> > > ---
> > >  drivers/tty/serial/rsci.c   | 3 ++-
> > >  drivers/tty/serial/sh-sci.c | 3 ++-
> > >  2 files changed, 4 insertions(+), 2 deletions(-)
> > >
> > > diff --git a/drivers/tty/serial/rsci.c b/drivers/tty/serial/rsci.c
> > > index b00c9e385169..a0858bab0822 100644
> > > --- a/drivers/tty/serial/rsci.c
> > > +++ b/drivers/tty/serial/rsci.c
> > > @@ -286,7 +286,8 @@ static void rsci_set_termios(struct uart_port *port, struct ktermios *termios,
> > >  	sci_port_enable(s);
> > >  	uart_port_lock_irqsave(port, &flags);
> > >
> > > -	uart_update_timeout(port, termios->c_cflag, baud);
> > > +	if (baud)
> > > +		uart_update_timeout(port, termios->c_cflag, baud);
> > >
> > >  	rsci_serial_out(port, CCR0, ccr0_val);
> > >
> > > diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
> > > index 6c819b6b2425..429e89106ee3 100644
> > > --- a/drivers/tty/serial/sh-sci.c
> > > +++ b/drivers/tty/serial/sh-sci.c
> > > @@ -2805,7 +2805,8 @@ static void sci_set_termios(struct uart_port
> > > *port, struct ktermios *termios,
> > >
> > >  	sci_reset(port);
> > >
> > > -	uart_update_timeout(port, termios->c_cflag, baud);
> > > +	if (baud)
> > > +		uart_update_timeout(port, termios->c_cflag, baud);
> > 
> > After this patch, have you re-tested if having baud = 0 produces any other errors? A litle bit later in
> > the same function, there is this
> > code:
> 
> +	/* Avoid divide-by-zero fault in divider operations */
> +	if (!baud)
> +		baud = 100;
> +
> 
> Plan is to update the code with the above change, that will cover
> All divide-by-zero case in this function.

As stated above, does it makes sense to proceed if baud was zero?

> 
> Cheers,
> Biju


-- 
Hugo Villeneuve

^ permalink raw reply

* Re: [PATCH v2 1/2] serial: sh-sci: Avoid divide-by-zero fault
From: Hugo Villeneuve @ 2026-04-08 16:30 UTC (permalink / raw)
  To: Biju
  Cc: Greg Kroah-Hartman, Jiri Slaby, Biju Das, Geert Uytterhoeven,
	Thierry Bultel, Wolfram Sang, Lad Prabhakar, linux-kernel,
	linux-serial, linux-renesas-soc
In-Reply-To: <20260408142105.310210-2-biju.das.jz@bp.renesas.com>

Hi Biju,

On Wed,  8 Apr 2026 15:20:58 +0100
Biju <biju.das.au@gmail.com> wrote:

> From: Biju Das <biju.das.jz@bp.renesas.com>
> 
> uart_update_timeout() computes a timeout value by dividing by the baud
> rate. If baud is zero — which can occur when the hardware returns an
> unsupported or invalid rate — this results in a divide-by-zero fault.

baud is returned by uart_get_baud_rate(), so this is not returned
by the hardware?


> 
> Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>

Missing Fixes tag?


> ---
> v2:
>  * New patch
> ---
>  drivers/tty/serial/rsci.c   | 3 ++-
>  drivers/tty/serial/sh-sci.c | 3 ++-
>  2 files changed, 4 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/tty/serial/rsci.c b/drivers/tty/serial/rsci.c
> index b00c9e385169..a0858bab0822 100644
> --- a/drivers/tty/serial/rsci.c
> +++ b/drivers/tty/serial/rsci.c
> @@ -286,7 +286,8 @@ static void rsci_set_termios(struct uart_port *port, struct ktermios *termios,
>  	sci_port_enable(s);
>  	uart_port_lock_irqsave(port, &flags);
>  
> -	uart_update_timeout(port, termios->c_cflag, baud);
> +	if (baud)
> +		uart_update_timeout(port, termios->c_cflag, baud);
>  
>  	rsci_serial_out(port, CCR0, ccr0_val);
>  
> diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
> index 6c819b6b2425..429e89106ee3 100644
> --- a/drivers/tty/serial/sh-sci.c
> +++ b/drivers/tty/serial/sh-sci.c
> @@ -2805,7 +2805,8 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios,
>  
>  	sci_reset(port);
>  
> -	uart_update_timeout(port, termios->c_cflag, baud);
> +	if (baud)
> +		uart_update_timeout(port, termios->c_cflag, baud);

After this patch, have you re-tested if having baud = 0 produces any
other errors? A litle bit later in the same function, there is this
code:

    /* Calculate delay for 2 DMA buffers (4 FIFO). */
    s->rx_frame = (10000 * bits) / (baud / 100);

Does this trigger a division by zero fault?

There is also this:

	if ((srr + 1 == 5) &&
	    (s->type == PORT_SCIFA || s->type == PORT_SCIFB)) {
            ...
		udelay(DIV_ROUND_UP(10 * 1000000, baud));

Can this also trigger a division by zero fault?


>  
>  	/* byte size and parity */
>  	bits = tty_get_frame_size(termios->c_cflag);
> -- 
> 2.43.0
> 
> 


-- 
Hugo Villeneuve

^ permalink raw reply

* RE: [PATCH v2 1/2] serial: sh-sci: Avoid divide-by-zero fault
From: Biju Das @ 2026-04-08 16:35 UTC (permalink / raw)
  To: Hugo Villeneuve, biju.das.au
  Cc: Greg Kroah-Hartman, Jiri Slaby, Geert Uytterhoeven,
	Thierry Bultel, wsa+renesas, Prabhakar Mahadev Lad,
	linux-kernel@vger.kernel.org, linux-serial@vger.kernel.org,
	linux-renesas-soc@vger.kernel.org
In-Reply-To: <20260408123039.922a75327fd7672df3bd61da@hugovil.com>

Hi Hugo,

Thanks for the feedback.

> -----Original Message-----
> From: Hugo Villeneuve <hugo@hugovil.com>
> Sent: 08 April 2026 17:31
> Subject: Re: [PATCH v2 1/2] serial: sh-sci: Avoid divide-by-zero fault
> 
> Hi Biju,
> 
> On Wed,  8 Apr 2026 15:20:58 +0100
> Biju <biju.das.au@gmail.com> wrote:
> 
> > From: Biju Das <biju.das.jz@bp.renesas.com>
> >
> > uart_update_timeout() computes a timeout value by dividing by the baud
> > rate. If baud is zero — which can occur when the hardware returns an
> > unsupported or invalid rate — this results in a divide-by-zero fault.
> 
> baud is returned by uart_get_baud_rate(), so this is not returned by the hardware?

You are tight, Will update commit description.
> 
> 
> >
> > Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
> 
> Missing Fixes tag?

I will split patch into 2 adding Fixes tag.

> 
> 
> > ---
> > v2:
> >  * New patch
> > ---
> >  drivers/tty/serial/rsci.c   | 3 ++-
> >  drivers/tty/serial/sh-sci.c | 3 ++-
> >  2 files changed, 4 insertions(+), 2 deletions(-)
> >
> > diff --git a/drivers/tty/serial/rsci.c b/drivers/tty/serial/rsci.c
> > index b00c9e385169..a0858bab0822 100644
> > --- a/drivers/tty/serial/rsci.c
> > +++ b/drivers/tty/serial/rsci.c
> > @@ -286,7 +286,8 @@ static void rsci_set_termios(struct uart_port *port, struct ktermios *termios,
> >  	sci_port_enable(s);
> >  	uart_port_lock_irqsave(port, &flags);
> >
> > -	uart_update_timeout(port, termios->c_cflag, baud);
> > +	if (baud)
> > +		uart_update_timeout(port, termios->c_cflag, baud);
> >
> >  	rsci_serial_out(port, CCR0, ccr0_val);
> >
> > diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
> > index 6c819b6b2425..429e89106ee3 100644
> > --- a/drivers/tty/serial/sh-sci.c
> > +++ b/drivers/tty/serial/sh-sci.c
> > @@ -2805,7 +2805,8 @@ static void sci_set_termios(struct uart_port
> > *port, struct ktermios *termios,
> >
> >  	sci_reset(port);
> >
> > -	uart_update_timeout(port, termios->c_cflag, baud);
> > +	if (baud)
> > +		uart_update_timeout(port, termios->c_cflag, baud);
> 
> After this patch, have you re-tested if having baud = 0 produces any other errors? A litle bit later in
> the same function, there is this
> code:

+	/* Avoid divide-by-zero fault in divider operations */
+	if (!baud)
+		baud = 100;
+

Plan is to update the code with the above change, that will cover
All divide-by-zero case in this function.

Cheers,
Biju

^ permalink raw reply

* RE: [PATCH v2 1/2] serial: sh-sci: Avoid divide-by-zero fault
From: Biju Das @ 2026-04-08 16:05 UTC (permalink / raw)
  To: geert, biju.das.au
  Cc: Greg Kroah-Hartman, Jiri Slaby, Thierry Bultel, wsa+renesas,
	Prabhakar Mahadev Lad, linux-kernel@vger.kernel.org,
	linux-serial@vger.kernel.org, linux-renesas-soc@vger.kernel.org
In-Reply-To: <CAMuHMdW5_k+iBekmV47W+Qqt5qDLMrLMRWZnnH5wCNP8E30N3A@mail.gmail.com>

Hi Geert,

Thanks for the feedback.

> -----Original Message-----
> From: Geert Uytterhoeven <geert@linux-m68k.org>
> Sent: 08 April 2026 16:39
> Subject: Re: [PATCH v2 1/2] serial: sh-sci: Avoid divide-by-zero fault
> 
> Hi Biju,
> 
> On Wed, 8 Apr 2026 at 16:21, Biju <biju.das.au@gmail.com> wrote:
> > From: Biju Das <biju.das.jz@bp.renesas.com>
> >
> > uart_update_timeout() computes a timeout value by dividing by the baud
> > rate. If baud is zero — which can occur when the hardware returns an
> > unsupported or invalid rate — this results in a divide-by-zero fault.
> >
> > Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
> 
> Thanks for your patch!
> 
> > --- a/drivers/tty/serial/rsci.c
> > +++ b/drivers/tty/serial/rsci.c
> > @@ -286,7 +286,8 @@ static void rsci_set_termios(struct uart_port *port, struct ktermios *termios,
> >         sci_port_enable(s);
> >         uart_port_lock_irqsave(port, &flags);
> >
> > -       uart_update_timeout(port, termios->c_cflag, baud);
> > +       if (baud)
> > +               uart_update_timeout(port, termios->c_cflag, baud);
> >
> >         rsci_serial_out(port, CCR0, ccr0_val);
> >
> > diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
> > index 6c819b6b2425..429e89106ee3 100644
> > --- a/drivers/tty/serial/sh-sci.c
> > +++ b/drivers/tty/serial/sh-sci.c
> > @@ -2805,7 +2805,8 @@ static void sci_set_termios(struct uart_port
> > *port, struct ktermios *termios,
> >
> >         sci_reset(port);
> >
> > -       uart_update_timeout(port, termios->c_cflag, baud);
> > +       if (baud)
> > +               uart_update_timeout(port, termios->c_cflag, baud);
> 
> Nice catches!
> 
> >
> >         /* byte size and parity */
> >         bits = tty_get_frame_size(termios->c_cflag);
> 
> I think there's another one out of context, which can even trigger with baud == 75:
> 

Will add a check, if (baud > 99)

Cheers,
Biju

>         s->rx_frame = (10000 * bits) / (baud / 100);
> 
> Gr{oetje,eeting}s,
> 
>                         Geert
> 
> --
> Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
> 
> In personal conversations with technical people, I call myself a hacker. But when I'm talking to
> journalists I just say "programmer" or something like that.
>                                 -- Linus Torvalds

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox