mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH 0/2] panic: flush unsafe consoles before reboot and kdump
@ 2026-11-02 18:14 Breno Leitao
  2026-11-02 18:14 ` [PATCH 1/2] printk: nbcon: Flush unsafe consoles from printk() in panic Breno Leitao
  2026-11-02 18:14 ` [PATCH 2/2] crash: Flush unsafe consoles before machine_crash_shutdown() Breno Leitao
  0 siblings, 2 replies; 3+ messages in thread
From: Breno Leitao @ 2026-11-02 18:14 UTC (permalink / raw)
  To: Petr Mladek, John Ogness, Kiryl Shutsemau
  Cc: linux-kernel, printk, gustavold, samuelcrossley, ryan.roberts,
	brads, x86, Breno Leitao, kernel-team, stable

Since netconsole moved to NBCON, its messages are lost when the
machine reboots after a panic or boots a crash kernel. netconsole is
a CON_NBCON_ATOMIC_UNSAFE console, and those are only flushed at the
very end of panic(), after both.

Ryan reported this [1], and the fix is based on Petr's suggestions
[2][3]. Patch 1 flushes the unsafe consoles from printk() on the
panic CPU. Patch 2 also flushes them in __crash_kexec(), for an oops
that goes straight to kdump: on x86 that path prints nothing once the
CPU has become the panic CPU.

Tested on x86 with netconsole sending to a receiver: panic reboot,
kdump from sysrq and kdump from an oops all deliver the report, and
the crash kernel boots. Under virtme-ng that is 21 of 21 runs,
against 0 of 21 without the series. On a bare-metal host each case
was run once, and an unpatched kernel delivered nothing in all
three. arm64 is untested.

One case is left open. A printk() inside machine_crash_shutdown()
now also reaches netconsole. On x86 that only happens on errors, but
on a TDX guest tdx_kexec_finish() can pr_err() after it has unmapped
the shared memory a virtio-net netconsole uses. Stopping the printk()
flush once __crash_kexec() has flushed would close it, but would also
drop "Starting crashdump kernel..." and "Bye!" from netconsole on
arm64.

[1] https://lore.kernel.org/all/20260915100140.3631650-1-ryan.roberts@arm.com/
[2] https://lore.kernel.org/all/auNaD8LELWok3LOF@pathway/
[3] https://lore.kernel.org/all/auhl3cdwrHt4Vw7U@pathway/

Signed-off-by: Breno Leitao <leitao@debian.org>
---
Breno Leitao (2):
      printk: nbcon: Flush unsafe consoles from printk() in panic
      crash: Flush unsafe consoles before machine_crash_shutdown()

 include/linux/console.h |  7 ++++---
 include/linux/printk.h  |  5 +++++
 kernel/crash_core.c     |  1 +
 kernel/printk/nbcon.c   | 38 ++++++++++++++++++++++++++++++++------
 4 files changed, 42 insertions(+), 9 deletions(-)
---
base-commit: a39c950806213f6861d00f90729acaaa21f2d95a
change-id: 20261030-panic_unsafe_flush-62939c2c28e7

Best regards,
--  
Breno Leitao <leitao@debian.org>


^ permalink raw reply	[flat|nested] 3+ messages in thread

* [PATCH 1/2] printk: nbcon: Flush unsafe consoles from printk() in panic
  2026-11-02 18:14 [PATCH 0/2] panic: flush unsafe consoles before reboot and kdump Breno Leitao
@ 2026-11-02 18:14 ` Breno Leitao
  2026-11-02 18:14 ` [PATCH 2/2] crash: Flush unsafe consoles before machine_crash_shutdown() Breno Leitao
  1 sibling, 0 replies; 3+ messages in thread
From: Breno Leitao @ 2026-11-02 18:14 UTC (permalink / raw)
  To: Petr Mladek, John Ogness, Kiryl Shutsemau
  Cc: linux-kernel, printk, gustavold, samuelcrossley, ryan.roberts,
	brads, x86, Breno Leitao, kernel-team, stable

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. Before the conversion,
netconsole was a legacy console and printk() wrote each panic message to
it as it was printed.

Flush the unsafe consoles from nbcon_atomic_flush_pending() as well,
right after the safe ones, when it runs on the panic CPU with
oops_in_progress set. Every printk() on the panic CPU then reaches
netconsole again, "Rebooting in" included.

An unsafe write_atomic() that hangs now stops the panic CPU at the first
message, before the other consoles print the rest and before the reboot
or the crash kernel. Getting the messages out is worth that.

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: Petr Mladek <pmladek@suse.com>
Cc: stable@vger.kernel.org
Signed-off-by: Breno Leitao <leitao@debian.org>
---
 include/linux/console.h |  7 ++++---
 kernel/printk/nbcon.c   | 24 ++++++++++++++++++------
 2 files changed, 22 insertions(+), 9 deletions(-)

diff --git a/include/linux/console.h b/include/linux/console.h
index cb8be9ea4a767b..934fe72978b0e5 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 in panic, when unsafe takeovers
+ *			are allowed.
  */
 enum cons_flags {
 	CON_PRINTBUFFER		= BIT(0),
@@ -246,8 +247,8 @@ static_assert(sizeof(struct nbcon_state) <= sizeof(int));
  * @NBCON_PRIO_MAX:		The number of priority levels
  *
  * A higher priority context can takeover the console when it is
- * in the safe state. The final attempt to flush consoles in panic()
- * can be allowed to do so even in an unsafe state (Hope and pray).
+ * in the safe state. The panic CPU can be allowed to do so even in
+ * an unsafe state (Hope and pray).
  */
 enum nbcon_prio {
 	NBCON_PRIO_NONE = 0,
diff --git a/kernel/printk/nbcon.c b/kernel/printk/nbcon.c
index 5f8afaca886650..19fa9f79cac3cb 100644
--- a/kernel/printk/nbcon.c
+++ b/kernel/printk/nbcon.c
@@ -84,8 +84,8 @@
  *        b) Gives up console ownership by clearing the 'prio' field.
  *
  *   3) Unsafe hostile takeover allows to take over the lock even when the
