From patchwork Wed Oct 19 14:55:46 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Ogness X-Patchwork-Id: 13011966 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 gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 90F28C43217 for ; Wed, 19 Oct 2022 15:09:51 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 5A69610EAF1; Wed, 19 Oct 2022 15:09:49 +0000 (UTC) Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) by gabe.freedesktop.org (Postfix) with ESMTPS id 35AD510EAF1 for ; Wed, 19 Oct 2022 15:09:23 +0000 (UTC) From: John Ogness DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1666191375; 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=yQcHjaE6CQfq7iO6zRmu96wMYI8aMwb9KZsnUEYxyHY=; b=uJxwQf34Ytc+E+xlVFr+QJdkNyrMOfUvwvaZcWKOsw0HPBVGrb4yMLRvikG5fD7cUCCc3C 28HKnPfM+uG1Z5z4L56fxWXyrRIKTZSVZptsjItATwqm3Q4MhzYIPKqCJpyLB7fFVS0j6u /X9PqMg8IxzzFdciI7TDe8A+OYuDmG+ME1toyuS2fFqmqa1hTm+YBUxQV3oCJZHXuqalbQ QU8S/p/3lIK/8LUUToUovSXE4jfY76zMpDU7MTtRzM++2mNnVj7bKvcl8AgTMdYYD4YXz3 z8y5puCaOyxnbNpSsfsdnnyyPts9YXiBFHfz2EsNyXbwpHaTQcRNqZA6iu/ZOw== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1666191375; 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=yQcHjaE6CQfq7iO6zRmu96wMYI8aMwb9KZsnUEYxyHY=; b=FnIygPB0dsrSCCUyaFzWqQi5S8pnwh8nD/V378wLSKMrAbys4FHt9SsFaYaowHj8t+QBgh QwF/uqpaFI+ppICQ== To: Petr Mladek Subject: [PATCH printk v2 24/38] xen: fbfront: use srcu console list iterator Date: Wed, 19 Oct 2022 17:01:46 +0206 Message-Id: <20221019145600.1282823-25-john.ogness@linutronix.de> In-Reply-To: <20221019145600.1282823-1-john.ogness@linutronix.de> References: <20221019145600.1282823-1-john.ogness@linutronix.de> MIME-Version: 1.0 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Juergen Gross , linux-fbdev@vger.kernel.org, Tom Rix , Helge Deller , linux-kernel@vger.kernel.org, Steven Rostedt , Javier Martinez Canillas , Sergey Senozhatsky , dri-devel@lists.freedesktop.org, Thomas Zimmermann , Thomas Gleixner , Boris Ostrovsky Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" Since the console_lock is not being used for anything other than safe console list traversal, use srcu console list iteration instead. Signed-off-by: John Ogness Reviewed-by: Petr Mladek --- drivers/video/fbdev/xen-fbfront.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/video/fbdev/xen-fbfront.c b/drivers/video/fbdev/xen-fbfront.c index 4d2694d904aa..2552c853c6c2 100644 --- a/drivers/video/fbdev/xen-fbfront.c +++ b/drivers/video/fbdev/xen-fbfront.c @@ -500,16 +500,18 @@ static int xenfb_probe(struct xenbus_device *dev, static void xenfb_make_preferred_console(void) { struct console *c; + int cookie; if (console_set_on_cmdline) return; - console_lock(); - for_each_console(c) { + cookie = console_srcu_read_lock(); + for_each_console_srcu(c) { if (!strcmp(c->name, "tty") && c->index == 0) break; } - console_unlock(); + console_srcu_read_unlock(cookie); + if (c) { unregister_console(c); c->flags |= CON_CONSDEV; From patchwork Wed Oct 19 14:56:00 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Ogness X-Patchwork-Id: 13011965 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 gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 3C5E4C433FE for ; Wed, 19 Oct 2022 15:09:37 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 7D53B10E4DE; Wed, 19 Oct 2022 15:09:33 +0000 (UTC) X-Greylist: delayed 791 seconds by postgrey-1.36 at gabe; Wed, 19 Oct 2022 15:09:21 UTC Received: from galois.linutronix.de (Galois.linutronix.de [IPv6:2a0a:51c0:0:12e:550::1]) by gabe.freedesktop.org (Postfix) with ESMTPS id E20BF10E4DE for ; Wed, 19 Oct 2022 15:09:21 +0000 (UTC) From: John Ogness DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1666191382; 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=aXcesGHiS9CJwBLB5AtQkJ+SjPh3MNkbA2I4bHFlwT4=; b=vyVdNsmDCOtZ1td7FZJE2kL0NFcmHJkDeb8tBWR6iDUAHMNtB/gaxUaCu7IOuYDjCtdTGf 7JMy3AFlQHUwJVxxWRF61DKsEUyqZRkxV7auxPl3IWWrfKeqXCbTFP1XCjq4+t36WbX9n3 Lk0u97wao4rNY5seMwaeTD9hMMmwwZAO7FNkBian35LLG7JI5kr+LIiauXac/JHyFLh0oS 0bab60tCRUjG95HHblokpeEUA2qyzG6Wp6FwAKRehYx7odX+BRLntV+unpa7brXAp90riX g0saBHF8isP/h2pPYkiVRR0qX2oN2XOyv2ogU5splu0VZKufFuAm+1ETP7yO7Q== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1666191382; 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=aXcesGHiS9CJwBLB5AtQkJ+SjPh3MNkbA2I4bHFlwT4=; b=3KenGGEQ+2eWZ5r+4AzHNAE//1dUZSpARbtG8UMeJGjl8XQGUV1nPPSymknxmfh1mJh3sK E+W71aY0Z0vk/3Bg== To: Petr Mladek Subject: [PATCH printk v2 38/38] printk, xen: fbfront: create/use safe function for forcing preferred Date: Wed, 19 Oct 2022 17:02:00 +0206 Message-Id: <20221019145600.1282823-39-john.ogness@linutronix.de> In-Reply-To: <20221019145600.1282823-1-john.ogness@linutronix.de> References: <20221019145600.1282823-1-john.ogness@linutronix.de> MIME-Version: 1.0 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Juergen Gross , linux-fbdev@vger.kernel.org, Greg Kroah-Hartman , Helge Deller , linux-kernel@vger.kernel.org, Steven Rostedt , Javier Martinez Canillas , Sergey Senozhatsky , dri-devel@lists.freedesktop.org, Thomas Zimmermann , Tom Rix , Thomas Gleixner , Boris Ostrovsky Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" With commit 9e124fe16ff2("xen: Enable console tty by default in domU if it's not a dummy") a hack was implemented to make sure that the tty console remains the console behind the /dev/console device. The main problem with the hack is that, after getting the console pointer to the tty console, it is assumed the pointer is still valid after releasing the console_sem. This assumption is incorrect and unsafe. Make the hack safe by introducing a new function console_force_preferred() to perform the full operation under the console_list_lock. Signed-off-by: John Ogness --- drivers/video/fbdev/xen-fbfront.c | 8 +--- include/linux/console.h | 1 + kernel/printk/printk.c | 69 +++++++++++++++++++------------ 3 files changed, 46 insertions(+), 32 deletions(-) diff --git a/drivers/video/fbdev/xen-fbfront.c b/drivers/video/fbdev/xen-fbfront.c index 2552c853c6c2..aa362b25a60f 100644 --- a/drivers/video/fbdev/xen-fbfront.c +++ b/drivers/video/fbdev/xen-fbfront.c @@ -512,12 +512,8 @@ static void xenfb_make_preferred_console(void) } console_srcu_read_unlock(cookie); - if (c) { - unregister_console(c); - c->flags |= CON_CONSDEV; - c->flags &= ~CON_PRINTBUFFER; /* don't print again */ - register_console(c); - } + if (c) + console_force_preferred(c); } static int xenfb_resume(struct xenbus_device *dev) diff --git a/include/linux/console.h b/include/linux/console.h index bf1e8136424a..41378b00bbdd 100644 --- a/include/linux/console.h +++ b/include/linux/console.h @@ -235,6 +235,7 @@ enum con_flush_mode { }; extern int add_preferred_console(char *name, int idx, char *options); +extern void console_force_preferred(struct console *c); extern void register_console(struct console *); extern int unregister_console(struct console *); extern void console_lock(void); diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c index 840d581c4b23..9a056a42b8d8 100644 --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c @@ -3207,38 +3207,17 @@ static void try_enable_default_console(struct console *newcon) static int unregister_console_locked(struct console *console); -/* - * The console driver calls this routine during kernel initialization - * to register the console printing procedure with printk() and to - * print any messages that were printed by the kernel before the - * console driver was initialized. - * - * This can happen pretty early during the boot process (because of - * early_printk) - sometimes before setup_arch() completes - be careful - * of what kernel features are used - they may not be initialised yet. - * - * There are two types of consoles - bootconsoles (early_printk) and - * "real" consoles (everything which is not a bootconsole) which are - * handled differently. - * - Any number of bootconsoles can be registered at any time. - * - As soon as a "real" console is registered, all bootconsoles - * will be unregistered automatically. - * - Once a "real" console is registered, any attempt to register a - * bootconsoles will be rejected - */ -void register_console(struct console *newcon) +static void register_console_locked(struct console *newcon) { struct console *con; bool bootcon_enabled = false; bool realcon_enabled = false; int err; - console_list_lock(); - for_each_console(con) { if (WARN(con == newcon, "console '%s%d' already registered\n", con->name, con->index)) { - goto unlock; + return; } if (con->flags & CON_BOOT) @@ -3251,7 +3230,7 @@ void register_console(struct console *newcon) if (newcon->flags & CON_BOOT && realcon_enabled) { pr_info("Too late to register bootconsole %s%d\n", newcon->name, newcon->index); - goto unlock; + return; } /* @@ -3282,7 +3261,7 @@ void register_console(struct console *newcon) /* printk() messages are not printed to the Braille console. */ if (err || newcon->flags & CON_BRL) - goto unlock; + return; /* * If we have a bootconsole, and are switching to a real console, @@ -3346,7 +3325,31 @@ void register_console(struct console *newcon) unregister_console_locked(con); } } -unlock: +} + +/* + * The console driver calls this routine during kernel initialization + * to register the console printing procedure with printk() and to + * print any messages that were printed by the kernel before the + * console driver was initialized. + * + * This can happen pretty early during the boot process (because of + * early_printk) - sometimes before setup_arch() completes - be careful + * of what kernel features are used - they may not be initialised yet. + * + * There are two types of consoles - bootconsoles (early_printk) and + * "real" consoles (everything which is not a bootconsole) which are + * handled differently. + * - Any number of bootconsoles can be registered at any time. + * - As soon as a "real" console is registered, all bootconsoles + * will be unregistered automatically. + * - Once a "real" console is registered, any attempt to register a + * bootconsoles will be rejected + */ +void register_console(struct console *newcon) +{ + console_list_lock(); + register_console_locked(newcon); console_list_unlock(); } EXPORT_SYMBOL(register_console); @@ -3411,6 +3414,20 @@ int unregister_console(struct console *console) } EXPORT_SYMBOL(unregister_console); +void console_force_preferred(struct console *c) +{ + console_list_lock(); + + if (unregister_console_locked(c) == 0) { + c->flags |= CON_CONSDEV; + c->flags &= ~CON_PRINTBUFFER; /* don't print again */ + register_console_locked(c); + } + + console_list_unlock(); +} +EXPORT_SYMBOL(console_force_preferred); + /* * Initialize the console device. This is called *early*, so * we can't necessarily depend on lots of kernel help here.