From: sashiko-bot@kernel.org
To: "Christian Marangi" <ansuelsmth@gmail.com>
Cc: robh@kernel.org, conor+dt@kernel.org, devicetree@vger.kernel.org
Subject: Re: [PATCH 4/4] serial: 8250: Add Airoha SoC UART and HSUART support
Date: Thu, 09 Jul 2026 21:19:05 +0000 [thread overview]
Message-ID: <20260709211905.E2A811F000E9@smtp.kernel.org> (raw)
In-Reply-To: <20260709205656.319531-5-ansuelsmth@gmail.com>
Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:
- [High] Hardware registers are accessed without holding the port lock, causing a critical race condition with interrupt handlers.
- [High] Integer overflow and out-of-bounds truncation in custom baud rate calculation.
- [High] Missing NULL pointer check for device_get_match_data() result.
- [Low] Unused static const arrays (dead code).
--
--- Patch [4]: [PATCH 4/4] serial: 8250: Add Airoha SoC UART and HSUART support ---
commit 787398b7c15179f8d67914a09402fbd411a20806
Author: Christian Marangi <ansuelsmth@gmail.com>
serial: 8250: Add Airoha SoC UART and HSUART support
This commit adds support for Airoha AN7523 UART and AN7581 HSUART.
These implement a standard 16550 UART with custom logic for baud rate handling.
> diff --git a/drivers/tty/serial/8250/8250_airoha.c b/drivers/tty/serial/8250/8250_airoha.c
> new file mode 100644
> index 0000000000000..9ec98cd8de438
> --- /dev/null
> +++ b/drivers/tty/serial/8250/8250_airoha.c
[ ... ]
> +static const struct airoha_8250_clk_div_info airoha_clk_div_info[] = {
> + { .div = 10, .mask = BIT(2) },
> + { .div = 4, .mask = BIT(1) },
> + { .div = 2, .mask = BIT(0) },
> +};
> +
> +static const int clock_div_tab[] = { 10, 4, 2};
> +static const int clock_div_reg[] = { 4, 2, 1};
[Severity: Low]
Are these arrays used anywhere in the driver? It looks like the implementation
relies on airoha_clk_div_info instead, making these dead code.
> +
> +/*
> + * Airoha UART baud rate calculation logic
[ ... ]
> +static void airoha_set_termios(struct uart_port *port, struct ktermios *termios,
> + const struct ktermios *old)
> +{
> + const struct airoha_8250_clk_div_info *clk_div_info;
> + struct uart_8250_port *up = up_to_u8250p(port);
> + unsigned int xyd_x, nom, denom;
> + unsigned int baud;
> + int i;
> +
> + serial8250_do_set_termios(port, termios, old);
> +
> + baud = serial8250_get_baud_rate(port, termios, old);
> +
> + /* Set DLAB to access the baud rate divider registers (BRDH, BRDL) */
> + serial_port_out(port, UART_LCR, up->lcr | UART_LCR_DLAB);
[Severity: High]
Does this sequence leave the port registers unprotected?
Looking at serial8250_do_set_termios(), it acquires and then releases the
port lock. Modifying UART_LCR here to set the DLAB bit without holding the
port lock leaves a race window.
If a UART RX or TX interrupt fires concurrently, the interrupt handler
(serial8250_handle_irq) will acquire the port lock and attempt to read UART_RX
or write UART_TX at offset 0. Since DLAB=1, offset 0 becomes the UART_DLL
register, which could lead to silently overwriting the baud rate divisor or
reading corrupted data.
Additionally, does this access registers without an active runtime PM reference?
> +
> + /* Set baud rate calculation defaults (BRDIV ([BRDH,BRDL]) to 1) */
> + serial_port_out(port, UART_AIROHA_BRDL, UART_BRDL_20M);
> + serial_port_out(port, UART_AIROHA_BRDH, UART_BRDH_20M);
> +
> + /*
> + * Calculate XYD_x and XINCLKDR register by searching
> + * through a table of crystal_clock divisors.
> + */
> + for (i = 0 ; i < ARRAY_SIZE(airoha_clk_div_info) ; i++) {
> + clk_div_info = &airoha_clk_div_info[i];
> +
> + denom = (XINDIV_CLOCK / 40) / clk_div_info->div;
> + nom = baud * (XYD_Y / 40);
> + xyd_x = ((nom / denom) << 4);
[Severity: High]
Could the calculation for nom silently overflow on high baud rates?
If baud is very high (e.g., 3,000,000 or 4,000,000 for HSUARTs), multiplying
it by 1625 (XYD_Y / 40) exceeds the maximum capacity of a 32-bit unsigned int,
resulting in an incorrectly calculated baud rate.
> + /* For the HSUART xyd_x needs to be scaled by a factor of 2 */
> + if (port->type == UART_PORT_AIROHA_HS)
> + xyd_x = xyd_x >> 1;
> + if (xyd_x < XYD_Y)
> + break;
> + }
> +
> + serial_port_out(port, UART_AIROHA_XINCLKDR, clk_div_info->mask);
> + serial_port_out(port, UART_AIROHA_XYD, (xyd_x << 16) | XYD_Y);
[Severity: High]
If the loop terminates without finding a valid divider and xyd_x remains
large, will the left shift of xyd_x by 16 silently overflow a 32-bit integer
here before the write to UART_AIROHA_XYD?
> +
> + /* unset DLAB */
> + serial_port_out(port, UART_LCR, up->lcr);
> +}
> +
> +static int airoha_8250_probe(struct platform_device *pdev)
> +{
> + const struct airoha_8250_data *data;
> + struct uart_8250_port uart = { };
> + struct device *dev = &pdev->dev;
> + struct airoha_8250_priv *priv;
> + struct resource *res;
> + int ret;
> +
> + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> + if (!res)
> + return dev_err_probe(dev, -EINVAL, "invalid address\n");
> +
> + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
> + if (!priv)
> + return -ENOMEM;
> +
> + data = device_get_match_data(dev);
> +
> + uart.port.dev = dev;
> + uart.port.type = data->type;
[Severity: High]
Is it possible for device_get_match_data() to return NULL here?
If a platform device is manually bound via sysfs without a Device Tree node,
it would lack OF match data, causing device_get_match_data() to return NULL.
This would lead to a NULL pointer dereference when accessing data->type.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260709205656.319531-1-ansuelsmth@gmail.com?part=4
next prev parent reply other threads:[~2026-07-09 21:19 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-09 20:56 [PATCH 0/4] serial: 8250: Add AN7581 UART support Christian Marangi
2026-07-09 20:56 ` [PATCH 1/4] dt-bindings: serial: 8250: Add Airoha compatibles Christian Marangi
2026-07-10 16:43 ` Conor Dooley
2026-07-09 20:56 ` [PATCH 2/4] serial: 8250: export serial8250_get_baud_rate() Christian Marangi
2026-07-09 21:35 ` Andy Shevchenko
2026-07-09 21:39 ` Christian Marangi
2026-07-10 8:20 ` Andy Shevchenko
2026-07-10 8:49 ` Christian Marangi
2026-07-10 9:14 ` Andy Shevchenko
2026-07-10 8:19 ` Ilpo Järvinen
2026-07-09 20:56 ` [PATCH 3/4] serial: 8250: map UAPI port type to internal enum Christian Marangi
2026-07-09 21:18 ` sashiko-bot
2026-07-09 21:37 ` Andy Shevchenko
2026-07-09 21:46 ` Christian Marangi
2026-07-10 10:09 ` Andy Shevchenko
2026-07-09 20:56 ` [PATCH 4/4] serial: 8250: Add Airoha SoC UART and HSUART support Christian Marangi
2026-07-09 21:19 ` sashiko-bot [this message]
2026-07-10 7:13 ` Jiri Slaby
2026-07-14 14:55 ` Benjamin Larsson
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260709211905.E2A811F000E9@smtp.kernel.org \
--to=sashiko-bot@kernel.org \
--cc=ansuelsmth@gmail.com \
--cc=conor+dt@kernel.org \
--cc=devicetree@vger.kernel.org \
--cc=robh@kernel.org \
--cc=sashiko-reviews@lists.linux.dev \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.