- *      console is an unsafe state. It is used only in panic() by the final
- *      attempt to flush consoles in a try and hope mode.
+ *      console is an unsafe state. It is used only on the panic CPU, in a
+ *      try and hope mode.
  *
  *      Note that separate record buffers are used in panic(). As a result,
  *      the messages can be read and formatted without any risk even after
@@ -543,7 +543,7 @@ static int nbcon_context_try_acquire_handover(struct nbcon_context *ctxt,
  * Acquire the console even in the unsafe state.
  *
  * It can be permitted by setting the 'allow_unsafe_takeover' field only
- * by the final attempt to flush messages in panic().
+ * on the panic CPU.
  *
  * Return:	0 on success. -EPERM when not allowed by the context.
  */
@@ -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,15 @@ static void __nbcon_atomic_flush_pending(u64 stop_seq)
  */
 void nbcon_atomic_flush_pending(void)
 {
-	__nbcon_atomic_flush_pending(prb_next_reserve_seq(prb));
+	u64 stop_seq = prb_next_reserve_seq(prb);
+
+	__nbcon_atomic_flush_pending(stop_seq, false);
+
+	if (panic_on_this_cpu() && oops_in_progress) {
+		panic_nbcon_allow_unsafe_takeover = true;
+		__nbcon_atomic_flush_pending(stop_seq, true);
+		panic_nbcon_allow_unsafe_takeover = false;
+	}
 }
 
 /**
@@ -1701,7 +1713,7 @@ 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;
 }
 

-- 
2.53.0-Meta


^ permalink raw reply	[flat|nested] 3+ messages in thread

* [PATCH 2/2] crash: Flush unsafe consoles before machine_crash_shutdown()
  2026-11-02 18:14 [PATCH 0/2] panic: flush unsafe consoles before reboot and kdump Breno Leitao
  2026-11-02 18:14 ` [PATCH 1/2] printk: nbcon: Flush unsafe consoles from printk() in panic Breno Leitao
@ 2026-11-02 18:14 ` Breno Leitao
  1 sibling, 0 replies; 3+ messages in thread
From: Breno Leitao @ 2026-11-02 18:14 UTC (permalink / raw)
  To: Petr Mladek, John Ogness, Kiryl Shutsemau
  Cc: linux-kernel, printk, gustavold, samuelcrossley, ryan.roberts,
	brads, x86, Breno Leitao, kernel-team, stable

On x86, an oops that goes to kdump never reaches netconsole. oops_end()
calls crash_kexec() after the oops is printed, before this CPU becomes
the panic CPU, so printk() skips the unsafe consoles for the whole
report. Unless something fails, nothing else is printed on the panic CPU
before machine_kexec().

Add nbcon_atomic_unsafe_only_flush(), which flushes only the
CON_NBCON_ATOMIC_UNSAFE consoles and allows unsafe takeovers on them.
Call it in __crash_kexec() before machine_crash_shutdown() tears down
what they may need, such as the shared memory of a TDX guest. As with
the legacy console, the other CPUs are still running at that point,
unless crash_kexec_post_notifiers is set.

When kdump comes from panic(), printk() has already flushed the unsafe
consoles and the call finds nothing pending.

Fixes: 187de7c212e5 ("printk: nbcon: Allow unsafe write_atomic() for panic")
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>
---
 include/linux/printk.h |  5 +++++
 kernel/crash_core.c    |  1 +
 kernel/printk/nbcon.c  | 14 ++++++++++++++
 3 files changed, 20 insertions(+)

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..6580eaa86685a9 100644
--- a/kernel/crash_core.c
+++ b/kernel/crash_core.c
@@ -140,6 +140,7 @@ void __noclone __crash_kexec(struct pt_regs *regs)
 
 			crash_setup_regs(&fixed_regs, regs);
 			crash_save_vmcoreinfo();
+			nbcon_atomic_unsafe_only_flush();
 			machine_crash_shutdown(&fixed_regs);
 			crash_cma_clear_pending_dma();
 			machine_kexec(kexec_crash_image);
diff --git a/kernel/printk/nbcon.c b/kernel/printk/nbcon.c
index 19fa9f79cac3cb..c22175a33ce17e 100644
--- a/kernel/printk/nbcon.c
+++ b/kernel/printk/nbcon.c
@@ -1717,6 +1717,20 @@ void nbcon_atomic_flush_unsafe(void)
 	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. Only effective on the panic CPU.
+ */
+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;
+}
+
 /**
  * nbcon_cpu_emergency_enter - Enter an emergency section where printk()
  *				messages for that CPU are flushed directly

-- 
2.53.0-Meta


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2026-11-02 18:16 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-11-02 18:14 [PATCH 0/2] panic: flush unsafe consoles before reboot and kdump Breno Leitao
2026-11-02 18:14 ` [PATCH 1/2] printk: nbcon: Flush unsafe consoles from printk() in panic Breno Leitao
2026-11-02 18:14 ` [PATCH 2/2] crash: Flush unsafe consoles before machine_crash_shutdown() Breno Leitao

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®