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 Suggested-by: Petr Mladek Cc: stable@vger.kernel.org Signed-off-by: Breno Leitao --- 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