From a15eb4e43d89ed10ff371a0a898a505d68776e12 Mon Sep 17 00:00:00 2001 From: Zhang Enpei Date: Thu, 26 Jun 2025 18:11:57 +0800 Subject: [PATCH 1/2] serial: 8250_omap: Implementation of Errata i2310 commit e67d7f38008e56fb691b6a72cadf16c107c2f48b upstream. commit 9d141c1e615795eeb93cd35501ad144ee997a826 upstream. As per Errata i2310[0], Erroneous timeout can be triggered, if this Erroneous interrupt is not cleared then it may leads to storm of interrupts, therefore apply Errata i2310 solution. [0] https://www.ti.com/lit/pdf/sprz536 page 23 Fixes: b67e830d38fa ("serial: 8250: 8250_omap: Fix possible interrupt storm on K3 SoCs") Cc: stable@vger.kernel.org Signed-off-by: Udit Kumar Link: https://lore.kernel.org/r/20240619105903.165434-1-u-kumar1@ti.com Signed-off-by: Greg Kroah-Hartman Fixes: CVE-2024-42095 Signed-off-by: Enpei Zhang Signed-off-by: Wenya Zhang Reviewed-by: Xuexin Jiang --- drivers/tty/serial/8250/8250_omap.c | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/drivers/tty/serial/8250/8250_omap.c b/drivers/tty/serial/8250/8250_omap.c index db5519ce0192..2993907632b5 100644 --- a/drivers/tty/serial/8250/8250_omap.c +++ b/drivers/tty/serial/8250/8250_omap.c @@ -165,6 +165,10 @@ static u32 uart_read(struct omap8250_priv *priv, u32 reg) return readl(priv->membase + (reg << OMAP_UART_REGSHIFT)); } +/* Timeout low and High */ +#define UART_OMAP_TO_L 0x26 +#define UART_OMAP_TO_H 0x27 + /* * Called on runtime PM resume path from omap8250_restore_regs(), and * omap8250_set_mctrl(). @@ -646,13 +650,24 @@ static irqreturn_t omap8250_irq(int irq, void *dev_id) /* * On K3 SoCs, it is observed that RX TIMEOUT is signalled after - * FIFO has been drained, in which case a dummy read of RX FIFO - * is required to clear RX TIMEOUT condition. + * FIFO has been drained or erroneously. + * So apply solution of Errata i2310 as mentioned in + * https://www.ti.com/lit/pdf/sprz536 */ if (priv->habit & UART_RX_TIMEOUT_QUIRK && - (iir & UART_IIR_RX_TIMEOUT) == UART_IIR_RX_TIMEOUT && - serial_port_in(port, UART_OMAP_RX_LVL) == 0) { - serial_port_in(port, UART_RX); + (iir & UART_IIR_RX_TIMEOUT) == UART_IIR_RX_TIMEOUT) { + unsigned char efr2, timeout_h, timeout_l; + + efr2 = serial_in(up, UART_OMAP_EFR2); + timeout_h = serial_in(up, UART_OMAP_TO_H); + timeout_l = serial_in(up, UART_OMAP_TO_L); + serial_out(up, UART_OMAP_TO_H, 0xFF); + serial_out(up, UART_OMAP_TO_L, 0xFF); + serial_out(up, UART_OMAP_EFR2, UART_OMAP_EFR2_TIMEOUT_BEHAVE); + serial_in(up, UART_IIR); + serial_out(up, UART_OMAP_EFR2, efr2); + serial_out(up, UART_OMAP_TO_H, timeout_h); + serial_out(up, UART_OMAP_TO_L, timeout_l); } /* Stop processing interrupts on input overrun */ -- Gitee From b74c57f960bd1b61d0d0ba634865f7861832f131 Mon Sep 17 00:00:00 2001 From: Zhang Enpei Date: Thu, 26 Jun 2025 18:11:58 +0800 Subject: [PATCH 2/2] serial: 8250_omap: Fix Errata i2310 with RX FIFO level check commit 18630d83b7708032f00b84b1733da05f0b53a1e9 upstream. commit c128a1b0523b685c8856ddc0ac0e1caef1fdeee5 upstream. Errata i2310[0] says, Erroneous timeout can be triggered, if this Erroneous interrupt is not cleared then it may leads to storm of interrupts. Commit 9d141c1e6157 ("serial: 8250_omap: Implementation of Errata i2310") which added the workaround but missed ensuring RX FIFO is really empty before applying the errata workaround as recommended in the errata text. Fix this by adding back check for UART_OMAP_RX_LVL to be 0 for workaround to take effect. [0] https://www.ti.com/lit/pdf/sprz536 page 23 Fixes: 9d141c1e6157 ("serial: 8250_omap: Implementation of Errata i2310") Cc: stable@vger.kernel.org Reported-by: Vignesh Raghavendra Closes: https://lore.kernel.org/all/e96d0c55-0b12-4cbf-9d23-48963543de49@ti.com/ Signed-off-by: Udit Kumar Link: https://lore.kernel.org/r/20240625160725.2102194-1-u-kumar1@ti.com Signed-off-by: Greg Kroah-Hartman Fixes: CVE-2024-42095 Signed-off-by: Enpei Zhang Signed-off-by: Wenya Zhang Reviewed-by: Xuexin Jiang --- drivers/tty/serial/8250/8250_omap.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/tty/serial/8250/8250_omap.c b/drivers/tty/serial/8250/8250_omap.c index 2993907632b5..78fc1f17d5e2 100644 --- a/drivers/tty/serial/8250/8250_omap.c +++ b/drivers/tty/serial/8250/8250_omap.c @@ -655,7 +655,8 @@ static irqreturn_t omap8250_irq(int irq, void *dev_id) * https://www.ti.com/lit/pdf/sprz536 */ if (priv->habit & UART_RX_TIMEOUT_QUIRK && - (iir & UART_IIR_RX_TIMEOUT) == UART_IIR_RX_TIMEOUT) { + (iir & UART_IIR_RX_TIMEOUT) == UART_IIR_RX_TIMEOUT && + serial_port_in(port, UART_OMAP_RX_LVL) == 0) { unsigned char efr2, timeout_h, timeout_l; efr2 = serial_in(up, UART_OMAP_EFR2); -- Gitee