]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
kdb: Adapt kdb_msg_write to work with NBCON consoles
authorMarcos Paulo de Souza <mpdesouza@suse.com>
Thu, 16 Oct 2025 14:47:58 +0000 (11:47 -0300)
committerPetr Mladek <pmladek@suse.com>
Fri, 24 Oct 2025 10:56:20 +0000 (12:56 +0200)
Function kdb_msg_write was calling con->write for any found console,
but it won't work on NBCON consoles. In this case we should acquire the
ownership of the console using NBCON_PRIO_EMERGENCY, since printing
kdb messages should only be interrupted by a panic.

At this point, the console is required to use the atomic callback. The
console is skipped if the write_atomic callback is not set or if the
context could not be acquired. The validation of NBCON is done by the
console_is_usable helper. The context is released right after
write_atomic finishes.

The oops_in_progress handling is only needed in the legacy consoles,
so it was moved around the con->write callback.

Suggested-by: Petr Mladek <pmladek@suse.com>
Reviewed-by: Petr Mladek <pmladek@suse.com>
Reviewed-by: John Ogness <john.ogness@linutronix.de>
Signed-off-by: Marcos Paulo de Souza <mpdesouza@suse.com>
Link: https://patch.msgid.link/20251016-nbcon-kgdboc-v6-5-866aac60a80e@suse.com
[pmladek@suse.com: Fixed compilation with !CONFIG_PRINTK.]
Signed-off-by: Petr Mladek <pmladek@suse.com>
include/linux/console.h
kernel/debug/kdb/kdb_io.c

index 4585eb8e109ecbbc1df6158cbc6215b03559a389..d17f1f525bec993113c29abca0779e409cb53b35 100644 (file)
@@ -664,7 +664,7 @@ static inline bool nbcon_exit_unsafe(struct nbcon_write_context *wctxt) { return
 static inline void nbcon_reacquire_nobuf(struct nbcon_write_context *wctxt) { }
 static inline bool nbcon_kdb_try_acquire(struct console *con,
                                         struct nbcon_write_context *wctxt) { return false; }
-static inline void nbcon_kdb_release(struct console *con) { }
+static inline void nbcon_kdb_release(struct nbcon_write_context *wctxt) { }
 static inline bool console_is_usable(struct console *con, short flags,
                                     bool use_atomic) { return false; }
 #endif
index b12b9db75c1d8d16dad9eea3d6fece314de21c6b..61c1690058ed135472df78f7cda66b3dff32e2bd 100644 (file)
@@ -589,24 +589,41 @@ static void kdb_msg_write(const char *msg, int msg_len)
         */
        cookie = console_srcu_read_lock();
        for_each_console_srcu(c) {
-               if (!(console_srcu_read_flags(c) & CON_ENABLED))
+               short flags = console_srcu_read_flags(c);
+
+               if (!console_is_usable(c, flags, true))
                        continue;
                if (c == dbg_io_ops->cons)
                        continue;
-               if (!c->write)
-                       continue;
-               /*
-                * Set oops_in_progress to encourage the console drivers to
-                * disregard their internal spin locks: in the current calling
-                * context the risk of deadlock is a bigger problem than risks
-                * due to re-entering the console driver. We operate directly on
-                * oops_in_progress rather than using bust_spinlocks() because
-                * the calls bust_spinlocks() makes on exit are not appropriate
-                * for this calling context.
-                */
-               ++oops_in_progress;
-               c->write(c, msg, msg_len);
-               --oops_in_progress;
+
+               if (flags & CON_NBCON) {
+                       struct nbcon_write_context wctxt = { };
+
+                       /*
+                        * Do not continue if the console is NBCON and the context
+                        * can't be acquired.
+                        */
+                       if (!nbcon_kdb_try_acquire(c, &wctxt))
+                               continue;
+
+                       nbcon_write_context_set_buf(&wctxt, (char *)msg, msg_len);
+
+                       c->write_atomic(c, &wctxt);
+                       nbcon_kdb_release(&wctxt);
+               } else {
+                       /*
+                        * Set oops_in_progress to encourage the console drivers to
+                        * disregard their internal spin locks: in the current calling
+                        * context the risk of deadlock is a bigger problem than risks
+                        * due to re-entering the console driver. We operate directly on
+                        * oops_in_progress rather than using bust_spinlocks() because
+                        * the calls bust_spinlocks() makes on exit are not appropriate
+                        * for this calling context.
+                        */
+                       ++oops_in_progress;
+                       c->write(c, msg, msg_len);
+                       --oops_in_progress;
+               }
                touch_nmi_watchdog();
        }
        console_srcu_read_unlock(cookie);