[PATCH 2/2] crash: Flush unsafe consoles before machine_crash_shutdown()
From: Breno Leitao
Date: Mon Nov 02 2026 - 14:43:12 EST
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@xxxxxxxxxxxxx>
Suggested-by: Petr Mladek <pmladek@xxxxxxxx>
Cc: stable@xxxxxxxxxxxxxxx
Signed-off-by: Breno Leitao <leitao@xxxxxxxxxx>
---
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