All of lore.kernel.org
 help / color / mirror / Atom feed
From: Breno Leitao <leitao@debian.org>
To: Petr Mladek <pmladek@suse.com>
Cc: John Ogness <john.ogness@linutronix.de>,
	 Ryan Roberts <ryan.roberts@arm.com>,
	Andrew Morton <akpm@linux-foundation.org>,
	 Steven Rostedt <rostedt@goodmis.org>,
	Sergey Senozhatsky <senozhatsky@chromium.org>,
	 Rio <rioo.tsukatsukii@gmail.com>,
	linux-kernel@vger.kernel.org
Subject: Re: [RFC PATCH v1] panic: Flush unsafe consoles before panic reboot
Date: Fri, 30 Oct 2026 10:56:35 -0700	[thread overview]
Message-ID: <auTaBZlNbpm3jgvb@gmail.com> (raw)
In-Reply-To: <auNaD8LELWok3LOF@pathway>

On Thu, Oct 29, 2026 at 03:37:03PM +0100, Petr Mladek wrote:
> Another question is where to call it. I guess the it should be called
> in two code paths:
> 
>    + __crash_kexec() likely after stopping other CPUs
> 
>     + console_flush_on_panic() after flushing safe nbcon consoles
> 	the safe way

What about something like:


commit de57403441b601af01d92bc03bf0625338d39c80
Author: Breno Leitao <leitao@debian.org>
Date:   Fri Oct 30 10:08:01 2026 -0700

    panic: flush unsafe consoles before reboot and kdump
    
    netconsole registers with CON_NBCON_ATOMIC_UNSAFE since commit
    7eab73b18630 ("netconsole: convert to NBCON console infrastructure"), so
    its write_atomic() only runs from nbcon_atomic_flush_unsafe(). vpanic()
    calls that right before its final busy loop, after emergency_restart()
    and after __crash_kexec().
    
    A panic that reboots (panic_timeout != 0) or boots a crash kernel
    therefore never reaches the netconsole target. Neither does an oops that
    goes to kdump through crash_kexec(), which skips vpanic() entirely.
    Before the conversion, netconsole was a legacy console, flushed by
    console_flush_on_panic() ahead of the reboot.
    
    Add nbcon_atomic_unsafe_only_flush(), which flushes only the
    CON_NBCON_ATOMIC_UNSAFE consoles and allows unsafe takeovers on them.
    Call it on the panic CPU once the other CPUs are stopped, leaving the
    consoles with a safe write_atomic() alone.
    
    In vpanic() it runs after the safe flush, when
    panic_other_cpus_shutdown() has stopped the other CPUs. In
    __crash_kexec() it runs after crash_smp_send_stop() and before
    machine_crash_shutdown(), the order panic() already uses with
    crash_kexec_post_notifiers.
    
    The call does not go into console_flush_on_panic(), because kgdb_panic()
    calls that before the other CPUs are stopped. It does not go after
    machine_crash_shutdown() either: on TDX guests tdx_kexec_finish() zaps
    the shared PTEs there, and netconsole on a virtio NIC would touch that
    memory.
    
    A write_atomic() that hangs now keeps the machine from rebooting or from
    reaching the crash kernel.
    
    Fixes: 187de7c212e5 ("printk: nbcon: Allow unsafe write_atomic() for panic")
    Reported-by: Ryan Roberts <ryan.roberts@arm.com>
    Closes: https://lore.kernel.org/all/20260915100140.3631650-1-ryan.roberts@arm.com/
    Suggested-by: John Ogness <john.ogness@linutronix.de>
    Suggested-by: Petr Mladek <pmladek@suse.com>
    Cc: stable@vger.kernel.org
    Signed-off-by: Breno Leitao <leitao@debian.org>

diff --git a/include/linux/console.h b/include/linux/console.h
index cb8be9ea4a767b..ebfa259633761a 100644
--- a/include/linux/console.h
+++ b/include/linux/console.h
@@ -183,7 +183,8 @@ static inline void con_debug_leave(void) { }
  * @CON_NBCON:		Console can operate outside of the legacy style console_lock
  *			constraints.
  * @CON_NBCON_ATOMIC_UNSAFE: The write_atomic() callback is not safe and is
