]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
serial: 8250: always disable IRQ during THRE test
authorPeng Zhang <zhangpeng.00@bytedance.com>
Tue, 24 Feb 2026 12:16:39 +0000 (13:16 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 12 Mar 2026 14:30:30 +0000 (15:30 +0100)
commit 039d4926379b ("serial: 8250: Toggle IER bits on only after irq
has been set up") moved IRQ setup before the THRE test, in combination
with commit 205d300aea75 ("serial: 8250: change lock order in
serial8250_do_startup()") the interrupt handler can run during the
test and race with its IIR reads. This can produce wrong THRE test
results and cause spurious registration of the
serial8250_backup_timeout timer. Unconditionally disable the IRQ for
the short duration of the test and re-enable it afterwards to avoid
the race.

Fixes: 039d4926379b ("serial: 8250: Toggle IER bits on only after irq has been set up")
Depends-on: 205d300aea75 ("serial: 8250: change lock order in serial8250_do_startup()")
Cc: stable <stable@kernel.org>
Signed-off-by: Peng Zhang <zhangpeng.00@bytedance.com>
Reviewed-by: Muchun Song <songmuchun@bytedance.com>
Signed-off-by: Alban Bedel <alban.bedel@lht.dlh.de>
Tested-by: Maximilian Lueer <maximilian.lueer@lht.dlh.de>
Link: https://patch.msgid.link/20260224121639.579404-1-alban.bedel@lht.dlh.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/tty/serial/8250/8250_port.c

index cc94af2d578a64de54ec64a2abbf5cabed3f0b20..a743964c9d22740d762b7c466e83e6c9a4fa89a4 100644 (file)
@@ -2147,8 +2147,7 @@ static void serial8250_THRE_test(struct uart_port *port)
        if (up->port.flags & UPF_NO_THRE_TEST)
                return;
 
-       if (port->irqflags & IRQF_SHARED)
-               disable_irq_nosync(port->irq);
+       disable_irq(port->irq);
 
        /*
         * Test for UARTs that do not reassert THRE when the transmitter is idle and the interrupt
@@ -2170,8 +2169,7 @@ static void serial8250_THRE_test(struct uart_port *port)
                serial_port_out(port, UART_IER, 0);
        }
 
-       if (port->irqflags & IRQF_SHARED)
-               enable_irq(port->irq);
+       enable_irq(port->irq);
 
        /*
         * If the interrupt is not reasserted, or we otherwise don't trust the iir, setup a timer to