Received: by 2002:a05:6a10:c604:0:0:0:0 with SMTP id y4csp3778018pxt; Tue, 10 Aug 2021 11:06:06 -0700 (PDT) X-Google-Smtp-Source: ABdhPJyuyr0qQs/nJBeCXcnEsz2ZDsf075VaHSbjxXu4H2qTJpNRDBQOI2udUPYBmkqjmIBwdCO5 X-Received: by 2002:a92:db4b:: with SMTP id w11mr485184ilq.297.1628618765926; Tue, 10 Aug 2021 11:06:05 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1628618765; cv=none; d=google.com; s=arc-20160816; b=nQU7e5CLRwozQuUGAwcAWVUQMjuUuDNAnL6BGd7mCn//x88xhYxF+lqM+yQgyl6v1I KUsombJf/hXVOxQw809H0Ix/V0pd1WQW92mw4TCeJXjiRd4bIAxbhMlGE5PU4Cg99L3E Ii2u7HqFPDv6HJ9we7xdzIZxmM6OgYkaxgHdH555s1DP7CYbwSTNpRUpqc+crpzQzW2H gTYqpIP7y7lKayos6nbWF/q1asyKQ2MgCZI7ednenTA2vFP8UbG3Hq3XKXisF6fEjCUE SlXlqqNbKB5rfQufy4CGww5j6wMSebkPLJ7MVp5LGD6hrJsco1zQUL8/ikxKtJkipgU6 fEpQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=+6r92pgDWNp3rcHe9DAcW/5pU8xW9Mlxp6BPMaT956s=; b=lcPm/ebLM3Cc84ZgB9loCc/3w3MXzpVJW82sgokFLsJauyenjMqTHLPYUPzW8yoBGt W19em9WwblXVi9xFDtI/R9rBM1lcFgX1mAMweOOHUuNm42UgHklRZr3b+i2pmgKwjVbP yNJQgboUT9WAk0IdtVU79/WbnSE6vidr3XabekVuWqggsjZyQ6pjU3IRGZ8Z0+Wneaot zyhLsmLVJUdz8BabhZOeOpxsHkM1yKdpogwy+YSfQYVdS877mVEqvxjipDZI8PlZ5cOf fogVp6DEG55Rdw4r/lOMRz9J9M+9g6wPBVWrw7cq6Qyf37wRfg5UfyZ8rokqMSiFS7uz 5fwg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=XDBVUaZp; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id g17si22751616jao.103.2021.08.10.11.05.54; Tue, 10 Aug 2021 11:06:05 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=XDBVUaZp; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238690AbhHJSEZ (ORCPT + 99 others); Tue, 10 Aug 2021 14:04:25 -0400 Received: from mail.kernel.org ([198.145.29.99]:34378 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238669AbhHJR7v (ORCPT ); Tue, 10 Aug 2021 13:59:51 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id DD4316112D; Tue, 10 Aug 2021 17:46:35 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1628617596; bh=CStUyNp+qm5s8GGhGw22zcDDyNT/riOMp3pldqrNyxI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=XDBVUaZpYiBDlklMDJucjPyS34e+kIvBKy6Sj+PCqsuHLGPFD0PLg2HksVi69jP4g Kl9INqefRtcvUQZDnJ/GIN9z361oAJakZtMXbbaQaLFEnrvBNgwBXaTIrCQfJbc3Za Amh9B0esEfSGJbG6Wa/drvwa5LCwGAqB7hpA+t/Y= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Joel Stanley , Andrew Jeffery , kernel test robot , Johan Hovold Subject: [PATCH 5.13 127/175] serial: 8250: fix handle_irq locking Date: Tue, 10 Aug 2021 19:30:35 +0200 Message-Id: <20210810173005.136988577@linuxfoundation.org> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20210810173000.928681411@linuxfoundation.org> References: <20210810173000.928681411@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Johan Hovold commit 853a9ae29e978d37f5dfa72622a68c9ae3d7fa89 upstream. The 8250 handle_irq callback is not just called from the interrupt handler but also from a timer callback when polling (e.g. for ports without an interrupt line). Consequently the callback must explicitly disable interrupts to avoid a potential deadlock with another interrupt in polled mode. Add back an irqrestore-version of the sysrq port-unlock helper and use it in the 8250 callbacks that need it. Fixes: 75f4e830fa9c ("serial: do not restore interrupt state in sysrq helper") Cc: stable@vger.kernel.org # 5.13 Cc: Joel Stanley Cc: Andrew Jeffery Reported-by: kernel test robot Signed-off-by: Johan Hovold Link: https://lore.kernel.org/r/20210714080427.28164-1-johan@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_aspeed_vuart.c | 5 +++-- drivers/tty/serial/8250/8250_fsl.c | 5 +++-- drivers/tty/serial/8250/8250_port.c | 5 +++-- include/linux/serial_core.h | 24 ++++++++++++++++++++++++ 4 files changed, 33 insertions(+), 6 deletions(-) --- a/drivers/tty/serial/8250/8250_aspeed_vuart.c +++ b/drivers/tty/serial/8250/8250_aspeed_vuart.c @@ -320,6 +320,7 @@ static int aspeed_vuart_handle_irq(struc { struct uart_8250_port *up = up_to_u8250p(port); unsigned int iir, lsr; + unsigned long flags; int space, count; iir = serial_port_in(port, UART_IIR); @@ -327,7 +328,7 @@ static int aspeed_vuart_handle_irq(struc if (iir & UART_IIR_NO_INT) return 0; - spin_lock(&port->lock); + spin_lock_irqsave(&port->lock, flags); lsr = serial_port_in(port, UART_LSR); @@ -363,7 +364,7 @@ static int aspeed_vuart_handle_irq(struc if (lsr & UART_LSR_THRE) serial8250_tx_chars(up); - uart_unlock_and_check_sysrq(port); + uart_unlock_and_check_sysrq_irqrestore(port, flags); return 1; } --- a/drivers/tty/serial/8250/8250_fsl.c +++ b/drivers/tty/serial/8250/8250_fsl.c @@ -30,10 +30,11 @@ struct fsl8250_data { int fsl8250_handle_irq(struct uart_port *port) { unsigned char lsr, orig_lsr; + unsigned long flags; unsigned int iir; struct uart_8250_port *up = up_to_u8250p(port); - spin_lock(&up->port.lock); + spin_lock_irqsave(&up->port.lock, flags); iir = port->serial_in(port, UART_IIR); if (iir & UART_IIR_NO_INT) { @@ -82,7 +83,7 @@ int fsl8250_handle_irq(struct uart_port up->lsr_saved_flags = orig_lsr; - uart_unlock_and_check_sysrq(&up->port); + uart_unlock_and_check_sysrq_irqrestore(&up->port, flags); return 1; } --- a/drivers/tty/serial/8250/8250_port.c +++ b/drivers/tty/serial/8250/8250_port.c @@ -1899,11 +1899,12 @@ int serial8250_handle_irq(struct uart_po unsigned char status; struct uart_8250_port *up = up_to_u8250p(port); bool skip_rx = false; + unsigned long flags; if (iir & UART_IIR_NO_INT) return 0; - spin_lock(&port->lock); + spin_lock_irqsave(&port->lock, flags); status = serial_port_in(port, UART_LSR); @@ -1929,7 +1930,7 @@ int serial8250_handle_irq(struct uart_po (up->ier & UART_IER_THRI)) serial8250_tx_chars(up); - uart_unlock_and_check_sysrq(port); + uart_unlock_and_check_sysrq_irqrestore(port, flags); return 1; } --- a/include/linux/serial_core.h +++ b/include/linux/serial_core.h @@ -517,6 +517,25 @@ static inline void uart_unlock_and_check if (sysrq_ch) handle_sysrq(sysrq_ch); } + +static inline void uart_unlock_and_check_sysrq_irqrestore(struct uart_port *port, + unsigned long flags) +{ + int sysrq_ch; + + if (!port->has_sysrq) { + spin_unlock_irqrestore(&port->lock, flags); + return; + } + + sysrq_ch = port->sysrq_ch; + port->sysrq_ch = 0; + + spin_unlock_irqrestore(&port->lock, flags); + + if (sysrq_ch) + handle_sysrq(sysrq_ch); +} #else /* CONFIG_MAGIC_SYSRQ_SERIAL */ static inline int uart_handle_sysrq_char(struct uart_port *port, unsigned int ch) { @@ -530,6 +549,11 @@ static inline void uart_unlock_and_check { spin_unlock(&port->lock); } +static inline void uart_unlock_and_check_sysrq_irqrestore(struct uart_port *port, + unsigned long flags) +{ + spin_unlock_irqrestore(&port->lock, flags); +} #endif /* CONFIG_MAGIC_SYSRQ_SERIAL */ /*