- *			therefore only used by nbcon_atomic_flush_unsafe().
+ *			therefore only used by nbcon_atomic_flush_unsafe() and
+ *			nbcon_atomic_unsafe_only_flush().
  */
 enum cons_flags {
 	CON_PRINTBUFFER		= BIT(0),
diff --git a/include/linux/printk.h b/include/linux/printk.h
index f594c1266bfd41..95da3904c0d30e 100644
--- a/include/linux/printk.h
+++ b/include/linux/printk.h
@@ -208,6 +208,7 @@ void printk_legacy_allow_panic_sync(void);
 extern bool nbcon_device_try_acquire(struct console *con);
 extern void nbcon_device_release(struct console *con);
 void nbcon_atomic_flush_unsafe(void);
+void nbcon_atomic_unsafe_only_flush(void);
 bool pr_flush(int timeout_ms, bool reset_on_progress);
 #else
 static inline __printf(1, 0)
@@ -322,6 +323,10 @@ static inline void nbcon_atomic_flush_unsafe(void)
 {
 }
 
+static inline void nbcon_atomic_unsafe_only_flush(void)
+{
+}
+
 static inline bool pr_flush(int timeout_ms, bool reset_on_progress)
 {
 	return true;
diff --git a/kernel/crash_core.c b/kernel/crash_core.c
index d0bd2d0cf8990b..d00a8ce5cb618c 100644
--- a/kernel/crash_core.c
+++ b/kernel/crash_core.c
@@ -140,6 +140,13 @@ void __noclone __crash_kexec(struct pt_regs *regs)
 
 			crash_setup_regs(&fixed_regs, regs);
 			crash_save_vmcoreinfo();
+			/*
+			 * Flush the unsafe consoles with the other CPUs
+			 * stopped, before machine_crash_shutdown() tears
+			 * down what they may need.
+			 */
+			crash_smp_send_stop();
+			nbcon_atomic_unsafe_only_flush();
 			machine_crash_shutdown(&fixed_regs);
 			crash_cma_clear_pending_dma();
 			machine_kexec(kexec_crash_image);
diff --git a/kernel/panic.c b/kernel/panic.c
index 91e48d33b7dbbd..e14b1b60828130 100644
--- a/kernel/panic.c
+++ b/kernel/panic.c
@@ -723,6 +723,9 @@ void vpanic(const char *fmt, va_list args)
 		panic_console_replay)
 		console_flush_on_panic(CONSOLE_REPLAY_ALL);
 
+	/* The other CPUs are stopped, flush the unsafe consoles too.
h /tmp/puf_post.sh kerneltest001.31.atn1 6791 atn1a &); (sh
/tmp/puf_post.sh kerneltest005.19.atn2 6792 atn2a &)
/
+	nbcon_atomic_unsafe_only_flush();
+
 	if (!panic_blink)
 		panic_blink = no_blink;
 
diff --git a/kernel/printk/nbcon.c b/kernel/printk/nbcon.c
index 5f8afaca886650..a43143eca1a015 100644
--- a/kernel/printk/nbcon.c
+++ b/kernel/printk/nbcon.c
@@ -1653,8 +1653,9 @@ static void nbcon_atomic_flush_pending_con(struct console *con, u64 stop_seq)
  * __nbcon_atomic_flush_pending - Flush all nbcon consoles using their
  *					write_atomic() callback
  * @stop_seq:			Flush up until this record
+ * @unsafe_only:		Flush only the CON_NBCON_ATOMIC_UNSAFE consoles
  */
-static void __nbcon_atomic_flush_pending(u64 stop_seq)
+static void __nbcon_atomic_flush_pending(u64 stop_seq, bool unsafe_only)
 {
 	struct console *con;
 	int cookie;
@@ -1666,6 +1667,9 @@ static void __nbcon_atomic_flush_pending(u64 stop_seq)
 		if (!(flags & CON_NBCON))
 			continue;
 
+		if (unsafe_only && !(flags & CON_NBCON_ATOMIC_UNSAFE))
+			continue;
+
 		if (!console_is_usable(con, flags, true))
 			continue;
 
@@ -1688,7 +1692,7 @@ static void __nbcon_atomic_flush_pending(u64 stop_seq)
  */
 void nbcon_atomic_flush_pending(void)
 {
-	__nbcon_atomic_flush_pending(prb_next_reserve_seq(prb));
+	__nbcon_atomic_flush_pending(prb_next_reserve_seq(prb), false);
 }
 
 /**
@@ -1701,7 +1705,21 @@ void nbcon_atomic_flush_pending(void)
 void nbcon_atomic_flush_unsafe(void)
 {
 	panic_nbcon_allow_unsafe_takeover = true;
-	__nbcon_atomic_flush_pending(prb_next_reserve_seq(prb));
+	__nbcon_atomic_flush_pending(prb_next_reserve_seq(prb), false);
+	panic_nbcon_allow_unsafe_takeover = false;
+}
+
+/**
+ * nbcon_atomic_unsafe_only_flush - Flush only the CON_NBCON_ATOMIC_UNSAFE
+ *	consoles, allowing unsafe hostile takeovers
+ *
+ * Like nbcon_atomic_flush_unsafe(), but consoles with a safe write_atomic()
+ * are left alone. Meant for the panic CPU once the other CPUs are stopped.
+ */
+void nbcon_atomic_unsafe_only_flush(void)
+{
+	panic_nbcon_allow_unsafe_takeover = true;
+	__nbcon_atomic_flush_pending(prb_next_reserve_seq(prb), true);
 	panic_nbcon_allow_unsafe_takeover = false;
 }
 

  reply	other threads:[~2026-10-30 17:56 UTC|newest]

Thread overview: 29+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-15 10:01 [RFC PATCH v1] panic: Flush unsafe consoles before panic reboot Ryan Roberts
2026-09-15 10:06 ` Ryan Roberts
2026-09-15 18:49   ` Bradley Morgan
2026-09-16  7:44     ` Ryan Roberts
2026-09-16 14:58       ` Bradley Morgan
2026-09-16 13:08 ` Petr Mladek
2026-10-22 20:35   ` Gustavo Luiz Duarte
2026-10-23  7:57   ` John Ogness
2026-10-23 10:36     ` Petr Mladek
2026-10-27 16:12       ` Breno Leitao
2026-10-27 17:43         ` Breno Leitao
2026-10-27 18:01           ` John Ogness
2026-10-28 11:24             ` Breno Leitao
2026-10-28 10:52     ` Breno Leitao
2026-10-28 14:37       ` John Ogness
2026-10-28 21:15         ` Breno Leitao
2026-10-29  9:20           ` John Ogness
2026-10-29 10:58             ` Breno Leitao
2026-10-29 13:53               ` John Ogness
2026-10-29 14:37                 ` Petr Mladek
2026-10-30 17:56                   ` Breno Leitao [this message]
2026-11-02 10:28                     ` Petr Mladek
2026-11-02 13:27                       ` Breno Leitao
2026-11-02 22:22                       ` John Ogness
2026-11-03 13:31                         ` Petr Mladek
2026-11-04 11:18                           ` John Ogness
2026-11-05 16:50                             ` Petr Mladek
2026-11-05 19:01                               ` John Ogness
2026-11-02 22:14                     ` John Ogness

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=auTaBZlNbpm3jgvb@gmail.com \
    --to=leitao@debian.org \
    --cc=akpm@linux-foundation.org \
    --cc=john.ogness@linutronix.de \
    --cc=linux-kernel@vger.kernel.org \
    --cc=pmladek@suse.com \
    --cc=rioo.tsukatsukii@gmail.com \
    --cc=rostedt@goodmis.org \
    --cc=ryan.roberts@arm.com \
    --cc=senozhatsky@chromium.org \
    /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: link
Be 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.