drivers/tty/serial/serial_port.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-)
serial_base_port_shutdown() calls serial_base_port_set_tx(false)
unconditionally. When a TTY hangup occurs on a port that is also a
registered kernel console, this permanently disables the console
transmitter.
uart_hangup() already guards against uart_change_pm(PM_OFF) for console
ports (see the uart_console() check in uart_hangup()). Apply the same
guard in serial_base_port_shutdown(): skip TX-disable if the port is a
registered console.
Without this fix, any path that calls uart_shutdown() on a console port
- including TIOCSCTTY with force=1 (as used by init systems such as
procd) - permanently silences all subsequent kernel console output.
Signed-off-by: Kervin Pursoty <kpursoty@proton.me>
---
drivers/tty/serial/serial_port.c | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/drivers/tty/serial/serial_port.c b/drivers/tty/serial/serial_port.c
--- a/drivers/tty/serial/serial_port.c
+++ b/drivers/tty/serial/serial_port.c
@@ -110,5 +110,14 @@
{
struct serial_port_device *port_dev = port->port_dev;
- serial_base_port_set_tx(port, port_dev, false);
+ /*
+ * Do not disable TX on a console port. When an init system calls
+ * TIOCSCTTY with force=1, the kernel hangs up the previous session,
+ * triggering uart_hangup() -> uart_shutdown() -> here. Stopping TX
+ * kills all kernel console output permanently.
+ * uart_hangup() already skips uart_change_pm(PM_OFF) for consoles
+ * via uart_console(); apply the same guard here.
+ */
+ if (!uart_console(port))
+ serial_base_port_set_tx(port, port_dev, false);
}
static DEFINE_RUNTIME_DEV_PM_OPS(serial_port_pm,
Thanks for your notes. Patch withdrawn.
On Wednesday, 15 April 2026 at 09:01, kpursoty@proton.me <kpursoty@proton.me> wrote:
> serial_base_port_shutdown() calls serial_base_port_set_tx(false)
> unconditionally. When a TTY hangup occurs on a port that is also a
> registered kernel console, this permanently disables the console
> transmitter.
>
> uart_hangup() already guards against uart_change_pm(PM_OFF) for console
> ports (see the uart_console() check in uart_hangup()). Apply the same
> guard in serial_base_port_shutdown(): skip TX-disable if the port is a
> registered console.
>
> Without this fix, any path that calls uart_shutdown() on a console port
> - including TIOCSCTTY with force=1 (as used by init systems such as
> procd) - permanently silences all subsequent kernel console output.
>
> Signed-off-by: Kervin Pursoty <kpursoty@proton.me>
> ---
> drivers/tty/serial/serial_port.c | 11 ++++++++++-
> 1 file changed, 10 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/tty/serial/serial_port.c b/drivers/tty/serial/serial_port.c
> --- a/drivers/tty/serial/serial_port.c
> +++ b/drivers/tty/serial/serial_port.c
> @@ -110,5 +110,14 @@
> {
> struct serial_port_device *port_dev = port->port_dev;
>
> - serial_base_port_set_tx(port, port_dev, false);
> + /*
> + * Do not disable TX on a console port. When an init system calls
> + * TIOCSCTTY with force=1, the kernel hangs up the previous session,
> + * triggering uart_hangup() -> uart_shutdown() -> here. Stopping TX
> + * kills all kernel console output permanently.
> + * uart_hangup() already skips uart_change_pm(PM_OFF) for consoles
> + * via uart_console(); apply the same guard here.
> + */
> + if (!uart_console(port))
> + serial_base_port_set_tx(port, port_dev, false);
> }
>
> static DEFINE_RUNTIME_DEV_PM_OPS(serial_port_pm,
>
© 2016 - 2026 Red Hat, Inc.