From: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com> mainline inclusion from mainline-v7.0-rc5 commit 8324a54f604da18f21070702a8ad82ab2062787b category: feature bugzilla: https://atomgit.com/src-openeuler/kernel/issues/18269 CVE: CVE-2026-74653 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?i... -------------------------------- 8250_port exports serial8250_handle_irq() to HW specific 8250 drivers. It takes port's lock within but a HW specific 8250 driver may want to take port's lock itself, do something, and then call the generic handler in 8250_port but to do that, the caller has to release port's lock for no good reason. Introduce serial8250_handle_irq_locked() which a HW specific driver can call while already holding port's lock. As this is new export, put it straight into a namespace (where all 8250 exports should eventually be moved). Tested-by: Bandal, Shankar <shankar.bandal@intel.com> Tested-by: Murthy, Shanth <shanth.murthy@intel.com> Cc: stable <stable@kernel.org> Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com> Link: https://patch.msgid.link/20260203171049.4353-4-ilpo.jarvinen@linux.intel.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Conflicts: drivers/tty/serial/8250/8250_port.c include/linux/serial_8250.h [There is no guard(xxx) in 6.6. Restore it to the method of locking and unlocking. Others are context conflicts.] Signed-off-by: Cai Xinchen <caixinchen1@huawei.com> --- drivers/tty/serial/8250/8250_port.c | 27 +++++++++++++++++++-------- include/linux/serial_8250.h | 1 + 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c index c246503c9f80..04b1e3157dca 100644 --- a/drivers/tty/serial/8250/8250_port.c +++ b/drivers/tty/serial/8250/8250_port.c @@ -18,6 +18,7 @@ #include <linux/irq.h> #include <linux/console.h> #include <linux/gpio/consumer.h> +#include <linux/lockdep.h> #include <linux/sysrq.h> #include <linux/delay.h> #include <linux/platform_device.h> @@ -1899,20 +1900,16 @@ static bool handle_rx_dma(struct uart_8250_port *up, unsigned int iir) } /* - * This handles the interrupt from one port. + * Context: port's lock must be held by the caller. */ -int serial8250_handle_irq(struct uart_port *port, unsigned int iir) +void serial8250_handle_irq_locked(struct uart_port *port, unsigned int iir) { struct uart_8250_port *up = up_to_u8250p(port); struct tty_port *tport = &port->state->port; bool skip_rx = false; - unsigned long flags; u16 status; - if (iir & UART_IIR_NO_INT) - return 0; - - spin_lock_irqsave(&port->lock, flags); + lockdep_assert_held_once(&port->lock); status = serial_lsr_in(up); @@ -1945,8 +1942,22 @@ int serial8250_handle_irq(struct uart_port *port, unsigned int iir) else if (!up->dma->tx_running) __stop_tx(up); } +} +EXPORT_SYMBOL_NS_GPL(serial8250_handle_irq_locked, SERIAL_8250); + +/* + * This handles the interrupt from one port. + */ +int serial8250_handle_irq(struct uart_port *port, unsigned int iir) +{ + unsigned long flags; + + if (iir & UART_IIR_NO_INT) + return 0; - uart_unlock_and_check_sysrq_irqrestore(port, flags); + uart_port_lock_irqsave(port, &flags); + serial8250_handle_irq_locked(port, iir); + uart_port_unlock_irqrestore(port, flags); return 1; } diff --git a/include/linux/serial_8250.h b/include/linux/serial_8250.h index be65de65fe61..7e66e6237935 100644 --- a/include/linux/serial_8250.h +++ b/include/linux/serial_8250.h @@ -195,6 +195,7 @@ void serial8250_do_set_mctrl(struct uart_port *port, unsigned int mctrl); void serial8250_do_set_divisor(struct uart_port *port, unsigned int baud, unsigned int quot, unsigned int quot_frac); int fsl8250_handle_irq(struct uart_port *port); +void serial8250_handle_irq_locked(struct uart_port *port, unsigned int iir); int serial8250_handle_irq(struct uart_port *port, unsigned int iir); u16 serial8250_rx_chars(struct uart_8250_port *up, u16 lsr); void serial8250_read_char(struct uart_8250_port *up, u16 lsr); -- 2.18.0.huawei.25