From nobody Sun Feb 8 03:58:04 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 22C2B12FF69; Wed, 27 Mar 2024 12:22:44 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1711542165; cv=none; b=FOzkLVOMQlfnRBz82LOT4Xg0OdZ8ba5+O0558rCWB9ABsRCTWDaJq0jAuIWGYveMHD5a5YHLFKEjFoR7uoeTekNiJHZF/wRyS0tLIhabb9h3UkR2SGdVhxq/SvYo6pmyRvlisiFD49X0+3o9A/dp59DbJCQArEbmDY0in8mi3AM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1711542165; c=relaxed/simple; bh=mu1QpX12s8RhnKVIQrgvsQdB1NHlixa0oNaX2v8nA20=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=M4951OvcqwfuveOSTkhL1Up8MmUlIgvH460YTv86UiozqXCbDXB2RTNx/WHNaPLqMBP8rWgnx2nZql3dYsrhAIBFJ23MyRpMrtHUV/kqEGBD5NjP7XhEuXI7LpH04+F2X63odNenrLfkVsxCIAEzOUDHBrXujwQ2/5/8UMh514M= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=VTSvbQ0k; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="VTSvbQ0k" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 12809C433F1; Wed, 27 Mar 2024 12:22:43 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1711542164; bh=mu1QpX12s8RhnKVIQrgvsQdB1NHlixa0oNaX2v8nA20=; h=From:To:Cc:Subject:Date:From; b=VTSvbQ0kXWPiCslOXElbqkuxzuiFaa9k98wi2wL5MXuCyRexONxLDyngfWYJdfZfW +50mei+Ye9mKw3B0o551uuXNRnuwgxtUmiHwXlNb68RkwNIyfGFw2MBp2dkKA53PHm y4sKPZxo7pIGHAHu4izCW7o5RKJgzGbVOEjyBoqDXN2T+zSA36GskPWiWrZcFv52Ae WRiJlsgKZqdfos4zMEPT0XtJWGKCER1YmpscFjFCkGXDwA0ER7LAMzXY4LOAQH7imV FXEozY3s61PGrHHUrQeG8703OqJFQnSZOZoeIucF0yGd3koVc+7iMBX1DVdv4UfMgt KfWyJLkw0q3ag== From: Sasha Levin To: stable@vger.kernel.org, pcc@google.com Cc: John Ogness , Greg Kroah-Hartman , linux-kernel@vger.kernel.org, linux-serial@vger.kernel.org Subject: FAILED: Patch "serial: Lock console when calling into driver before registration" failed to apply to 5.4-stable tree Date: Wed, 27 Mar 2024 08:22:39 -0400 Message-ID: <20240327122243.2837897-1-sashal@kernel.org> X-Mailer: git-send-email 2.43.0 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Patchwork-Hint: ignore X-stable: review Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The patch below does not apply to the 5.4-stable tree. If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to . Thanks, Sasha Reviewed-by: John Ogness ------------------ original commit in Linus's tree ------------------ From 801410b26a0e8b8a16f7915b2b55c9528b69ca87 Mon Sep 17 00:00:00 2001 From: Peter Collingbourne Date: Mon, 4 Mar 2024 13:43:49 -0800 Subject: [PATCH] serial: Lock console when calling into driver before registration During the handoff from earlycon to the real console driver, we have two separate drivers operating on the same device concurrently. In the case of the 8250 driver these concurrent accesses cause problems due to the driver's use of banked registers, controlled by LCR.DLAB. It is possible for the setup(), config_port(), pm() and set_mctrl() callbacks to set DLAB, which can cause the earlycon code that intends to access TX to instead access DLL, leading to missed output and corruption on the serial line due to unintended modifications to the baud rate. In particular, for setup() we have: univ8250_console_setup() -> serial8250_console_setup() -> uart_set_options() -> serial8250_set_termios() -> serial8250_do_set_termios() -> serial8250_do_set_divisor() For config_port() we have: serial8250_config_port() -> autoconfig() For pm() we have: serial8250_pm() -> serial8250_do_pm() -> serial8250_set_sleep() For set_mctrl() we have (for some devices): serial8250_set_mctrl() -> omap8250_set_mctrl() -> __omap8250_set_mctrl() To avoid such problems, let's make it so that the console is locked during pre-registration calls to these callbacks, which will prevent the earlycon driver from running concurrently. Remove the partial solution to this problem in the 8250 driver that locked the console only during autoconfig_irq(), as this would result in a deadlock with the new approach. The console continues to be locked during autoconfig_irq() because it can only be called through uart_configure_port(). Although this patch introduces more locking than strictly necessary (and in particular it also locks during the call to rs485_config() which is not affected by this issue as far as I can tell), it follows the principle that it is the responsibility of the generic console code to manage the earlycon handoff by ensuring that earlycon and real console driver code cannot run concurrently, and not the individual drivers. Signed-off-by: Peter Collingbourne Reviewed-by: John Ogness Link: https://linux-review.googlesource.com/id/I7cf8124dcebf8618e6b2ee543fa= 5b25532de55d8 Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20240304214350.501253-1-pcc@google.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_port.c | 6 ------ drivers/tty/serial/serial_core.c | 12 ++++++++++++ kernel/printk/printk.c | 21 ++++++++++++++++++--- 3 files changed, 30 insertions(+), 9 deletions(-) diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/= 8250_port.c index 336a0bd4d172a..fc9dd5d45295d 100644 --- a/drivers/tty/serial/8250/8250_port.c +++ b/drivers/tty/serial/8250/8250_port.c @@ -1325,9 +1325,6 @@ static void autoconfig_irq(struct uart_8250_port *up) inb_p(ICP); } =20 - if (uart_console(port)) - console_lock(); - /* forget possible initially masked and pending IRQ */ probe_irq_off(probe_irq_on()); save_mcr =3D serial8250_in_MCR(up); @@ -1367,9 +1364,6 @@ static void autoconfig_irq(struct uart_8250_port *up) if (port->flags & UPF_FOURPORT) outb_p(save_ICP, ICP); =20 - if (uart_console(port)) - console_unlock(); - port->irq =3D (irq > 0) ? irq : 0; } =20 diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_c= ore.c index d6a58a9e072a1..ff85ebd3a007d 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c @@ -2608,7 +2608,12 @@ uart_configure_port(struct uart_driver *drv, struct = uart_state *state, port->type =3D PORT_UNKNOWN; flags |=3D UART_CONFIG_TYPE; } + /* Synchronize with possible boot console. */ + if (uart_console(port)) + console_lock(); port->ops->config_port(port, flags); + if (uart_console(port)) + console_unlock(); } =20 if (port->type !=3D PORT_UNKNOWN) { @@ -2616,6 +2621,10 @@ uart_configure_port(struct uart_driver *drv, struct = uart_state *state, =20 uart_report_port(drv, port); =20 + /* Synchronize with possible boot console. */ + if (uart_console(port)) + console_lock(); + /* Power up port for set_mctrl() */ uart_change_pm(state, UART_PM_STATE_ON); =20 @@ -2632,6 +2641,9 @@ uart_configure_port(struct uart_driver *drv, struct u= art_state *state, =20 uart_rs485_config(port); =20 + if (uart_console(port)) + console_unlock(); + /* * If this driver supports console, and it hasn't been * successfully registered yet, try to re-register it. diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c index f2444b581e16c..89f2aa2e1172f 100644 --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c @@ -3263,6 +3263,21 @@ static int __init keep_bootcon_setup(char *str) =20 early_param("keep_bootcon", keep_bootcon_setup); =20 +static int console_call_setup(struct console *newcon, char *options) +{ + int err; + + if (!newcon->setup) + return 0; + + /* Synchronize with possible boot console. */ + console_lock(); + err =3D newcon->setup(newcon, options); + console_unlock(); + + return err; +} + /* * This is called by register_console() to try to match * the newly registered console with any of the ones selected @@ -3298,8 +3313,8 @@ static int try_enable_preferred_console(struct consol= e *newcon, if (_braille_register_console(newcon, c)) return 0; =20 - if (newcon->setup && - (err =3D newcon->setup(newcon, c->options)) !=3D 0) + err =3D console_call_setup(newcon, c->options); + if (err) return err; } newcon->flags |=3D CON_ENABLED; @@ -3325,7 +3340,7 @@ static void try_enable_default_console(struct console= *newcon) if (newcon->index < 0) newcon->index =3D 0; =20 - if (newcon->setup && newcon->setup(newcon, NULL) !=3D 0) + if (console_call_setup(newcon, NULL) !=3D 0) return; =20 newcon->flags |=3D CON_ENABLED; --=20 2.43.0