From patchwork Mon Feb 26 19:23:26 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Collingbourne X-Patchwork-Id: 206880 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7300:a81b:b0:108:e6aa:91d0 with SMTP id bq27csp2286309dyb; Mon, 26 Feb 2024 11:23:58 -0800 (PST) X-Forwarded-Encrypted: i=3; AJvYcCW9wgCPXDn9Aa1C1GsHT+fv6gJKaQg78m2QfGWXlqjnCHXVudb+5P2ZkTs6zjFv0/TkSdsc9O83oOnGL7I6Nh/iCwa31g== X-Google-Smtp-Source: AGHT+IEBKrNui1bomHTqENY0pxa7fOZEPpZMRuV8kUf8BFOIv7a9eUcoPdApF6VDq3ZyxeUvmzRb X-Received: by 2002:a17:902:d4cb:b0:1dc:8c77:3381 with SMTP id o11-20020a170902d4cb00b001dc8c773381mr7058107plg.14.1708975438712; Mon, 26 Feb 2024 11:23:58 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1708975438; cv=pass; d=google.com; s=arc-20160816; b=EacCdO2mX9pSDP9Da+KN4tlfPaIYV5GFiXNYDP6iflcrHCsKHaH0h6XRQYRRnKEOmx A5vPD2O36jwrT7oimk2n4aHsaD5eqaqchLmdHkgFpbxtavtdLy9SNxDWH4Eem09Nnmlb hPDo42TPXynMAfJ1sRXqgbhODBXZUfW+RuvwEysCAsatnNOonEIf2qkkx+oVZY8vDtjg EaHXnSwoQUOAIlw5Y9QRmuBpkiWkQYra7liWGOzuuBrz+p3oTtsr4vKerW29BgouxCKN rmDHiaTSJJoqtWpVXk7BP7bqDhraBMf2BkzoC5g6DnIivINkmS8wx3+KN4bwN58LAksm uWdg== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=cc:to:from:subject:mime-version:list-unsubscribe:list-subscribe :list-id:precedence:message-id:date:dkim-signature; bh=srrm+S8jUudlxyacmT7eG3M+AguE7ufuIMxy9ow2wbY=; fh=in6oztTsHO4uRgWUtW58qqXvk1AgqaljP1DaBnD3xW0=; b=to0YPe2P8p6Xc25Ll0fQCwps9lCCrUlWDMDzWbHcXfhzueUIQ9iviQPH+ualVKh3u8 v5QU4sJfjRbgfB0JbpcU+8zM8LZ5eeySfsDT/TGo9lDWjSKDSkG2EeeAJdiF3iRYIwM3 k9e6FZ5SvHfj5oTRBM3Ktr7Z9P/XmL/KvTaHum1vVJ8h3Dau1kZA393yjrMH+Ho9sz0J U2gNHNCDISQhw+Rd+Gr0gQ7q0MjnFJ43FcGL/dmMZHidjYRnGFqOr7Ev8H5pvZ4YfXGA HaWItXi6I9zQeQUBE/uXLyMtL1tw5SxafT6UYiL6mHTmmpFQuyUxmKPU9ObHVxV9z2+3 anIQ==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@google.com header.s=20230601 header.b=BGKIAXvq; arc=pass (i=1 spf=pass spfdomain=flex--pcc.bounces.google.com dkim=pass dkdomain=google.com dmarc=pass fromdomain=google.com); spf=pass (google.com: domain of linux-kernel+bounces-82234-ouuuleilei=gmail.com@vger.kernel.org designates 139.178.88.99 as permitted sender) smtp.mailfrom="linux-kernel+bounces-82234-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Received: from sv.mirrors.kernel.org (sv.mirrors.kernel.org. [139.178.88.99]) by mx.google.com with ESMTPS id h11-20020a170902f7cb00b001da1b31fc38si60378plw.497.2024.02.26.11.23.58 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 26 Feb 2024 11:23:58 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-82234-ouuuleilei=gmail.com@vger.kernel.org designates 139.178.88.99 as permitted sender) client-ip=139.178.88.99; Authentication-Results: mx.google.com; dkim=pass header.i=@google.com header.s=20230601 header.b=BGKIAXvq; arc=pass (i=1 spf=pass spfdomain=flex--pcc.bounces.google.com dkim=pass dkdomain=google.com dmarc=pass fromdomain=google.com); spf=pass (google.com: domain of linux-kernel+bounces-82234-ouuuleilei=gmail.com@vger.kernel.org designates 139.178.88.99 as permitted sender) smtp.mailfrom="linux-kernel+bounces-82234-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by sv.mirrors.kernel.org (Postfix) with ESMTPS id 81965298554 for ; Mon, 26 Feb 2024 19:23:58 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 10D2A12FF7B; Mon, 26 Feb 2024 19:23:43 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="BGKIAXvq" Received: from mail-yb1-f201.google.com (mail-yb1-f201.google.com [209.85.219.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 04DDF12F395 for ; Mon, 26 Feb 2024 19:23:37 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.219.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708975419; cv=none; b=mCPxVxmQBPSx9u4TBbSEhHKq5Ppy91VoSgGmjWf5HUhmnrF7XBWeRhAHhtqFFK+CJCcfo0r36V2AMkcDuKFDFUJFJ6OGsWB/P1EImrx6mT71cGgu/hHYCr27upHw/Uirlo1GS+WTeAJwPh5cAzkshHg8QI3qpQcDVnwCJ4L3Vco= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708975419; c=relaxed/simple; bh=RIaUJYfd1turT62O8XqlowDKwrAPQEYnub3MbudaHOc=; h=Date:Message-Id:Mime-Version:Subject:From:To:Cc:Content-Type; b=jrCO7mn0r4N8COXoi7iT24VE7Ny3O3Yd1paixqW7Xc23LZdGLKGce2cOJBCl37cHq/jdwJT0g5VN/W8oABxcrDqyGlxsn8VEndp4VR8tPk50zQz4zQ8tVkIKXWEku67P95SMNyMud8CG5iH8RZlJe17Jgxpjt4XqCn3t5q0ymE0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--pcc.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=BGKIAXvq; arc=none smtp.client-ip=209.85.219.201 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--pcc.bounces.google.com Received: by mail-yb1-f201.google.com with SMTP id 3f1490d57ef6-dcbfe1a42a4so6599252276.2 for ; Mon, 26 Feb 2024 11:23:37 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1708975417; x=1709580217; darn=vger.kernel.org; h=cc:to:from:subject:mime-version:message-id:date:from:to:cc:subject :date:message-id:reply-to; bh=srrm+S8jUudlxyacmT7eG3M+AguE7ufuIMxy9ow2wbY=; b=BGKIAXvq2iHLOk0s5wguMNmoAAVkhDm8x4KWg1aaIS2WowbcZBMuJ6x9bLuiwxvG0l jeG+jLXZnSGZRsZap6bCFnk5p+4PyB+dhSyYE7KIvbU/tAkKX4xeN8eluG5fuXRziXe0 0MDQ59gKJURS0PEMxRP2itj4Oht8GrjDiPDIlgBSzXC+CmcSnOBGop/ndiq0gaJAgiuR sUu+Be8smG8LQCEMuYVtyM46WrXtrEEkO8R0OEB7UCLnGufPKQNW7a6tBIXu+eJu4xYi voxai8+63kOyNkCSWrzFDbVri6DjuGW8dMnWC056EHZSH/NOwJpA+fuBnwA4t0tnCMts COCA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1708975417; x=1709580217; h=cc:to:from:subject:mime-version:message-id:date:x-gm-message-state :from:to:cc:subject:date:message-id:reply-to; bh=srrm+S8jUudlxyacmT7eG3M+AguE7ufuIMxy9ow2wbY=; b=pIR60WD4dGWgyR4B00vnvPl71SD3eS4x0EQALIulS1pOqmXwiU0ws4rWNcPVq92Tlr PhbdgHkd/EZxS8gc9LH9WapQIlymyBLFeytI9I2hTz9U+ZeKJKd56jbEt9S47QoXvwf2 KeIKmVGEnVNg9m/hLIYPXfZ1woqjd19ErI79B0UcnuvmhdpM92e5zfyJn5nNO6UrVBtA PLLqdfI6wtwaDxGklmXHxMLtdLRWINZwqplq9lXvgO+9MxmRkCPxF9mIRWfMVR+N5u9Y F4BhWZfPy25A5JhOYO9yjVgxTkXseltRKEluALLfcoZ+Ms82kDMu4ERvwT0f92iIYbwF 7pIw== X-Forwarded-Encrypted: i=1; AJvYcCWX/VNV4vZuqmwgTeX/JotYYD+J183Q0ozSCX5/cX5REPN4pFQ9t/Bdgk+1hLYNcICW44Nj3vajn+rGBcq6rYotYPUd8tOLcbTIeYgO X-Gm-Message-State: AOJu0Yx8GkTktJmAGPs4MwAX1nlF3cn3e6f/QuCRt1UgS90yeDnsyEih U0hI0CfuVUvM01OkxUtdxll6BLgzdeFOoZvZzU05YtBg0WL9LMYOKS2WJbH7hqyiFQ== X-Received: from pcc-desktop.svl.corp.google.com ([2620:15c:2d3:205:f53b:71ca:7113:2c2b]) (user=pcc job=sendgmr) by 2002:a05:6902:34b:b0:dcc:6065:2b3d with SMTP id e11-20020a056902034b00b00dcc60652b3dmr35640ybs.8.1708975416968; Mon, 26 Feb 2024 11:23:36 -0800 (PST) Date: Mon, 26 Feb 2024 11:23:26 -0800 Message-Id: <20240226192329.3281301-1-pcc@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 X-Mailer: git-send-email 2.44.0.rc1.240.g4c46232300-goog Subject: [PATCH v2] serial: Lock console when calling into driver before registration From: Peter Collingbourne To: Greg Kroah-Hartman , Jiri Slaby , Petr Mladek , Steven Rostedt , John Ogness , Sergey Senozhatsky Cc: Peter Collingbourne , linux-kernel@vger.kernel.org, linux-serial@vger.kernel.org, stable@vger.kernel.org X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1791990629657621289 X-GMAIL-MSGID: 1791990629657621289 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/I7cf8124dcebf8618e6b2ee543fa5b25532de55d8 Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Cc: stable@vger.kernel.org --- 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 8ca061d3bbb9..1d65055dde27 100644 --- a/drivers/tty/serial/8250/8250_port.c +++ b/drivers/tty/serial/8250/8250_port.c @@ -1329,9 +1329,6 @@ static void autoconfig_irq(struct uart_8250_port *up) inb_p(ICP); } - if (uart_console(port)) - console_lock(); - /* forget possible initially masked and pending IRQ */ probe_irq_off(probe_irq_on()); save_mcr = serial8250_in_MCR(up); @@ -1371,9 +1368,6 @@ static void autoconfig_irq(struct uart_8250_port *up) if (port->flags & UPF_FOURPORT) outb_p(save_ICP, ICP); - if (uart_console(port)) - console_unlock(); - port->irq = (irq > 0) ? irq : 0; } diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index d6a58a9e072a..ff85ebd3a007 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 = PORT_UNKNOWN; flags |= 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(); } if (port->type != PORT_UNKNOWN) { @@ -2616,6 +2621,10 @@ uart_configure_port(struct uart_driver *drv, struct uart_state *state, uart_report_port(drv, port); + /* 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); @@ -2632,6 +2641,9 @@ uart_configure_port(struct uart_driver *drv, struct uart_state *state, uart_rs485_config(port); + 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 f2444b581e16..f51e4e5a869d 100644 --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c @@ -3263,6 +3263,21 @@ static int __init keep_bootcon_setup(char *str) early_param("keep_bootcon", keep_bootcon_setup); +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 = 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 console *newcon, if (_braille_register_console(newcon, c)) return 0; - if (newcon->setup && - (err = newcon->setup(newcon, c->options)) != 0) + err = console_call_setup(newcon, c->options); + if (err != 0) return err; } newcon->flags |= CON_ENABLED; @@ -3325,7 +3340,7 @@ static void try_enable_default_console(struct console *newcon) if (newcon->index < 0) newcon->index = 0; - if (newcon->setup && newcon->setup(newcon, NULL) != 0) + if (console_call_setup(newcon, NULL) != 0) return; newcon->flags |= CON_ENABLED;