]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
MIPS: Loongson64: env: Check UARTs passed by LEFI cautiously
authorRong Zhang <rongrong@oss.cipunited.com>
Sun, 15 Mar 2026 17:28:22 +0000 (01:28 +0800)
committerThomas Bogendoerfer <tsbogend@alpha.franken.de>
Wed, 1 Apr 2026 19:49:44 +0000 (21:49 +0200)
Some firmware does not set nr_uarts properly and passes empty items.
Iterate at most min(system->nr_uarts, MAX_UARTS) items to prevent
out-of-bounds access, and ignore UARTs with addr 0 silently.

Meanwhile, our DT only works with UPIO_MEM but theoretically firmware
may pass other IO types, so explicitly check against that.

Tested on Loongson-LS3A4000-7A1000-NUC-SE.

Fixes: 3989ed418483 ("MIPS: Loongson64: env: Fixup serial clock-frequency when using LEFI")
Cc: stable@vger.kernel.org
Reviewed-by: Yao Zi <me@ziyao.cc>
Signed-off-by: Rong Zhang <rongrong@oss.cipunited.com>
Reviewed-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
arch/mips/loongson64/env.c

index 11ddf02d6a15866414c55cb33b2e5be37ee1c94a..7abcca7ab4ed4437cccf96c6d441074e1cae0f88 100644 (file)
@@ -17,7 +17,9 @@
 #include <linux/dma-map-ops.h>
 #include <linux/export.h>
 #include <linux/libfdt.h>
+#include <linux/minmax.h>
 #include <linux/pci_ids.h>
+#include <linux/serial_core.h>
 #include <linux/string_choices.h>
 #include <asm/bootinfo.h>
 #include <loongson.h>
@@ -106,9 +108,23 @@ static void __init lefi_fixup_fdt(struct system_loongson *system)
 
        is_loongson64g = (read_c0_prid() & PRID_IMP_MASK) == PRID_IMP_LOONGSON_64G;
 
-       for (i = 0; i < system->nr_uarts; i++) {
+       for (i = 0; i < min(system->nr_uarts, MAX_UARTS); i++) {
                uartdev = &system->uarts[i];
 
+               /*
+                * Some firmware does not set nr_uarts properly and passes empty
+                * items. Ignore them silently.
+                */
+               if (uartdev->uart_base == 0)
+                       continue;
+
+               /* Our DT only works with UPIO_MEM. */
+               if (uartdev->iotype != UPIO_MEM) {
+                       pr_warn("Ignore UART 0x%llx with iotype %u passed by firmware\n",
+                               uartdev->uart_base, uartdev->iotype);
+                       continue;
+               }
+
                ret = lefi_fixup_fdt_serial(fdt_buf, uartdev->uart_base,
                                            uartdev->uartclk);
                /*