From nobody Fri Sep 20 19:22:29 2024 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3A8CBC7EE31 for ; Thu, 25 May 2023 09:35:08 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240766AbjEYJe5 (ORCPT ); Thu, 25 May 2023 05:34:57 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60666 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240503AbjEYJek (ORCPT ); Thu, 25 May 2023 05:34:40 -0400 Received: from galois.linutronix.de (Galois.linutronix.de [IPv6:2a0a:51c0:0:12e:550::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id AF70919C; Thu, 25 May 2023 02:34:30 -0700 (PDT) From: John Ogness DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1685007268; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=4NGWDH2m9xz3zGie63zl1kcLGjTJ0fX1VflVrGzz2ZQ=; b=Kja8EByGHMg80rkSKT9+A6oAP7Ytw5mSKQu0+uGfVfwe5tVdGCEi5josuEM1SwN606+mom tJOhrFWIt2zJG+DlK5DjPmWfVz6loRqSChpbkp8HXvZab2zEzJXhmgL0k+AWUZunXGh4bK ZB+SftTZW59pKhVFlzUNZNYOpZMdX8zxvpepVbJv55/P+jYmWnd8ln/AejbG3dDoZJevAa J7Qto8rkUPaEA13Qh78iauHtxD9/MNjhQsamwocWO64h7fGgSzp5rGrAHv5Xn4mRXNmpig fi0pD7NC4PYFiEdTiZBJclw3eqzxfLzFQqzujGa99ba9O296DwZrG+8YpmfJ+w== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1685007268; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=4NGWDH2m9xz3zGie63zl1kcLGjTJ0fX1VflVrGzz2ZQ=; b=mmiTP6jCW1+KvC8QM+LWeB5WcVHbyStKgJqzDNEQsZrG0o3PYsrEqd/a7KE5S+4YPNPZjx 20P+WWxS57IdbmBQ== To: Greg Kroah-Hartman Cc: Petr Mladek , Thomas Gleixner , linux-kernel@vger.kernel.org, Al Cooper , Broadcom internal kernel review list , Jiri Slaby , =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= , Lino Sanfilippo , Matthew Howell , Tony Lindgren , Lukas Wunner , Matthias Schiffer , Andy Shevchenko , =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= , linux-serial@vger.kernel.org Subject: [PATCH tty v1 1/8] serial: 8250: lock port in startup() callbacks Date: Thu, 25 May 2023 11:37:52 +0206 Message-Id: <20230525093159.223817-2-john.ogness@linutronix.de> In-Reply-To: <20230525093159.223817-1-john.ogness@linutronix.de> References: <20230525093159.223817-1-john.ogness@linutronix.de> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" uart_ops startup() callback is called without interrupts disabled and without port->lock locked, relatively late during the boot process (from the call path of console_on_rootfs()). If the device is a console, it was already previously registered and could be actively printing messages. The console printing function serial8250_console_write() modifies the interrupt register (UART_IER) under the port->lock with the pattern: read, clear, restore. Since some startup() callbacks are modifying UART_IER without the port->lock locked, it is possible that the value intended to be written by the startup() callback will get overwritten and be lost. CPU0 CPU1 serial8250_console_write omap_8250_startup -------------------------- ----------------- spin_lock(port->lock) oldval =3D read(UART_IER) uart_console_write() write(newval, UART_IER) write(oldval, UART_IER) spin_unlock(port->lock) Add port->lock synchronization to the 8250 startup() callbacks where they need to access UART_IER. This avoids racing with serial8250_console_write(). Signed-off-by: John Ogness --- drivers/tty/serial/8250/8250_bcm7271.c | 4 ++++ drivers/tty/serial/8250/8250_exar.c | 4 ++++ drivers/tty/serial/8250/8250_omap.c | 3 +++ drivers/tty/serial/8250/8250_port.c | 18 ++++++++++++++++-- 4 files changed, 27 insertions(+), 2 deletions(-) diff --git a/drivers/tty/serial/8250/8250_bcm7271.c b/drivers/tty/serial/82= 50/8250_bcm7271.c index f801b1f5b46c..2b38bcc5112e 100644 --- a/drivers/tty/serial/8250/8250_bcm7271.c +++ b/drivers/tty/serial/8250/8250_bcm7271.c @@ -605,9 +605,13 @@ static int brcmuart_startup(struct uart_port *port) /* * Disable the Receive Data Interrupt because the DMA engine * will handle this. + * + * Synchronize UART_IER access against the console. */ + spin_lock_irq(&port->lock); up->ier &=3D ~UART_IER_RDI; serial_port_out(port, UART_IER, up->ier); + spin_unlock_irq(&port->lock); =20 priv->tx_running =3D false; priv->dma.rx_dma =3D NULL; diff --git a/drivers/tty/serial/8250/8250_exar.c b/drivers/tty/serial/8250/= 8250_exar.c index 64770c62bbec..ae66ef9d863c 100644 --- a/drivers/tty/serial/8250/8250_exar.c +++ b/drivers/tty/serial/8250/8250_exar.c @@ -194,8 +194,12 @@ static int xr17v35x_startup(struct uart_port *port) /* * Make sure all interrups are masked until initialization is * complete and the FIFOs are cleared + * + * Synchronize UART_IER access against the console. */ + spin_lock_irq(&port->lock); serial_port_out(port, UART_IER, 0); + spin_unlock_irq(&port->lock); =20 return serial8250_do_startup(port); } diff --git a/drivers/tty/serial/8250/8250_omap.c b/drivers/tty/serial/8250/= 8250_omap.c index 5c093dfcee1d..fbca0692aa51 100644 --- a/drivers/tty/serial/8250/8250_omap.c +++ b/drivers/tty/serial/8250/8250_omap.c @@ -710,8 +710,11 @@ static int omap_8250_startup(struct uart_port *port) up->dma =3D NULL; } =20 + /* Synchronize UART_IER access against the console. */ + spin_lock_irq(&port->lock); up->ier =3D UART_IER_RLSI | UART_IER_RDI; serial_out(up, UART_IER, up->ier); + spin_unlock_irq(&port->lock); =20 #ifdef CONFIG_PM up->capabilities |=3D UART_CAP_RPM; diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/= 8250_port.c index 0cef9bfd0471..b3971302d8e5 100644 --- a/drivers/tty/serial/8250/8250_port.c +++ b/drivers/tty/serial/8250/8250_port.c @@ -2149,7 +2149,12 @@ int serial8250_do_startup(struct uart_port *port) =20 serial8250_rpm_get(up); if (port->type =3D=3D PORT_16C950) { - /* Wake up and initialize UART */ + /* + * Wake up and initialize UART + * + * Synchronize UART_IER access against the console. + */ + spin_lock_irqsave(&port->lock, flags); up->acr =3D 0; serial_port_out(port, UART_LCR, UART_LCR_CONF_MODE_B); serial_port_out(port, UART_EFR, UART_EFR_ECB); @@ -2159,12 +2164,19 @@ int serial8250_do_startup(struct uart_port *port) serial_port_out(port, UART_LCR, UART_LCR_CONF_MODE_B); serial_port_out(port, UART_EFR, UART_EFR_ECB); serial_port_out(port, UART_LCR, 0); + spin_unlock_irqrestore(&port->lock, flags); } =20 if (port->type =3D=3D PORT_DA830) { - /* Reset the port */ + /* + * Reset the port + * + * Synchronize UART_IER access against the console. + */ + spin_lock_irqsave(&port->lock, flags); serial_port_out(port, UART_IER, 0); serial_port_out(port, UART_DA830_PWREMU_MGMT, 0); + spin_unlock_irqrestore(&port->lock, flags); mdelay(10); =20 /* Enable Tx, Rx and free run mode */ @@ -2275,6 +2287,8 @@ int serial8250_do_startup(struct uart_port *port) * this interrupt whenever the transmitter is idle and * the interrupt is enabled. Delays are necessary to * allow register changes to become visible. + * + * Synchronize UART_IER access against the console. */ spin_lock_irqsave(&port->lock, flags); =20 --=20 2.30.2 From nobody Fri Sep 20 19:22:29 2024 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 178DCC7EE32 for ; Thu, 25 May 2023 09:35:08 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240739AbjEYJex (ORCPT ); Thu, 25 May 2023 05:34:53 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60586 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240547AbjEYJeg (ORCPT ); Thu, 25 May 2023 05:34:36 -0400 Received: from galois.linutronix.de (Galois.linutronix.de [IPv6:2a0a:51c0:0:12e:550::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id AF59B197; Thu, 25 May 2023 02:34:30 -0700 (PDT) From: John Ogness DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1685007269; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=GfgGfHa1/jsadbpGlnKJSGFRiVJrywAA/VFxC+Yj2dA=; b=1XqeSoefdhJJALM506iJsLxxiP33wRzEY/RsMT3xMOtbbwSIZJfn7afMjs2zCnNlZFm+MY 4C4cM0CGhUpbyB2kwn0lz5YTvF/Pt/sQyJPQpL7ICrDoCw7ifmLRZAs55sTnQ6JhTjOZvH P8ygMFRT+3hgG5MJYXN/psukiO3zfw/8WXpvUVy5s/XmOzO/zRZyDvBPeRwWAo7b82kTg8 RQIPSeXcpQpG51Ta2ARcV0PQgJ0IGjyzvmZR59/tZ1sW5mPAgFgBa6+E6wzg55gRrk/i9r Wr2sPsBgf4RtvEO2LM/yU3WOLQ94jsK5nTTOYFi3lG4gpbvRbCWh7zCaCkGkzQ== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1685007269; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=GfgGfHa1/jsadbpGlnKJSGFRiVJrywAA/VFxC+Yj2dA=; b=Fyn+5UtOwFlmls5SvZ5Pshw2Y2RG5/lrcgn39nVFzwqUwJW/1dghAip25QPfmh228+BFEH xBccxteWawp6g4AQ== To: Greg Kroah-Hartman Cc: Petr Mladek , Thomas Gleixner , linux-kernel@vger.kernel.org, Jiri Slaby , Vijaya Krishna Nivarthi , linux-serial@vger.kernel.org Subject: [PATCH tty v1 2/8] serial: core: lock port for stop_rx() in uart_suspend_port() Date: Thu, 25 May 2023 11:37:53 +0206 Message-Id: <20230525093159.223817-3-john.ogness@linutronix.de> In-Reply-To: <20230525093159.223817-1-john.ogness@linutronix.de> References: <20230525093159.223817-1-john.ogness@linutronix.de> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" The uarts_ops stop_rx() callback expects that the port->lock is taken and interrupts are disabled. Fixes: c9d2325cdb92 ("serial: core: Do stop_rx in suspend path for console = if console_suspend is disabled") Signed-off-by: John Ogness Reviewed-by: Douglas Anderson --- drivers/tty/serial/serial_core.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_c= ore.c index 4b98d13555c0..37ad53616372 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c @@ -2333,8 +2333,11 @@ int uart_suspend_port(struct uart_driver *drv, struc= t uart_port *uport) * able to Re-start_rx later. */ if (!console_suspend_enabled && uart_console(uport)) { - if (uport->ops->start_rx) + if (uport->ops->start_rx) { + spin_lock_irq(&uport->lock); uport->ops->stop_rx(uport); + spin_unlock_irq(&uport->lock); + } goto unlock; } =20 --=20 2.30.2 From nobody Fri Sep 20 19:22:29 2024 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3BE3CC77B7E for ; Thu, 25 May 2023 09:35:06 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240601AbjEYJen (ORCPT ); Thu, 25 May 2023 05:34:43 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60580 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240513AbjEYJeg (ORCPT ); Thu, 25 May 2023 05:34:36 -0400 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0001519D; Thu, 25 May 2023 02:34:30 -0700 (PDT) From: John Ogness DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1685007269; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=ja3DzHE65weLmaEmyLLj0yo4U8LIunOOQtWnThWK8is=; b=uFW1cntdseBw4Nlcii3FUzxCE96sV9v1tVE5rbCJukpWARo0YvyDW7fNUPGg0FvNu6s1L4 t6We7a+2Z00Cq4YA+JMYTYuZrCzXPGgGyJu+VA6wDf9iXY1rTSJq2gin2OAdXzi4jlhSJJ 3e5VGO1cy8G/CiPauZwJFH61Mzyo8Z20iM27bMRS7h9OvjQ2RdwbjGLpOPPL6ZUXBR4I36 1Ejn83BGTNE4mxbHsoFkj+NO3zwSvdZ1CAdcexT1vBAsCmHNCuGvOHisxD7cSP9Gs2xDTE 1RW8HccAkhT8ktSDbML28YHUcHpu+Y80gH4/AE+K4LHshnnL6lSWW05OlabDBA== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1685007269; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=ja3DzHE65weLmaEmyLLj0yo4U8LIunOOQtWnThWK8is=; b=XMnjW0U55afe9vxq3aGUAviz6nfwdyywSmRFA3DlpYPJOAS2TclvYZK+gOQ4tF0Z+gwo/b sCv7GuZAsSdAu5AA== To: Greg Kroah-Hartman Cc: Petr Mladek , Thomas Gleixner , linux-kernel@vger.kernel.org, Jiri Slaby , =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= , Tony Lindgren , Lukas Wunner , Matthias Schiffer , linux-serial@vger.kernel.org Subject: [PATCH tty v1 3/8] serial: 8250: lock port for stop_rx() in omap8250_irq() Date: Thu, 25 May 2023 11:37:54 +0206 Message-Id: <20230525093159.223817-4-john.ogness@linutronix.de> In-Reply-To: <20230525093159.223817-1-john.ogness@linutronix.de> References: <20230525093159.223817-1-john.ogness@linutronix.de> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" The uarts_ops stop_rx() callback expects that the port->lock is taken and interrupts are disabled. Fixes: 1fe0e1fa3209 ("serial: 8250_omap: Handle optional overrun-throttle-m= s property") Signed-off-by: John Ogness Reviewed-by: Tony Lindgren --- drivers/tty/serial/8250/8250_omap.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/tty/serial/8250/8250_omap.c b/drivers/tty/serial/8250/= 8250_omap.c index fbca0692aa51..c17d98161d5e 100644 --- a/drivers/tty/serial/8250/8250_omap.c +++ b/drivers/tty/serial/8250/8250_omap.c @@ -658,7 +658,9 @@ static irqreturn_t omap8250_irq(int irq, void *dev_id) =20 up->ier =3D port->serial_in(port, UART_IER); if (up->ier & (UART_IER_RLSI | UART_IER_RDI)) { + spin_lock(&port->lock); port->ops->stop_rx(port); + spin_unlock(&port->lock); } else { /* Keep restarting the timer until * the input overrun subsides. --=20 2.30.2 From nobody Fri Sep 20 19:22:29 2024 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id E95AFC77B7A for ; Thu, 25 May 2023 09:35:07 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240697AbjEYJeq (ORCPT ); Thu, 25 May 2023 05:34:46 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60588 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240519AbjEYJeg (ORCPT ); Thu, 25 May 2023 05:34:36 -0400 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 548C71A2; Thu, 25 May 2023 02:34:31 -0700 (PDT) From: John Ogness DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1685007269; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=4e3/MmglhQzDhzxZKmrh29ltZzGLtHjU6m+4lcF3Ohc=; b=NTr1IkyQZ3OjcNlK4kp6xH1FWtIZitO+012FKXjtrrK1TncJzHvVRCKB2HJMfrJeLNwbdv JqTB4lbCkHpWdmGVU5IV0oSMOrnCgco1IrJYFalyMgIYhkmoF+ls8sWoIXWwGHBTvAv2VM AsESQbtcYDRinZpSMAv2lQTsnptfIbem7K8AtFoGqFwud1/rfvw7F05ZvxvRy0LATu+F8T D+EFAcJK7ms+VnYmR2p2r9Qpx1ZLFq6Z0RTlRc1a0UNByZ9v138z6/F1HL5D3TdYva9DEW wga+ysXcWpNnhcGd/bCi+WRLYUf/VVV3R00jadPPgDtnIqKZbThruZgML7Vlfw== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1685007269; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=4e3/MmglhQzDhzxZKmrh29ltZzGLtHjU6m+4lcF3Ohc=; b=OQ/ky65DAwfr8I0FKrHj0L+b/kkpcdBW/cvTc4v+Gja6TPoPnsWTFi/SGx6YP134mMOLhZ Z42apekShbMWanBQ== To: Greg Kroah-Hartman Cc: Petr Mladek , Thomas Gleixner , linux-kernel@vger.kernel.org, Jiri Slaby , Vijaya Krishna Nivarthi , Douglas Anderson , linux-serial@vger.kernel.org Subject: [PATCH tty v1 4/8] serial: core: lock port for start_rx() in uart_resume_port() Date: Thu, 25 May 2023 11:37:55 +0206 Message-Id: <20230525093159.223817-5-john.ogness@linutronix.de> In-Reply-To: <20230525093159.223817-1-john.ogness@linutronix.de> References: <20230525093159.223817-1-john.ogness@linutronix.de> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" The only user of the start_rx() callback (qcom_geni) directly calls its own stop_rx() callback. Since stop_rx() requires that the port->lock is taken and interrupts are disabled, the start_rx() callback has the same requirement. Fixes: cfab87c2c271 ("serial: core: Introduce callback for start_rx and do = stop_rx in suspend only if this callback implementation is present.") Signed-off-by: John Ogness Reviewed-by: Douglas Anderson --- drivers/tty/serial/serial_core.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_c= ore.c index 37ad53616372..f856c7fae2fd 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c @@ -2430,8 +2430,11 @@ int uart_resume_port(struct uart_driver *drv, struct= uart_port *uport) if (console_suspend_enabled) uart_change_pm(state, UART_PM_STATE_ON); uport->ops->set_termios(uport, &termios, NULL); - if (!console_suspend_enabled && uport->ops->start_rx) + if (!console_suspend_enabled && uport->ops->start_rx) { + spin_lock_irq(&uport->lock); uport->ops->start_rx(uport); + spin_unlock_irq(&uport->lock); + } if (console_suspend_enabled) console_start(uport->cons); } --=20 2.30.2 From nobody Fri Sep 20 19:22:29 2024 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7B8CAC7EE2F for ; Thu, 25 May 2023 09:35:13 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240698AbjEYJfL (ORCPT ); Thu, 25 May 2023 05:35:11 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60686 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240605AbjEYJek (ORCPT ); Thu, 25 May 2023 05:34:40 -0400 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 07D0A1B4; Thu, 25 May 2023 02:34:33 -0700 (PDT) From: John Ogness DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1685007270; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=TAVFpLxJcM8gO8l/0bCuwkiWYAOYDDSeRboLXbR9Aek=; b=ykmKrFJzIEPB1IJaAecFMnbuPRNqq8W4v0ilizJRs2eB4zd7ETFHwUxbF6Df2nqmYD3Iq+ fVFjwJfAyXYbyQ05LIMuNPGD+V8a3Qfq+DoyY8wFHmCWzMRxEySwmgevQYbQSAebVZ88wu sda0dyy9wmEABP85uFpf+hZ2J1e7hZFZpvTZi6Vacwpz2CIeNzQvnrJDeaJlwwdrf2ERWc qT0fokVrR9JnRGf0lWBhxElkKlDcyksM6NBA/+ksbX+eoOEuwM9K7cf8p0ox724pBIn+Ho qsqu64ECv7iV41bH5ziiJqXDxAN8+hvvf2wTF8cDXJ/PW6fNBRIYGFAvWGKNHw== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1685007270; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=TAVFpLxJcM8gO8l/0bCuwkiWYAOYDDSeRboLXbR9Aek=; b=gCBfiyyGHO59EVDJPrbMzAqqpgW3m+JHu7zU/NjqtshBqw/l5TgEsDdTfEc/lNCqnfW0rW 3RBdS105E0pyplAw== To: Greg Kroah-Hartman Cc: Petr Mladek , Thomas Gleixner , linux-kernel@vger.kernel.org, Jiri Slaby , =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= , Tony Lindgren , Lukas Wunner , Matthias Schiffer , linux-serial@vger.kernel.org Subject: [PATCH tty v1 5/8] serial: 8250: lock port for rx_dma() callback Date: Thu, 25 May 2023 11:37:56 +0206 Message-Id: <20230525093159.223817-6-john.ogness@linutronix.de> In-Reply-To: <20230525093159.223817-1-john.ogness@linutronix.de> References: <20230525093159.223817-1-john.ogness@linutronix.de> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" The rx_dma() callback (omap_8250_rx_dma) accesses UART_IER. This register is modified twice by each console write (serial8250_console_write()) under the port lock. However, not all calls to the rx_dma() callback are under the port lock. Add the missing port locking around rx_dma() callback calls. Add lockdep notation to the omap_8250_rx_dma(). Note that this is not fixing a real problem because: 1. Currently DMA is forced off for 8250_omap consoles. 2. The serial devices are resumed before console printing is enabled. However, adding this locking allows for clean locking semantics for the rx_dma() callback so that lockdep can be used to identify possible problems in the future. It also simplifies synchronization of UART_IER in general by not needing to rely on implementation details such as 1 and 2. Signed-off-by: John Ogness --- drivers/tty/serial/8250/8250_omap.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/drivers/tty/serial/8250/8250_omap.c b/drivers/tty/serial/8250/= 8250_omap.c index c17d98161d5e..3cb9cfa62331 100644 --- a/drivers/tty/serial/8250/8250_omap.c +++ b/drivers/tty/serial/8250/8250_omap.c @@ -728,8 +728,11 @@ static int omap_8250_startup(struct uart_port *port) priv->wer |=3D OMAP_UART_TX_WAKEUP_EN; serial_out(up, UART_OMAP_WER, priv->wer); =20 - if (up->dma && !(priv->habit & UART_HAS_EFR2)) + if (up->dma && !(priv->habit & UART_HAS_EFR2)) { + spin_lock_irq(&port->lock); up->dma->rx_dma(up); + spin_unlock_irq(&port->lock); + } =20 enable_irq(up->port.irq); =20 @@ -1003,6 +1006,9 @@ static int omap_8250_rx_dma(struct uart_8250_port *p) unsigned long flags; u32 reg; =20 + /* Port locked to synchronize UART_IER access against the console. */ + lockdep_assert_held_once(&p->port.lock); + if (priv->rx_dma_broken) return -EINVAL; =20 @@ -1736,8 +1742,11 @@ static int omap8250_runtime_resume(struct device *de= v) if (up && omap8250_lost_context(up)) omap8250_restore_regs(up); =20 - if (up && up->dma && up->dma->rxchan && !(priv->habit & UART_HAS_EFR2)) + if (up && up->dma && up->dma->rxchan && !(priv->habit & UART_HAS_EFR2)) { + spin_lock_irq(&up->port.lock); omap_8250_rx_dma(up); + spin_unlock_irq(&up->port.lock); + } =20 priv->latency =3D priv->calc_latency; schedule_work(&priv->qos_work); --=20 2.30.2 From nobody Fri Sep 20 19:22:29 2024 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 27D34C77B7A for ; Thu, 25 May 2023 09:35:19 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240731AbjEYJfQ (ORCPT ); Thu, 25 May 2023 05:35:16 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60670 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240627AbjEYJel (ORCPT ); Thu, 25 May 2023 05:34:41 -0400 Received: from galois.linutronix.de (Galois.linutronix.de [IPv6:2a0a:51c0:0:12e:550::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 074271B1; Thu, 25 May 2023 02:34:33 -0700 (PDT) From: John Ogness DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1685007270; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=nPDJHm4lU4uW5PYPRilpSR3PUXlYNGeyc1k5gm2WMrg=; b=Bn9RR6tFw4VHxMRtNu5ITPrZWhJi9VsTk3Ief2f7HcBlEtLMBnVNouWr0IM4OCsP02Dq7Q gdWxPPKFD6kokGHfylzCLf1elFujWvrjGvnJqujbqfHuADfuMLyd6ENik68sarNNrhQFuE c4RkxSMLo7Jg4Ctn+oJapV4snGobAEx0h5zm/6LKkgV48KMBlXtUQ7u4cf07BFSCaEYVjs CLVHT/h0C+zTSycU3IFxqCaSwRZY02Qgl4LpRpu15aLv5QBON8m6QA+BXf3T7MUmdcMh/v tARTQSo+S9rmvPFdJm8rCofDsynBzdEdXV+R9vlJp9w5Fe5d9Bc6DCZitRM3iw== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1685007270; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=nPDJHm4lU4uW5PYPRilpSR3PUXlYNGeyc1k5gm2WMrg=; b=D7c8sfO9B0xWafdKccZQxoeJ+NYAiCmP6zJoGfo+FNhKFSWjUhH4xcqrDjjtHasOyuCFUa o6+70hF7B7N+QMDA== To: Greg Kroah-Hartman Cc: Petr Mladek , Thomas Gleixner , linux-kernel@vger.kernel.org, Jiri Slaby , =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= , Tony Lindgren , Lukas Wunner , Matthias Schiffer , linux-serial@vger.kernel.org Subject: [PATCH tty v1 6/8] serial: 8250: lock port for omap8250_restore_regs() Date: Thu, 25 May 2023 11:37:57 +0206 Message-Id: <20230525093159.223817-7-john.ogness@linutronix.de> In-Reply-To: <20230525093159.223817-1-john.ogness@linutronix.de> References: <20230525093159.223817-1-john.ogness@linutronix.de> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" omap8250_restore_regs() accesses UART_IER. This register is modified twice by each console write (serial8250_console_write()) under the port lock. However, not all calls to omap8250_restore_regs() are under the port lock. Add the missing port locking around omap8250_restore_regs() calls. Add lockdep notation to the omap8250_restore_regs(). Note that this is not fixing a real problem because the serial devices are resumed before console printing is enabled. However, adding this locking allows for clean locking semantics for omap8250_restore_regs() so that lockdep can be used to identify possible problems in the future. It also simplifies synchronization of UART_IER in general by not needing to rely on such implementation details. Signed-off-by: John Ogness --- drivers/tty/serial/8250/8250_omap.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/tty/serial/8250/8250_omap.c b/drivers/tty/serial/8250/= 8250_omap.c index 3cb9cfa62331..34939462fd69 100644 --- a/drivers/tty/serial/8250/8250_omap.c +++ b/drivers/tty/serial/8250/8250_omap.c @@ -309,6 +309,9 @@ static void omap8250_restore_regs(struct uart_8250_port= *up) struct uart_8250_dma *dma =3D up->dma; u8 mcr =3D serial8250_in_MCR(up); =20 + /* Port locked to synchronize UART_IER access against the console. */ + lockdep_assert_held_once(&up->port.lock); + if (dma && dma->tx_running) { /* * TCSANOW requests the change to occur immediately however if @@ -1739,8 +1742,11 @@ static int omap8250_runtime_resume(struct device *de= v) if (priv->line >=3D 0) up =3D serial8250_get_port(priv->line); =20 - if (up && omap8250_lost_context(up)) + if (up && omap8250_lost_context(up)) { + spin_lock_irq(&up->port.lock); omap8250_restore_regs(up); + spin_unlock_irq(&up->port.lock); + } =20 if (up && up->dma && up->dma->rxchan && !(priv->habit & UART_HAS_EFR2)) { spin_lock_irq(&up->port.lock); --=20 2.30.2 From nobody Fri Sep 20 19:22:29 2024 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0CB1DC77B7A for ; Thu, 25 May 2023 09:35:22 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240738AbjEYJfU (ORCPT ); Thu, 25 May 2023 05:35:20 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60678 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240507AbjEYJem (ORCPT ); Thu, 25 May 2023 05:34:42 -0400 Received: from galois.linutronix.de (Galois.linutronix.de [IPv6:2a0a:51c0:0:12e:550::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 57268E43; Thu, 25 May 2023 02:34:37 -0700 (PDT) From: John Ogness DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1685007271; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=6UePhmuOlccQPrukH0wHmWv4ftbqOBpeN2xQeS1c0hQ=; b=MQzqE+YwkU6EWfWTwWtWZv/w8j/DF13mM+sZsxWgRUqQWoda//KIf2ceBm4fX/z018WnnR 3S2l0ZIg/rzqINrnbsv4+/Xj9K8d2iYpoQEV4V8I9U5na8tc/9aSrHtIAwsVxtzAP9qkwI r5g0YpjrPlXGuFz4EDwggFCuB8C2COz4vpaGhgol/nVsEaEeQxOPu502kLiBAXK3AQ/j/f xyUHqLUz+feUuKjUlKSFG6JK5TR3Gu/ziDkw22pV7EMwR6oBxa9oQEnOJkFc3zJdJlQIaO hjswhAOvU/qvv6rfvmy1H1FJPTKHCPJlOuPucYSnpT64gt7ejhmmWAe5lnKkaw== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1685007271; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=6UePhmuOlccQPrukH0wHmWv4ftbqOBpeN2xQeS1c0hQ=; b=1cZB2z7Jl8jwfFvDISRhYZME1R2qmyJNn3L7OjY1A10/Y+u1VlvnKA+PHjTQQgZ+m+tAJw IVG+702no0FxTaAQ== To: Greg Kroah-Hartman Cc: Petr Mladek , Thomas Gleixner , linux-kernel@vger.kernel.org, Jiri Slaby , =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= , Tony Lindgren , Lukas Wunner , Matthias Schiffer , linux-serial@vger.kernel.org Subject: [PATCH tty v1 7/8] serial: 8250: lock port for UART_IER access in omap8250_irq() Date: Thu, 25 May 2023 11:37:58 +0206 Message-Id: <20230525093159.223817-8-john.ogness@linutronix.de> In-Reply-To: <20230525093159.223817-1-john.ogness@linutronix.de> References: <20230525093159.223817-1-john.ogness@linutronix.de> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" omap8250_irq() accesses UART_IER. This register is modified twice by each console write (serial8250_console_write()) under the port lock. omap8250_irq() must also take the port lock to guanentee synchronized access to UART_IER. Since the port lock is already being taken for the stop_rx() callback and since it is safe to call cancel_delayed_work() while holding the port lock, simply extend the port lock region to include UART_IER access. Fixes: 1fe0e1fa3209 ("serial: 8250_omap: Handle optional overrun-throttle-m= s property") Signed-off-by: John Ogness Reviewed-by: Tony Lindgren --- drivers/tty/serial/8250/8250_omap.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/tty/serial/8250/8250_omap.c b/drivers/tty/serial/8250/= 8250_omap.c index 34939462fd69..3225c95fde1d 100644 --- a/drivers/tty/serial/8250/8250_omap.c +++ b/drivers/tty/serial/8250/8250_omap.c @@ -659,17 +659,18 @@ static irqreturn_t omap8250_irq(int irq, void *dev_id) if ((lsr & UART_LSR_OE) && up->overrun_backoff_time_ms > 0) { unsigned long delay; =20 + /* Synchronize UART_IER access against the console. */ + spin_lock(&port->lock); up->ier =3D port->serial_in(port, UART_IER); if (up->ier & (UART_IER_RLSI | UART_IER_RDI)) { - spin_lock(&port->lock); port->ops->stop_rx(port); - spin_unlock(&port->lock); } else { /* Keep restarting the timer until * the input overrun subsides. */ cancel_delayed_work(&up->overrun_backoff); } + spin_unlock(&port->lock); =20 delay =3D msecs_to_jiffies(up->overrun_backoff_time_ms); schedule_delayed_work(&up->overrun_backoff, delay); --=20 2.30.2 From nobody Fri Sep 20 19:22:29 2024 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 246FCC7EE2E for ; Thu, 25 May 2023 09:35:27 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240753AbjEYJfY (ORCPT ); Thu, 25 May 2023 05:35:24 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60728 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240660AbjEYJem (ORCPT ); Thu, 25 May 2023 05:34:42 -0400 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 529FEE42; Thu, 25 May 2023 02:34:37 -0700 (PDT) From: John Ogness DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1685007271; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=vZVepLjGQmA8Sd7Dsoz91hGyNnRRVtsxo9tL/VycGyM=; b=uZ3fJDvn3TkdggxynrSMSfRfldyWS4BjQknTKnFLPsovz8j7ATjj9wKY0YrNVgjmstnPDp RpaZS25BsNwZGpaoJ/p7EJJ0uIbBlS2FUZb7JOxDaj01/dymaraJMQq3HMBNo8AdoDtjj9 zicPN9Y+n59Eio5tvFDuMNg3FqCmngFYk44jhQfhJmmgYQqabA/sWVdNy5FxqS89PuRfOd aIlGwXIVvB3HqG5QjnSzYqSFoy17PnFrpG0S42MoYhVVriluyO/v7qDu49txvu1bQtu0UR T/hMyr5UmoePZahxw43d/YnRICYxjiOuqkO5KdkecSSs27EigiIE7kgVE4e+xA== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1685007271; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=vZVepLjGQmA8Sd7Dsoz91hGyNnRRVtsxo9tL/VycGyM=; b=sSWawuGzshyC+A1UZwduoT3u0VBy5TcXDOddQy8qoXvVAcuzGJyKZcT9rD6R+qnYz6FWGe gQLD6b6k+lHbNkAw== To: Greg Kroah-Hartman Cc: Petr Mladek , Thomas Gleixner , linux-kernel@vger.kernel.org, Jiri Slaby , Joel Stanley , Andrew Jeffery , Matthias Brugger , AngeloGioacchino Del Regno , =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= , Andy Shevchenko , Tony Lindgren , Lukas Wunner , Matthias Schiffer , =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= , linux-serial@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-aspeed@lists.ozlabs.org, linux-mediatek@lists.infradead.org Subject: [PATCH tty v1 8/8] serial: 8250: synchronize and annotate UART_IER access Date: Thu, 25 May 2023 11:37:59 +0206 Message-Id: <20230525093159.223817-9-john.ogness@linutronix.de> In-Reply-To: <20230525093159.223817-1-john.ogness@linutronix.de> References: <20230525093159.223817-1-john.ogness@linutronix.de> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" The UART_IER register is modified twice by each console write (serial8250_console_write()) under the port lock. Any driver code that accesses UART_IER must do so with the port locked in order to ensure consistent values, even when for read accesses. Add locking, lockdep notation, and/or comments everywhere UART_IER is accessed. The added locking is not fixing a real problem because it occurs where the console is not active. However, adding the locking to these non-critical paths greatly simplifies UART_IER access tracking by establishing a general policy that all UART_IER access is performed with the port locked. Signed-off-by: John Ogness --- drivers/tty/serial/8250/8250.h | 6 +++ drivers/tty/serial/8250/8250_aspeed_vuart.c | 3 ++ drivers/tty/serial/8250/8250_mtk.c | 9 ++++ drivers/tty/serial/8250/8250_omap.c | 14 ++++++ drivers/tty/serial/8250/8250_port.c | 53 +++++++++++++++++++++ 5 files changed, 85 insertions(+) diff --git a/drivers/tty/serial/8250/8250.h b/drivers/tty/serial/8250/8250.h index 5418708f4631..471c6bc5f78f 100644 --- a/drivers/tty/serial/8250/8250.h +++ b/drivers/tty/serial/8250/8250.h @@ -179,6 +179,9 @@ static inline void serial_dl_write(struct uart_8250_por= t *up, u32 value) =20 static inline bool serial8250_set_THRI(struct uart_8250_port *up) { + /* Port locked to synchronize UART_IER access against the console. */ + lockdep_assert_held_once(&up->port.lock); + if (up->ier & UART_IER_THRI) return false; up->ier |=3D UART_IER_THRI; @@ -188,6 +191,9 @@ static inline bool serial8250_set_THRI(struct uart_8250= _port *up) =20 static inline bool serial8250_clear_THRI(struct uart_8250_port *up) { + /* Port locked to synchronize UART_IER access against the console. */ + lockdep_assert_held_once(&up->port.lock); + if (!(up->ier & UART_IER_THRI)) return false; up->ier &=3D ~UART_IER_THRI; diff --git a/drivers/tty/serial/8250/8250_aspeed_vuart.c b/drivers/tty/seri= al/8250/8250_aspeed_vuart.c index 9d2a7856784f..4a9e71b2dbbc 100644 --- a/drivers/tty/serial/8250/8250_aspeed_vuart.c +++ b/drivers/tty/serial/8250/8250_aspeed_vuart.c @@ -275,6 +275,9 @@ static void __aspeed_vuart_set_throttle(struct uart_825= 0_port *up, { unsigned char irqs =3D UART_IER_RLSI | UART_IER_RDI; =20 + /* Port locked to synchronize UART_IER access against the console. */ + lockdep_assert_held_once(&up->port.lock); + up->ier &=3D ~irqs; if (!throttle) up->ier |=3D irqs; diff --git a/drivers/tty/serial/8250/8250_mtk.c b/drivers/tty/serial/8250/8= 250_mtk.c index fb1d5ec0940e..aa8e98164d68 100644 --- a/drivers/tty/serial/8250/8250_mtk.c +++ b/drivers/tty/serial/8250/8250_mtk.c @@ -222,11 +222,17 @@ static void mtk8250_shutdown(struct uart_port *port) =20 static void mtk8250_disable_intrs(struct uart_8250_port *up, int mask) { + /* Port locked to synchronize UART_IER access against the console. */ + lockdep_assert_held_once(&up->port.lock); + serial_out(up, UART_IER, serial_in(up, UART_IER) & (~mask)); } =20 static void mtk8250_enable_intrs(struct uart_8250_port *up, int mask) { + /* Port locked to synchronize UART_IER access against the console. */ + lockdep_assert_held_once(&up->port.lock); + serial_out(up, UART_IER, serial_in(up, UART_IER) | mask); } =20 @@ -235,6 +241,9 @@ static void mtk8250_set_flow_ctrl(struct uart_8250_port= *up, int mode) struct uart_port *port =3D &up->port; int lcr =3D serial_in(up, UART_LCR); =20 + /* Port locked to synchronize UART_IER access against the console. */ + lockdep_assert_held_once(&port->lock); + serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); serial_out(up, MTK_UART_EFR, UART_EFR_ECB); serial_out(up, UART_LCR, lcr); diff --git a/drivers/tty/serial/8250/8250_omap.c b/drivers/tty/serial/8250/= 8250_omap.c index 3225c95fde1d..0498b9b0e4e9 100644 --- a/drivers/tty/serial/8250/8250_omap.c +++ b/drivers/tty/serial/8250/8250_omap.c @@ -533,6 +533,10 @@ static void omap_8250_pm(struct uart_port *port, unsig= ned int state, u8 efr; =20 pm_runtime_get_sync(port->dev); + + /* Synchronize UART_IER access against the console. */ + spin_lock_irq(&port->lock); + serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); efr =3D serial_in(up, UART_EFR); serial_out(up, UART_EFR, efr | UART_EFR_ECB); @@ -543,6 +547,8 @@ static void omap_8250_pm(struct uart_port *port, unsign= ed int state, serial_out(up, UART_EFR, efr); serial_out(up, UART_LCR, 0); =20 + spin_unlock_irq(&port->lock); + pm_runtime_mark_last_busy(port->dev); pm_runtime_put_autosuspend(port->dev); } @@ -760,8 +766,11 @@ static void omap_8250_shutdown(struct uart_port *port) if (priv->habit & UART_HAS_EFR2) serial_out(up, UART_OMAP_EFR2, 0x0); =20 + /* Synchronize UART_IER access against the console. */ + spin_lock_irq(&port->lock); up->ier =3D 0; serial_out(up, UART_IER, 0); + spin_unlock_irq(&port->lock); disable_irq_nosync(up->port.irq); dev_pm_clear_wake_irq(port->dev); =20 @@ -803,6 +812,7 @@ static void omap_8250_unthrottle(struct uart_port *port) =20 pm_runtime_get_sync(port->dev); =20 + /* Synchronize UART_IER access against the console. */ spin_lock_irqsave(&port->lock, flags); priv->throttled =3D false; if (up->dma) @@ -953,6 +963,7 @@ static void __dma_rx_complete(void *param) struct dma_tx_state state; unsigned long flags; =20 + /* Synchronize UART_IER access against the console. */ spin_lock_irqsave(&p->port.lock, flags); =20 /* @@ -1227,6 +1238,9 @@ static u16 omap_8250_handle_rx_dma(struct uart_8250_p= ort *up, u8 iir, u16 status static void am654_8250_handle_rx_dma(struct uart_8250_port *up, u8 iir, u16 status) { + /* Port locked to synchronize UART_IER access against the console. */ + lockdep_assert_held_once(&up->port.lock); + /* * Queue a new transfer if FIFO has data. */ diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/= 8250_port.c index b3971302d8e5..4b7bbd8b3305 100644 --- a/drivers/tty/serial/8250/8250_port.c +++ b/drivers/tty/serial/8250/8250_port.c @@ -539,6 +539,9 @@ EXPORT_SYMBOL_GPL(serial8250_rpm_put); */ static int serial8250_em485_init(struct uart_8250_port *p) { + /* Port locked to synchronize UART_IER access against the console. */ + lockdep_assert_held_once(&p->port.lock); + if (p->em485) goto deassert_rts; =20 @@ -676,6 +679,8 @@ static void serial8250_set_sleep(struct uart_8250_port = *p, int sleep) serial8250_rpm_get(p); =20 if (p->capabilities & UART_CAP_SLEEP) { + /* Synchronize UART_IER access against the console. */ + spin_lock_irq(&p->port.lock); if (p->capabilities & UART_CAP_EFR) { lcr =3D serial_in(p, UART_LCR); efr =3D serial_in(p, UART_EFR); @@ -689,6 +694,7 @@ static void serial8250_set_sleep(struct uart_8250_port = *p, int sleep) serial_out(p, UART_EFR, efr); serial_out(p, UART_LCR, lcr); } + spin_unlock_irq(&p->port.lock); } =20 serial8250_rpm_put(p); @@ -696,6 +702,9 @@ static void serial8250_set_sleep(struct uart_8250_port = *p, int sleep) =20 static void serial8250_clear_IER(struct uart_8250_port *up) { + /* Port locked to synchronize UART_IER access against the console. */ + lockdep_assert_held_once(&up->port.lock); + if (up->capabilities & UART_CAP_UUE) serial_out(up, UART_IER, UART_IER_UUE); else @@ -968,6 +977,9 @@ static void autoconfig_16550a(struct uart_8250_port *up) unsigned char status1, status2; unsigned int iersave; =20 + /* Port locked to synchronize UART_IER access against the console. */ + lockdep_assert_held_once(&up->port.lock); + up->port.type =3D PORT_16550A; up->capabilities |=3D UART_CAP_FIFO; =20 @@ -1151,6 +1163,8 @@ static void autoconfig(struct uart_8250_port *up) /* * We really do need global IRQs disabled here - we're going to * be frobbing the chips IRQ enable register to see if it exists. + * + * Synchronize UART_IER access against the console. */ spin_lock_irqsave(&port->lock, flags); =20 @@ -1323,7 +1337,10 @@ static void autoconfig_irq(struct uart_8250_port *up) /* forget possible initially masked and pending IRQ */ probe_irq_off(probe_irq_on()); save_mcr =3D serial8250_in_MCR(up); + /* Synchronize UART_IER access against the console. */ + spin_lock_irq(&port->lock); save_ier =3D serial_in(up, UART_IER); + spin_unlock_irq(&port->lock); serial8250_out_MCR(up, UART_MCR_OUT1 | UART_MCR_OUT2); =20 irqs =3D probe_irq_on(); @@ -1335,7 +1352,10 @@ static void autoconfig_irq(struct uart_8250_port *up) serial8250_out_MCR(up, UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2); } + /* Synchronize UART_IER access against the console. */ + spin_lock_irq(&port->lock); serial_out(up, UART_IER, UART_IER_ALL_INTR); + spin_unlock_irq(&port->lock); serial_in(up, UART_LSR); serial_in(up, UART_RX); serial_in(up, UART_IIR); @@ -1345,7 +1365,10 @@ static void autoconfig_irq(struct uart_8250_port *up) irq =3D probe_irq_off(irqs); =20 serial8250_out_MCR(up, save_mcr); + /* Synchronize UART_IER access against the console. */ + spin_lock_irq(&port->lock); serial_out(up, UART_IER, save_ier); + spin_unlock_irq(&port->lock); =20 if (port->flags & UPF_FOURPORT) outb_p(save_ICP, ICP); @@ -1360,6 +1383,9 @@ static void serial8250_stop_rx(struct uart_port *port) { struct uart_8250_port *up =3D up_to_u8250p(port); =20 + /* Port locked to synchronize UART_IER access against the console. */ + lockdep_assert_held_once(&port->lock); + serial8250_rpm_get(up); =20 up->ier &=3D ~(UART_IER_RLSI | UART_IER_RDI); @@ -1379,6 +1405,9 @@ void serial8250_em485_stop_tx(struct uart_8250_port *= p) { unsigned char mcr =3D serial8250_in_MCR(p); =20 + /* Port locked to synchronize UART_IER access against the console. */ + lockdep_assert_held_once(&p->port.lock); + if (p->port.rs485.flags & SER_RS485_RTS_AFTER_SEND) mcr |=3D UART_MCR_RTS; else @@ -1428,6 +1457,9 @@ static void __stop_tx_rs485(struct uart_8250_port *p,= u64 stop_delay) { struct uart_8250_em485 *em485 =3D p->em485; =20 + /* Port locked to synchronize UART_IER access against the console. */ + lockdep_assert_held_once(&p->port.lock); + stop_delay +=3D (u64)p->port.rs485.delay_rts_after_send * NSEC_PER_MSEC; =20 /* @@ -1607,6 +1639,9 @@ static void serial8250_start_tx(struct uart_port *por= t) struct uart_8250_port *up =3D up_to_u8250p(port); struct uart_8250_em485 *em485 =3D up->em485; =20 + /* Port locked to synchronize UART_IER access against the console. */ + lockdep_assert_held_once(&port->lock); + if (!port->x_char && uart_circ_empty(&port->state->xmit)) return; =20 @@ -1634,6 +1669,9 @@ static void serial8250_disable_ms(struct uart_port *p= ort) { struct uart_8250_port *up =3D up_to_u8250p(port); =20 + /* Port locked to synchronize UART_IER access against the console. */ + lockdep_assert_held_once(&port->lock); + /* no MSR capabilities */ if (up->bugs & UART_BUG_NOMSR) return; @@ -1648,6 +1686,9 @@ static void serial8250_enable_ms(struct uart_port *po= rt) { struct uart_8250_port *up =3D up_to_u8250p(port); =20 + /* Port locked to synchronize UART_IER access against the console. */ + lockdep_assert_held_once(&port->lock); + /* no MSR capabilities */ if (up->bugs & UART_BUG_NOMSR) return; @@ -2104,6 +2145,14 @@ static void serial8250_put_poll_char(struct uart_por= t *port, unsigned int ier; struct uart_8250_port *up =3D up_to_u8250p(port); =20 + /* + * Normally the port is locked to synchronize UART_IER access + * against the console. However, this function is only used by + * KDB/KGDB, where it may not be possible to acquire the port + * lock because all other CPUs are quiesced. The quiescence + * should allow safe lockless usage here. + */ + serial8250_rpm_get(up); /* * First save the IER then disable the interrupts @@ -2439,6 +2488,8 @@ void serial8250_do_shutdown(struct uart_port *port) serial8250_rpm_get(up); /* * Disable interrupts from this port + * + * Synchronize UART_IER access against the console. */ spin_lock_irqsave(&port->lock, flags); up->ier =3D 0; @@ -2738,6 +2789,8 @@ serial8250_do_set_termios(struct uart_port *port, str= uct ktermios *termios, /* * Ok, we're now changing the port state. Do it with * interrupts disabled. + * + * Synchronize UART_IER access against the console. */ serial8250_rpm_get(up); spin_lock_irqsave(&port->lock, flags); --=20 2.30.2