[PATCH 06/19] printk: Introduce register_console_force

Marcos Paulo de Souza
2025-12-27T12:17:45Z

The register_console_force function will register a console even if it
wasn't specified on boot. The new function will act like all consoles
being registered were using the CON_ENABLED flag.

The CON_ENABLED flag will be removed in the following patches and the
drivers that use it will migrate to register_console_force instead.

Signed-off-by: Marcos Paulo de Souza <mpdesouza@suse.com>
---
include/linux/console.h | 1 +
kernel/printk/printk.c | 65 ++++++++++++++++++++++++++++++++-----------------
2 files changed, 43 insertions(+), 23 deletions(-)

diff --git a/include/linux/console.h b/include/linux/console.h
index caf9b0951129..7d374a29a625 100644
--- a/include/linux/console.h
+++ b/include/linux/console.h
@@ -792,6 +792,7 @@ enum con_flush_mode {
extern int add_preferred_console(const char *name, const short idx, char *options);
extern void console_force_preferred_locked(struct console *con);
extern void register_console(struct console *);
+extern void register_console_force(struct console *c);
extern int unregister_console(struct console *);
extern void console_lock(void);
extern int console_trylock(void);
diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
index 85a8b6521d9e..c5c05e4d0a67 100644
--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -3858,7 +3858,7 @@ static int console_call_setup(struct console *newcon, char *options)
* enabled such as netconsole
*/
static int try_enable_preferred_console(struct console *newcon,
- bool user_specified)
+ bool user_specified, bool force)
{
struct console_cmdline *c;
int i, err;
@@ -3896,12 +3896,15 @@ static int try_enable_preferred_console(struct console *newcon,
return 0;
}

+ if (force)
+ newcon->flags |= CON_ENABLED;
+
/*
* Some consoles, such as pstore and netconsole, can be enabled even
* without matching. Accept the pre-enabled consoles only when match()
* and setup() had a chance to be called.
*/
- if (newcon->flags & CON_ENABLED && c->user_specified == user_specified)
+ if (newcon->flags & CON_ENABLED && c->user_specified == user_specified)
return 0;

return -ENOENT;
@@ -4001,26 +4004,11 @@ static u64 get_init_console_seq(struct console *newcon, bool bootcon_registered)

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
+/**
+ * __register_console: Register a new console
+ * @force: Register the console even if not specified on boot
*/
-void register_console(struct console *newcon)
+static void __register_console(struct console *newcon, bool force)
{
bool use_device_lock = (newcon->flags & CON_NBCON) && newcon->write_atomic;
bool bootcon_registered = false;
@@ -4080,11 +4068,11 @@ void register_console(struct console *newcon)
}

/* See if this console matches one we selected on the command line */
- err = try_enable_preferred_console(newcon, true);
+ err = try_enable_preferred_console(newcon, true, force);

/* If not, try to match against the platform default(s) */
if (err == -ENOENT)
- err = try_enable_preferred_console(newcon, false);
+ err = try_enable_preferred_console(newcon, false, force);

/* printk() messages are not printed to the Braille console. */
if (err || newcon->flags & CON_BRL) {
@@ -4185,8 +4173,39 @@ void register_console(struct console *newcon)
unlock:
console_list_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)
+{
+ __register_console(newcon, false);
+}
EXPORT_SYMBOL(register_console);

+
+void register_console_force(struct console *newcon)
+{
+ __register_console(newcon, true);
+}
+EXPORT_SYMBOL(register_console_force);
+
/* Must be called under console_list_lock(). */
static int unregister_console_locked(struct console *console)
{

--
2.52.0