From: John Ogness <john.ogness@linutronix.de> To: Petr Mladek <pmladek@suse.com> Cc: Sergey Senozhatsky <senozhatsky@chromium.org>, Steven Rostedt <rostedt@goodmis.org>, Thomas Gleixner <tglx@linutronix.de>, linux-kernel@vger.kernel.org, Helge Deller <deller@gmx.de>, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Javier Martinez Canillas <javierm@redhat.com>, Thomas Zimmermann <tzimmermann@suse.de>, Juergen Gross <jgross@suse.com>, Boris Ostrovsky <boris.ostrovsky@oracle.com>, Tom Rix <trix@redhat.com>, linux-fbdev@vger.kernel.org, dri-devel@lists.freedesktop.org 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 [thread overview] Message-ID: <20221019145600.1282823-39-john.ogness@linutronix.de> (raw) In-Reply-To: <20221019145600.1282823-1-john.ogness@linutronix.de> 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 <john.ogness@linutronix.de> --- 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. -- 2.30.2
WARNING: multiple messages have this Message-ID (diff)
From: John Ogness <john.ogness@linutronix.de> To: Petr Mladek <pmladek@suse.com> Cc: Juergen Gross <jgross@suse.com>, linux-fbdev@vger.kernel.org, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Helge Deller <deller@gmx.de>, linux-kernel@vger.kernel.org, Steven Rostedt <rostedt@goodmis.org>, Javier Martinez Canillas <javierm@redhat.com>, Sergey Senozhatsky <senozhatsky@chromium.org>, dri-devel@lists.freedesktop.org, Thomas Zimmermann <tzimmermann@suse.de>, Tom Rix <trix@redhat.com>, Thomas Gleixner <tglx@linutronix.de>, Boris Ostrovsky <boris.ostrovsky@oracle.com> 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 [thread overview] Message-ID: <20221019145600.1282823-39-john.ogness@linutronix.de> (raw) In-Reply-To: <20221019145600.1282823-1-john.ogness@linutronix.de> 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 <john.ogness@linutronix.de> --- 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. -- 2.30.2
next prev parent reply other threads:[~2022-10-19 15:08 UTC|newest] Thread overview: 151+ messages / expand[flat|nested] mbox.gz Atom feed top 2022-10-19 14:55 [PATCH printk v2 00/38] reduce console_lock scope John Ogness 2022-10-19 14:55 ` John Ogness 2022-10-19 14:55 ` John Ogness 2022-10-19 14:55 ` John Ogness 2022-10-19 14:55 ` [PATCH printk v2 01/38] serial: kgdboc: Lock console list in probe function John Ogness 2022-10-19 15:41 ` Greg Kroah-Hartman 2022-10-24 5:22 ` Sergey Senozhatsky 2022-10-25 0:34 ` Doug Anderson 2022-10-19 14:55 ` [PATCH printk v2 02/38] printk: Convert console_drivers list to hlist John Ogness 2022-10-19 15:44 ` Greg Kroah-Hartman 2022-10-19 21:46 ` John Ogness 2022-10-20 7:43 ` Greg Kroah-Hartman 2022-10-20 12:36 ` Petr Mladek 2022-10-24 5:23 ` Sergey Senozhatsky 2022-10-19 14:55 ` [PATCH printk v2 03/38] printk: Prepare for SRCU console list protection John Ogness 2022-10-19 15:16 ` Miguel Ojeda 2022-10-19 17:12 ` Paul E. McKenney 2022-10-21 8:34 ` Petr Mladek 2022-10-31 13:06 ` John Ogness 2022-10-31 14:09 ` Petr Mladek 2022-10-19 14:55 ` [PATCH printk v2 04/38] printk: introduce console_is_enabled() wrapper John Ogness 2022-10-19 16:01 ` Greg Kroah-Hartman 2022-10-21 8:57 ` Petr Mladek 2022-10-21 9:37 ` Petr Mladek 2022-10-19 14:55 ` [PATCH printk v2 05/38] printk: use console_is_enabled() John Ogness 2022-10-21 9:25 ` Petr Mladek 2022-10-31 15:39 ` John Ogness 2022-10-19 14:55 ` [PATCH printk v2 06/38] tty: nfcon: " John Ogness 2022-10-21 9:55 ` Petr Mladek 2022-10-31 15:59 ` John Ogness 2022-11-01 8:57 ` Petr Mladek 2022-10-19 14:55 ` [PATCH printk v2 07/38] um: kmsg_dump: " John Ogness 2022-10-19 14:55 ` John Ogness 2022-10-21 12:46 ` Petr Mladek 2022-10-21 12:46 ` Petr Mladek 2022-10-19 14:55 ` [PATCH printk v2 08/38] efi: earlycon: " John Ogness 2022-10-19 15:32 ` Ard Biesheuvel 2022-10-21 12:53 ` Petr Mladek 2022-10-19 14:55 ` [PATCH printk v2 09/38] netconsole: " John Ogness 2022-10-21 13:14 ` Petr Mladek 2022-11-04 15:12 ` John Ogness 2022-10-19 14:55 ` [PATCH printk v2 10/38] tty: hvc: " John Ogness 2022-10-19 14:55 ` John Ogness 2022-10-19 16:01 ` Greg Kroah-Hartman 2022-10-19 16:01 ` Greg Kroah-Hartman 2022-10-21 13:22 ` Petr Mladek 2022-10-21 13:22 ` Petr Mladek 2022-10-19 14:55 ` [PATCH printk v2 11/38] tty: serial: earlycon: " John Ogness 2022-10-19 16:01 ` Greg Kroah-Hartman 2022-10-21 13:51 ` Petr Mladek 2022-10-19 14:55 ` [PATCH printk v2 12/38] tty: serial: kgdboc: " John Ogness 2022-10-19 16:00 ` Greg Kroah-Hartman 2022-10-21 14:10 ` Petr Mladek 2022-10-24 22:46 ` Doug Anderson 2022-10-25 0:49 ` Doug Anderson 2022-10-25 11:28 ` John Ogness 2022-11-04 16:23 ` John Ogness 2022-11-07 8:47 ` Petr Mladek 2022-11-07 9:45 ` John Ogness 2022-10-19 14:55 ` [PATCH printk v2 13/38] tty: serial: pic32_uart: " John Ogness 2022-10-19 16:01 ` Greg Kroah-Hartman 2022-10-21 14:11 ` Petr Mladek 2022-10-19 14:55 ` [PATCH printk v2 14/38] tty: serial: samsung_tty: " John Ogness 2022-10-19 14:55 ` John Ogness 2022-10-19 16:00 ` Greg Kroah-Hartman 2022-10-19 16:00 ` Greg Kroah-Hartman 2022-10-21 14:14 ` Petr Mladek 2022-10-21 14:14 ` Petr Mladek 2022-10-19 14:55 ` [PATCH printk v2 15/38] tty: serial: serial_core: " John Ogness 2022-10-19 16:00 ` Greg Kroah-Hartman 2022-10-21 14:14 ` Petr Mladek 2022-10-19 14:55 ` [PATCH printk v2 16/38] tty: serial: xilinx_uartps: " John Ogness 2022-10-19 14:55 ` John Ogness 2022-10-19 16:01 ` Greg Kroah-Hartman 2022-10-19 16:01 ` Greg Kroah-Hartman 2022-10-21 14:23 ` Petr Mladek 2022-10-21 14:23 ` Petr Mladek 2022-10-19 14:55 ` [PATCH printk v2 17/38] tty: tty_io: " John Ogness 2022-10-19 16:00 ` Greg Kroah-Hartman 2022-10-21 14:24 ` Petr Mladek 2022-10-19 14:55 ` [PATCH printk v2 18/38] usb: early: xhci-dbc: " John Ogness 2022-10-19 16:01 ` Greg Kroah-Hartman 2022-10-21 14:27 ` Petr Mladek 2022-10-19 14:55 ` [PATCH printk v2 19/38] kdb: kdb_io: " John Ogness 2022-10-21 14:28 ` Petr Mladek 2022-10-25 0:34 ` Doug Anderson 2022-10-19 14:55 ` [PATCH printk v2 20/38] um: kmsg_dumper: use srcu console list iterator John Ogness 2022-10-19 14:55 ` John Ogness 2022-10-21 14:56 ` Petr Mladek 2022-10-21 14:56 ` Petr Mladek 2022-10-19 14:55 ` [PATCH printk v2 21/38] serial: kgdboc: " John Ogness 2022-10-19 16:02 ` Greg Kroah-Hartman 2022-10-21 15:09 ` Petr Mladek 2022-10-25 0:33 ` Doug Anderson 2022-10-19 14:55 ` [PATCH printk v2 22/38] serial: kgdboc: document console_lock usage John Ogness 2022-10-20 7:42 ` Greg Kroah-Hartman 2022-10-25 0:36 ` Doug Anderson 2022-10-25 10:09 ` Petr Mladek 2022-10-19 14:55 ` [PATCH printk v2 23/38] tty: tty_io: " John Ogness 2022-10-20 7:43 ` Greg Kroah-Hartman 2022-10-25 13:31 ` Petr Mladek 2022-10-19 14:55 ` [PATCH printk v2 24/38] xen: fbfront: use srcu console list iterator John Ogness 2022-10-19 14:55 ` John Ogness 2022-10-25 13:39 ` Petr Mladek 2022-10-25 13:39 ` Petr Mladek 2022-10-19 14:55 ` [PATCH printk v2 25/38] proc: consoles: document console_lock usage John Ogness 2022-10-25 14:40 ` Petr Mladek 2022-10-19 14:55 ` [PATCH printk v2 26/38] kdb: use srcu console list iterator John Ogness 2022-10-25 0:47 ` Doug Anderson 2022-10-25 14:59 ` Petr Mladek 2022-10-19 14:55 ` [PATCH printk v2 27/38] printk: console_flush_all: " John Ogness 2022-10-25 15:17 ` Petr Mladek 2022-11-07 0:00 ` John Ogness 2022-11-07 13:03 ` Petr Mladek 2022-10-19 14:55 ` [PATCH printk v2 28/38] printk: console_unblank: " John Ogness 2022-10-25 15:28 ` Petr Mladek 2022-10-25 15:31 ` Petr Mladek 2022-10-19 14:55 ` [PATCH printk v2 29/38] printk: console_flush_on_panic: " John Ogness 2022-10-25 15:32 ` Petr Mladek 2022-10-19 14:55 ` [PATCH printk v2 30/38] printk: console_device: " John Ogness 2022-10-25 15:35 ` Petr Mladek 2022-10-19 14:55 ` [PATCH printk v2 31/38] printk: register_console: " John Ogness 2022-10-26 8:20 ` Petr Mladek 2022-10-19 14:55 ` [PATCH printk v2 32/38] printk: __pr_flush: " John Ogness 2022-10-26 8:33 ` Petr Mladek 2022-10-19 14:55 ` [PATCH printk v2 33/38] printk: introduce console_list_lock John Ogness 2022-10-20 7:53 ` Greg Kroah-Hartman 2022-10-27 10:09 ` Petr Mladek 2022-10-27 18:50 ` Paul E. McKenney 2022-10-28 18:09 ` Boqun Feng 2022-10-28 18:42 ` Paul E. McKenney 2022-11-07 10:10 ` John Ogness 2022-11-07 16:16 ` Paul E. McKenney 2022-10-19 14:55 ` [PATCH printk v2 34/38] serial: kgdboc: use console_list_lock instead of console_lock John Ogness 2022-10-20 7:52 ` Greg Kroah-Hartman 2022-10-27 10:13 ` Petr Mladek 2022-10-19 14:55 ` [PATCH printk v2 35/38] tty: tty_io: use console_list_lock for list synchronization John Ogness 2022-10-20 7:43 ` Greg Kroah-Hartman 2022-10-27 10:17 ` Petr Mladek 2022-10-19 14:55 ` [PATCH printk v2 36/38] proc: consoles: use console_list_lock for list iteration John Ogness 2022-10-27 12:02 ` Petr Mladek 2022-10-19 14:55 ` [PATCH printk v2 37/38] printk: relieve console_lock of list synchronization duties John Ogness 2022-10-27 12:40 ` Petr Mladek 2022-10-19 14:56 ` John Ogness [this message] 2022-10-19 14:56 ` [PATCH printk v2 38/38] printk, xen: fbfront: create/use safe function for forcing preferred John Ogness 2022-10-27 13:18 ` Petr Mladek 2022-10-27 13:18 ` Petr Mladek 2022-10-27 13:35 ` John Ogness 2022-10-27 13:35 ` John Ogness 2022-10-27 14:27 ` Petr Mladek 2022-10-27 14:27 ` Petr Mladek
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20221019145600.1282823-39-john.ogness@linutronix.de \ --to=john.ogness@linutronix.de \ --cc=boris.ostrovsky@oracle.com \ --cc=deller@gmx.de \ --cc=dri-devel@lists.freedesktop.org \ --cc=gregkh@linuxfoundation.org \ --cc=javierm@redhat.com \ --cc=jgross@suse.com \ --cc=linux-fbdev@vger.kernel.org \ --cc=linux-kernel@vger.kernel.org \ --cc=pmladek@suse.com \ --cc=rostedt@goodmis.org \ --cc=senozhatsky@chromium.org \ --cc=tglx@linutronix.de \ --cc=trix@redhat.com \ --cc=tzimmermann@suse.de \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.