[PATCH 2/2] serial: tegra: Fix overflow in tegra_check_rate_in_range()

From: Patrick Fischer via B4 Relay

Date: Sun Oct 25 2026 - 18:50:40 EST


From: Patrick Fischer <admin@xxxxxxxxxxxxxxxxxx>

tegra_check_rate_in_range() calculates the deviation of the configured
from the required clock rate as (configured_rate - required_rate) *
10000 in a long, which is only 32 bits wide on 32-bit ARM. This
overflows as soon as the two rates differ by more than about 214.7 kHz,
so the check lets through exactly the large deviations it is meant to
catch.

On the Tegra Note 7 (Tegra114) the Bluetooth UART ran at 45.33 MHz
instead of 48 MHz at 3 Mbaud (-5.6 %, see the previous patch). The
check calculated -0.18 % and let it pass, although the limit is 4 %.

Do the multiplication in 64 bits.

Tested on the Tegra Note 7 with a tolerance of -500 for 1 to 4 Mbaud,
which gives 45.33 MHz at 3 Mbaud: the driver now logs
"configured baud rate is out of range by -555" and does not apply the
rate. With the tolerance of 136 (48.00 MHz) it logs nothing.

64-bit platforms are not affected.

Fixes: d781ec21bae6 ("serial: tegra: report clk rate errors")
Cc: stable@xxxxxxxxxxxxxxx
Signed-off-by: Patrick Fischer <admin@xxxxxxxxxxxxxxxxxx>
---
drivers/tty/serial/serial-tegra.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/tty/serial/serial-tegra.c b/drivers/tty/serial/serial-tegra.c
index cc09fbc3aad8..cb5ef8aac198 100644
--- a/drivers/tty/serial/serial-tegra.c
+++ b/drivers/tty/serial/serial-tegra.c
@@ -380,8 +380,8 @@ static int tegra_check_rate_in_range(struct tegra_uart_port *tup)
{
long diff;

- diff = ((long)(tup->configured_rate - tup->required_rate) * 10000)
- / tup->required_rate;
+ diff = div_s64((s64)(tup->configured_rate - tup->required_rate) * 10000,
+ tup->required_rate);
if (diff < (tup->cdata->error_tolerance_low_range * 100) ||
diff > (tup->cdata->error_tolerance_high_range * 100)) {
dev_err(tup->uport.dev,

--
2.56.0