* [PATCH v3 0/4] panic, x86/vmware: Preserve crash logs before kdump
@ 2026-11-09 5:47 Zack Rusin
2026-11-09 5:47 ` [PATCH v3 1/4] panic: Add a platform panic notifier list Zack Rusin
` (3 more replies)
0 siblings, 4 replies; 5+ messages in thread
From: Zack Rusin @ 2026-11-09 5:47 UTC (permalink / raw)
To: Andrew Morton, Petr Mladek, Baoquan He, Mike Rapoport,
Pasha Tatashin, Pratyush Yadav, Dave Young
Cc: Borislav Petkov, Ajay Kaher, Alexey Makhalov, x86, Joel Granados,
Thomas Gleixner, Ingo Molnar, Dave Hansen, H. Peter Anvin,
virtualization, bcm-kernel-feedback-list, linux-kernel,
John Ogness, Steven Rostedt, Sergey Senozhatsky, Kees Cook,
Jonathan Corbet, Bo Gan, Brennan Lamoreaux, kexec, linux-doc,
Guilherme G. Piccoli, Maaz Mombasawala, Shuah Khan, Randy Dunlap,
Stephen Brennan, Michael Kelley, Ian Forbes, Bradley Morgan
This series lets VMware guests copy the end of their kernel log to
the host's vmware.log when they crash, before entering kdump. This
preserves diagnostic information even if the guest cannot save its
own logs or the crash dump fails.
Using the existing panic notifier list for this would require
crash_kexec_post_notifiers=1, which also runs unrelated callbacks
before kdump. Following Petr's suggestion, v3 instead adds a separate
platform panic notifier list for callbacks that need to run early.
It runs before kdump and before stopping the other CPUs. It also
covers fatal oopses that enter kdump without going through panic().
The callbacks run at most once, and the list can be disabled for
debugging with disable_panic_notifiers_platform_list.
crash_kexec_post_notifiers, the existing panic notifiers and the
kmsg dumpers are unchanged.
The VMware log sender is the first user. It uses a preallocated
8 KiB buffer and limits both the transfer size and the number of
retries. Logging is enabled by default in ordinary guests; encrypted
guests must opt in through kernel.vmware_record_panic_msg. The copy
is best-effort: kdump and reboot do not depend on it succeeding.
The separate VMware guest-crash notification, which can cause the
host to terminate the VM, is a kmsg dumper registered late in boot,
so it runs after the built-in log dumpers. It is suppressed while a
crash kernel is loaded.
Changes since v2:
- Replace the pre-kdump list and postponement parameter with the
platform list and a debugging switch to disable it.
- Run the list in vpanic() before the other CPUs are stopped,
instead of just before the kmsg dumpers.
- Correct the sysctl documentation heading.
- Rebase onto v7.4-rc1.
Tested on x86-64 guests on VMware Workstation, ESXi (ordinary,
SEV-SNP and TDX) and QEMU/KVM.
Platform list proposal:
https://lore.kernel.org/r/ateYxCu63pRY9EGq@pathway.suse.cz
v2:
https://lore.kernel.org/r/cover.1790014793.git.zack.rusin@broadcom.com
v1:
https://lore.kernel.org/r/cover.1788414671.git.zack.rusin@broadcom.com
Zack Rusin (4):
panic: Add a platform panic notifier list
x86/vmware: Add a bounded panic log sender
x86/vmware: Add the vmware_record_panic_msg sysctl
x86/vmware: Report guest crashes after kmsg dumpers
.../admin-guide/kernel-parameters.txt | 12 +
Documentation/admin-guide/sysctl/kernel.rst | 20 ++
arch/x86/include/asm/vmware.h | 2 +
arch/x86/kernel/cpu/vmware.c | 250 ++++++++++++++++++
include/linux/panic_notifier.h | 3 +
kernel/crash_core.c | 3 +
kernel/panic.c | 50 ++++
7 files changed, 340 insertions(+)
base-commit: 6628e7d4c6b25c8d18f1345e3a20d21829aae7e4
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH v3 1/4] panic: Add a platform panic notifier list
2026-11-09 5:47 [PATCH v3 0/4] panic, x86/vmware: Preserve crash logs before kdump Zack Rusin
@ 2026-11-09 5:47 ` Zack Rusin
2026-11-09 5:47 ` [PATCH v3 2/4] x86/vmware: Add a bounded panic log sender Zack Rusin
` (2 subsequent siblings)
3 siblings, 0 replies; 5+ messages in thread
From: Zack Rusin @ 2026-11-09 5:47 UTC (permalink / raw)
To: Andrew Morton, Petr Mladek, Baoquan He, Mike Rapoport,
Pasha Tatashin, Pratyush Yadav, Dave Young
Cc: Borislav Petkov, Ajay Kaher, Alexey Makhalov, x86, Joel Granados,
Thomas Gleixner, Ingo Molnar, Dave Hansen, H. Peter Anvin,
virtualization, bcm-kernel-feedback-list, linux-kernel,
John Ogness, Steven Rostedt, Sergey Senozhatsky, Kees Cook,
Jonathan Corbet, Bo Gan, Brennan Lamoreaux, kexec, linux-doc,
Guilherme G. Piccoli, Maaz Mombasawala, Shuah Khan, Randy Dunlap,
Stephen Brennan, Michael Kelley, Ian Forbes, Bradley Morgan
Some platforms set crash_kexec_post_notifiers so their crash handlers
run before kdump. That also runs every other panic notifier and kmsg
dumper before the crash kernel.
Add panic_notifiers_platform_list for platform callbacks that need to
run early and are safe while other CPUs are still running. Call it
from vpanic() before kdump and before stopping the other CPUs,
independently of crash_kexec_post_notifiers.
Also call it from __crash_kexec() after saving the registers, since a
fatal oops can enter kdump without panic(). Run the list at most once,
including when a callback panics.
Add disable_panic_notifiers_platform_list to skip these callbacks
when debugging panic or kdump failures.
Suggested-by: Petr Mladek <pmladek@suse.com>
Link: https://lore.kernel.org/r/ateYxCu63pRY9EGq@pathway.suse.cz
Signed-off-by: Zack Rusin <zack.rusin@broadcom.com>
---
v3: New. Replaces v2 patches 1-3 (pre-kdump list, crash-core call and
panic_pre_kdump_postpone) with the platform list Petr suggested: one
early call in vpanic(), one in __crash_kexec(), a shared guard and a
disable switch. The guard is a plain bool, because calls are
serialized, normally by panic_cpu.
.../admin-guide/kernel-parameters.txt | 12 +++++
include/linux/panic_notifier.h | 3 ++
kernel/crash_core.c | 3 ++
kernel/panic.c | 50 +++++++++++++++++++
4 files changed, 68 insertions(+)
diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index 0b3c140babd9..85ddcad397bf 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -1308,6 +1308,18 @@ Kernel parameters
MTRR settings. This parameter disables that behavior,
possibly causing your machine to run very slowly.
+ disable_panic_notifiers_platform_list=
+ [KNL] Skip the platform panic notifiers. They
+ normally run early in panic(), before kdump, and on
+ crash paths that enter kdump without panic().
+ Intended for debugging panic and kdump failures.
+ Skipping them may lose platform crash handling,
+ such as a copy of the kernel log on the hypervisor.
+ Format: <bool>
+ Default: 0
+ Writable at runtime via
+ /sys/module/kernel/parameters/disable_panic_notifiers_platform_list.
+
disable_timer_pin_1 [X86,EARLY]
Disable PIN 1 of APIC timer
Can be useful to work around chipset bugs.
diff --git a/include/linux/panic_notifier.h b/include/linux/panic_notifier.h
index 41e32483d7a7..1eaf1ffba0bc 100644
--- a/include/linux/panic_notifier.h
+++ b/include/linux/panic_notifier.h
@@ -6,6 +6,9 @@
#include <linux/types.h>
extern struct atomic_notifier_head panic_notifier_list;
+extern struct atomic_notifier_head panic_notifiers_platform_list;
+
+void panic_notify_platform(void);
extern bool crash_kexec_post_notifiers;
diff --git a/kernel/crash_core.c b/kernel/crash_core.c
index d0bd2d0cf899..10b4384294c2 100644
--- a/kernel/crash_core.c
+++ b/kernel/crash_core.c
@@ -23,6 +23,7 @@
#include <linux/objtool.h>
#include <linux/delay.h>
#include <linux/panic.h>
+#include <linux/panic_notifier.h>
#include <asm/page.h>
#include <asm/sections.h>
@@ -139,6 +140,8 @@ void __noclone __crash_kexec(struct pt_regs *regs)
struct pt_regs fixed_regs;
crash_setup_regs(&fixed_regs, regs);
+ /* For crash paths that bypass panic() */
+ panic_notify_platform();
crash_save_vmcoreinfo();
machine_crash_shutdown(&fixed_regs);
crash_cma_clear_pending_dma();
diff --git a/kernel/panic.c b/kernel/panic.c
index 574ee5a12f92..99af1da9d9a5 100644
--- a/kernel/panic.c
+++ b/kernel/panic.c
@@ -62,6 +62,7 @@ static int pause_on_oops;
static int pause_on_oops_flag;
static DEFINE_SPINLOCK(pause_on_oops_lock);
bool crash_kexec_post_notifiers;
+static bool disable_panic_notifiers_platform_list;
int panic_on_warn __read_mostly;
unsigned long panic_on_taint;
bool panic_on_taint_nousertaint = false;
@@ -82,6 +83,10 @@ ATOMIC_NOTIFIER_HEAD(panic_notifier_list);
EXPORT_SYMBOL(panic_notifier_list);
+struct atomic_notifier_head panic_notifiers_platform_list =
+ ATOMIC_NOTIFIER_INIT(panic_notifiers_platform_list);
+EXPORT_SYMBOL_GPL(panic_notifiers_platform_list);
+
static void panic_print_deprecated(void)
{
pr_info_once("Kernel: The 'panic_print' parameter is now deprecated. Please use 'panic_sys_info' and 'panic_console_replay' instead.\n");
@@ -577,6 +582,46 @@ static void panic_other_cpus_shutdown(bool crash_kexec)
void __weak arch_do_panic(void) {}
+/**
+ * panic_notify_platform - run early platform crash callbacks
+ *
+ * panic_notifiers_platform_list is for platform callbacks that need to
+ * run during a crash without requiring crash_kexec_post_notifiers.
+ *
+ * vpanic() calls this before kdump and before stopping the other CPUs.
+ * __crash_kexec() also calls it for crash paths that bypass panic().
+ * Calls must be serialized across CPUs, normally by panic_cpu.
+ *
+ * The list runs at most once, even if a callback panics. Setting
+ * disable_panic_notifiers_platform_list skips the call without marking
+ * the list as run, so a call made after the switch is cleared can still
+ * run it.
+ *
+ * Callbacks receive a notifier value of 0 and NULL data. They must
+ * return NOTIFY_DONE; NOTIFY_STOP would skip the callbacks after them.
+ *
+ * Context: Callbacks run with interrupts disabled, possibly in NMI
+ * context or with the kexec lock held. Other CPUs may still be running.
+ * Callbacks must limit their work and must not sleep, allocate memory,
+ * take locks, wait for other CPUs or invoke kexec.
+ */
+void panic_notify_platform(void)
+{
+ static bool done;
+ unsigned long flags;
+
+ if (READ_ONCE(disable_panic_notifiers_platform_list))
+ return;
+
+ local_irq_save(flags);
+ if (!done) {
+ done = true;
+ atomic_notifier_call_chain(&panic_notifiers_platform_list,
+ 0, NULL);
+ }
+ local_irq_restore(flags);
+}
+
/**
* vpanic - halt the system
* @fmt: The text string to print
@@ -669,6 +714,9 @@ void vpanic(const char *fmt, va_list args)
*/
kgdb_panic(buf);
+ /* Before kdump and before stopping the other CPUs */
+ panic_notify_platform();
+
/*
* If we have crashed and we have a crash kernel loaded let it handle
* everything else.
@@ -1217,6 +1265,8 @@ core_param(panic, panic_timeout, int, 0644);
core_param(pause_on_oops, pause_on_oops, int, 0644);
core_param(panic_on_warn, panic_on_warn, int, 0644);
core_param(crash_kexec_post_notifiers, crash_kexec_post_notifiers, bool, 0644);
+core_param(disable_panic_notifiers_platform_list,
+ disable_panic_notifiers_platform_list, bool, 0644);
core_param(panic_console_replay, panic_console_replay, bool, 0644);
static int panic_print_set(const char *val, const struct kernel_param *kp)
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH v3 2/4] x86/vmware: Add a bounded panic log sender
2026-11-09 5:47 [PATCH v3 0/4] panic, x86/vmware: Preserve crash logs before kdump Zack Rusin
2026-11-09 5:47 ` [PATCH v3 1/4] panic: Add a platform panic notifier list Zack Rusin
@ 2026-11-09 5:47 ` Zack Rusin
2026-11-09 5:47 ` [PATCH v3 3/4] x86/vmware: Add the vmware_record_panic_msg sysctl Zack Rusin
2026-11-09 5:47 ` [PATCH v3 4/4] x86/vmware: Report guest crashes after kmsg dumpers Zack Rusin
3 siblings, 0 replies; 5+ messages in thread
From: Zack Rusin @ 2026-11-09 5:47 UTC (permalink / raw)
To: Andrew Morton, Petr Mladek, Baoquan He, Mike Rapoport,
Pasha Tatashin, Pratyush Yadav, Dave Young
Cc: Borislav Petkov, Ajay Kaher, Alexey Makhalov, x86, Joel Granados,
Thomas Gleixner, Ingo Molnar, Dave Hansen, H. Peter Anvin,
virtualization, bcm-kernel-feedback-list, linux-kernel,
John Ogness, Steven Rostedt, Sergey Senozhatsky, Kees Cook,
Jonathan Corbet, Bo Gan, Brennan Lamoreaux, kexec, linux-doc,
Guilherme G. Piccoli, Maaz Mombasawala, Shuah Khan, Randy Dunlap,
Stephen Brennan, Michael Kelley, Ian Forbes, Bradley Morgan
A VMware guest may be unable to save its own logs after a crash. Copy
the newest kernel log records to the host's vmware.log before kdump,
so they remain available if the capture kernel fails.
Register the sender on the platform panic notifier list and send the
log through the low-bandwidth register interface. Allocate a fixed
8 KiB buffer during early init; 4 KiB can lose useful stack-trace
context. The callback allocates no memory and emits no printk
messages. Limit the transfer to the buffer size and make at most three
attempts, retrying only if a VM checkpoint interrupts the transfer.
Enable logging by default only in guests without memory encryption;
encrypted guests should send their log to the host only when an
administrator opts in. The copy is best-effort diagnostics; kdump does
not depend on it succeeding.
Suggested-by: Michael Kelley <mhklinux@outlook.com>
Link: https://lore.kernel.org/r/SN6PR02MB41574A11D309A0530C63E0FED4842@SN6PR02MB4157.namprd02.prod.outlook.com
Link: https://lore.kernel.org/r/20260309235250.2611115-3-alexey.makhalov@broadcom.com
Co-developed-by: Bo Gan <bo.gan@broadcom.com>
Signed-off-by: Bo Gan <bo.gan@broadcom.com>
Co-developed-by: Alexey Makhalov <alexey.makhalov@broadcom.com>
Signed-off-by: Alexey Makhalov <alexey.makhalov@broadcom.com>
Signed-off-by: Zack Rusin <zack.rusin@broadcom.com>
---
v3: Register on the platform list instead of the pre-kdump list. The
VMware code is otherwise unchanged from v2.
arch/x86/include/asm/vmware.h | 1 +
arch/x86/kernel/cpu/vmware.c | 173 ++++++++++++++++++++++++++++++++++
2 files changed, 174 insertions(+)
diff --git a/arch/x86/include/asm/vmware.h b/arch/x86/include/asm/vmware.h
index 4220dae14a2d..598d4cd448ec 100644
--- a/arch/x86/include/asm/vmware.h
+++ b/arch/x86/include/asm/vmware.h
@@ -57,6 +57,7 @@
#define VMWARE_HYPERVISOR_MAGIC 0x564d5868U
#define VMWARE_CMD_GETVERSION 10
+#define VMWARE_CMD_MESSAGE 30
#define VMWARE_CMD_GETHZ 45
#define VMWARE_CMD_GETVCPU_INFO 68
#define VMWARE_CMD_STEALCLOCK 91
diff --git a/arch/x86/kernel/cpu/vmware.c b/arch/x86/kernel/cpu/vmware.c
index f7ab9e7902cf..0c6f7248a665 100644
--- a/arch/x86/kernel/cpu/vmware.c
+++ b/arch/x86/kernel/cpu/vmware.c
@@ -24,11 +24,16 @@
#include <linux/dmi.h>
#include <linux/init.h>
#include <linux/export.h>
+#include <linux/kmsg_dump.h>
+#include <linux/mm.h>
+#include <linux/panic_notifier.h>
#include <linux/clocksource.h>
#include <linux/cpu.h>
#include <linux/efi.h>
#include <linux/reboot.h>
+#include <linux/sizes.h>
#include <linux/static_call.h>
+#include <linux/wordpart.h>
#include <linux/sched/cputime.h>
#include <asm/div64.h>
#include <asm/x86_init.h>
@@ -52,6 +57,23 @@
#define STEALCLOCK_DISABLED 0
#define STEALCLOCK_ENABLED 1
+#define VMWARE_MSG_STATUS_SUCCESS BIT(16)
+#define VMWARE_MSG_STATUS_CPT BIT(20)
+
+#define VMWARE_RPCI_PROTOCOL 0x49435052
+#define VMWARE_GUESTMSG_COOKIE BIT(31)
+
+#define VMWARE_MSG_TYPE(n) ((n) << 16)
+#define VMWARE_MSG_OPEN VMWARE_MSG_TYPE(0U)
+#define VMWARE_MSG_SENDSIZE VMWARE_MSG_TYPE(1U)
+#define VMWARE_MSG_SENDPAYLOAD VMWARE_MSG_TYPE(2U)
+#define VMWARE_MSG_CLOSE VMWARE_MSG_TYPE(6U)
+
+#define VMWARE_LOG_BUF_SIZE SZ_8K
+#define VMWARE_LOG_ATTEMPTS 3
+#define VMWARE_LOG_PREFIX "log "
+#define VMWARE_LOG_PREFIX_LEN (sizeof(VMWARE_LOG_PREFIX) - 1)
+
struct vmware_steal_time {
union {
u64 clock; /* stolen time counter in units of vtsc */
@@ -64,6 +86,12 @@ struct vmware_steal_time {
u64 reserved[7];
};
+struct vmware_rpc_channel {
+ u16 id;
+ u32 cookie_high;
+ u32 cookie_low;
+};
+
static unsigned long vmware_tsc_khz __ro_after_init;
static u8 vmware_hypercall_mode __ro_after_init;
@@ -142,6 +170,151 @@ static unsigned long vmware_get_tsc_khz(void)
return vmware_tsc_khz;
}
+static int vmware_log_open(struct vmware_rpc_channel *channel)
+{
+ u32 info, id;
+
+ vmware_hypercall6(VMWARE_CMD_MESSAGE | VMWARE_MSG_OPEN,
+ VMWARE_RPCI_PROTOCOL | VMWARE_GUESTMSG_COOKIE, 0,
+ &info, &id, &channel->cookie_high,
+ &channel->cookie_low);
+ if (!(info & VMWARE_MSG_STATUS_SUCCESS))
+ return -EIO;
+
+ channel->id = upper_16_bits(id);
+ return 0;
+}
+
+static int vmware_log_close(const struct vmware_rpc_channel *channel)
+{
+ u32 info;
+
+ vmware_hypercall5(VMWARE_CMD_MESSAGE | VMWARE_MSG_CLOSE, 0,
+ (u32)channel->id << 16, channel->cookie_high,
+ channel->cookie_low, &info);
+
+ return info & VMWARE_MSG_STATUS_SUCCESS ? 0 : -EIO;
+}
+
+static int vmware_log_send_once(const struct vmware_rpc_channel *channel,
+ const char *buffer, size_t length)
+{
+ u32 info;
+
+ vmware_hypercall5(VMWARE_CMD_MESSAGE | VMWARE_MSG_SENDSIZE, length,
+ (u32)channel->id << 16, channel->cookie_high,
+ channel->cookie_low, &info);
+ if (!(info & VMWARE_MSG_STATUS_SUCCESS))
+ return info & VMWARE_MSG_STATUS_CPT ? -EAGAIN : -EIO;
+
+ while (length) {
+ size_t bytes = min_t(size_t, length, sizeof(u32));
+ u32 word = 0;
+
+ memcpy(&word, buffer, bytes);
+ vmware_hypercall5(VMWARE_CMD_MESSAGE | VMWARE_MSG_SENDPAYLOAD,
+ word, (u32)channel->id << 16,
+ channel->cookie_high, channel->cookie_low,
+ &info);
+ if (!(info & VMWARE_MSG_STATUS_SUCCESS))
+ return info & VMWARE_MSG_STATUS_CPT ? -EAGAIN : -EIO;
+
+ buffer += bytes;
+ length -= bytes;
+ }
+
+ return 0;
+}
+
+static int vmware_log_send(const struct vmware_rpc_channel *channel,
+ const char *buffer, size_t length)
+{
+ int attempt, ret;
+
+ for (attempt = 0; attempt < VMWARE_LOG_ATTEMPTS; attempt++) {
+ ret = vmware_log_send_once(channel, buffer, length);
+ if (ret != -EAGAIN)
+ return ret;
+ }
+
+ return -EAGAIN;
+}
+
+static int vmware_log_rpc(const char *buffer, size_t length)
+{
+ struct vmware_rpc_channel channel;
+ int close_ret, ret;
+
+ ret = vmware_log_open(&channel);
+ if (ret)
+ return ret;
+
+ ret = vmware_log_send(&channel, buffer, length);
+ close_ret = vmware_log_close(&channel);
+ if (!ret && close_ret)
+ ret = close_ret;
+
+ return ret;
+}
+
+static struct page *vmware_panic_page;
+static bool vmware_record_panic_msg;
+
+static int vmware_panic_log_notify(struct notifier_block *nb,
+ unsigned long action, void *data)
+{
+ struct kmsg_dump_iter iter;
+ char *buffer = page_address(vmware_panic_page);
+ size_t length = 0;
+
+ if (!READ_ONCE(vmware_record_panic_msg))
+ return NOTIFY_DONE;
+
+ memcpy(buffer, VMWARE_LOG_PREFIX, VMWARE_LOG_PREFIX_LEN);
+ kmsg_dump_rewind(&iter);
+ (void)kmsg_dump_get_buffer(&iter, true,
+ buffer + VMWARE_LOG_PREFIX_LEN,
+ VMWARE_LOG_BUF_SIZE - VMWARE_LOG_PREFIX_LEN,
+ &length);
+ (void)vmware_log_rpc(buffer, length + VMWARE_LOG_PREFIX_LEN);
+
+ return NOTIFY_DONE;
+}
+
+static struct notifier_block vmware_panic_log_nb = {
+ .notifier_call = vmware_panic_log_notify,
+};
+
+static int __init vmware_panic_log_init(void)
+{
+ int ret;
+
+ if (!IS_ENABLED(CONFIG_PRINTK) ||
+ !hypervisor_is_type(X86_HYPER_VMWARE))
+ return 0;
+
+ vmware_record_panic_msg =
+ !cc_platform_has(CC_ATTR_GUEST_MEM_ENCRYPT);
+
+ vmware_panic_page = alloc_pages(GFP_KERNEL,
+ get_order(VMWARE_LOG_BUF_SIZE));
+ if (!vmware_panic_page) {
+ pr_err("failed to allocate panic log buffer\n");
+ return 0;
+ }
+
+ ret = atomic_notifier_chain_register(&panic_notifiers_platform_list,
+ &vmware_panic_log_nb);
+ if (ret) {
+ pr_err("failed to register panic log notifier: %d\n", ret);
+ __free_pages(vmware_panic_page, get_order(VMWARE_LOG_BUF_SIZE));
+ vmware_panic_page = NULL;
+ }
+
+ return 0;
+}
+early_initcall(vmware_panic_log_init);
+
#ifdef CONFIG_PARAVIRT
static struct cyc2ns_data vmware_cyc2ns __ro_after_init;
static bool vmw_sched_clock __initdata = true;
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH v3 3/4] x86/vmware: Add the vmware_record_panic_msg sysctl
2026-11-09 5:47 [PATCH v3 0/4] panic, x86/vmware: Preserve crash logs before kdump Zack Rusin
2026-11-09 5:47 ` [PATCH v3 1/4] panic: Add a platform panic notifier list Zack Rusin
2026-11-09 5:47 ` [PATCH v3 2/4] x86/vmware: Add a bounded panic log sender Zack Rusin
@ 2026-11-09 5:47 ` Zack Rusin
2026-11-09 5:47 ` [PATCH v3 4/4] x86/vmware: Report guest crashes after kmsg dumpers Zack Rusin
3 siblings, 0 replies; 5+ messages in thread
From: Zack Rusin @ 2026-11-09 5:47 UTC (permalink / raw)
To: Andrew Morton, Petr Mladek, Baoquan He, Mike Rapoport,
Pasha Tatashin, Pratyush Yadav, Dave Young
Cc: Borislav Petkov, Ajay Kaher, Alexey Makhalov, x86, Joel Granados,
Thomas Gleixner, Ingo Molnar, Dave Hansen, H. Peter Anvin,
virtualization, bcm-kernel-feedback-list, linux-kernel,
John Ogness, Steven Rostedt, Sergey Senozhatsky, Kees Cook,
Jonathan Corbet, Bo Gan, Brennan Lamoreaux, kexec, linux-doc,
Guilherme G. Piccoli, Maaz Mombasawala, Shuah Khan, Randy Dunlap,
Stephen Brennan, Michael Kelley, Ian Forbes, Bradley Morgan
Allow administrators to disable host log transfer on ordinary guests or
opt in on encrypted guests. Expose the boolean recording policy through
kernel.vmware_record_panic_msg using proc_dobool(), as Joel suggested.
Zero disables recording, nonzero integers enable it, and reads return
0 or 1.
Register the sysctl only after the logger is ready. A registration failure
leaves the internal default in force. Document that the log is sent
before kdump, and that disable_panic_notifiers_platform_list also skips
it.
Link: https://lore.kernel.org/r/4e73yd2ofpdzl6rptzvd74no3hnyfblknoq7wzxlw7f3zjbz7c@srfabx6lsusj
Signed-off-by: Zack Rusin <zack.rusin@broadcom.com>
---
v3: Document the platform list ordering and the disable switch, and fix
the short section-title underline reported by Sashiko. No code change
from v2.
Documentation/admin-guide/sysctl/kernel.rst | 20 ++++++++++++++++++++
arch/x86/kernel/cpu/vmware.c | 15 +++++++++++++++
2 files changed, 35 insertions(+)
diff --git a/Documentation/admin-guide/sysctl/kernel.rst b/Documentation/admin-guide/sysctl/kernel.rst
index 608055d7ccc4..be2d5aa52362 100644
--- a/Documentation/admin-guide/sysctl/kernel.rst
+++ b/Documentation/admin-guide/sysctl/kernel.rst
@@ -1680,6 +1680,26 @@ entry will default to 2 instead of 0.
= =============================================================
+vmware_record_panic_msg
+=======================
+
+Controls whether kmsg data is written to the host's ``vmware.log`` on
+panic. This setting does not control the separate VMware guest-crash
+event. Writing zero disables recording; writing a nonzero integer
+enables it. Reads return 0 or 1.
+
+= ==============================================================
+0 Do not write kmsg data to ``vmware.log``. This is the default
+ for encrypted guests.
+1 Write kmsg data to ``vmware.log``. This is the default for
+ ordinary guests.
+= ==============================================================
+
+The data is written by a platform panic notifier: early in panic,
+before kdump, and also when a fatal oops enters kdump without a panic.
+Setting ``disable_panic_notifiers_platform_list`` skips it as well.
+
+
warn_limit
==========
diff --git a/arch/x86/kernel/cpu/vmware.c b/arch/x86/kernel/cpu/vmware.c
index 0c6f7248a665..8c8b6dd7c3e8 100644
--- a/arch/x86/kernel/cpu/vmware.c
+++ b/arch/x86/kernel/cpu/vmware.c
@@ -33,6 +33,7 @@
#include <linux/reboot.h>
#include <linux/sizes.h>
#include <linux/static_call.h>
+#include <linux/sysctl.h>
#include <linux/wordpart.h>
#include <linux/sched/cputime.h>
#include <asm/div64.h>
@@ -260,6 +261,16 @@ static int vmware_log_rpc(const char *buffer, size_t length)
static struct page *vmware_panic_page;
static bool vmware_record_panic_msg;
+static const struct ctl_table vmware_panic_sysctls[] = {
+ {
+ .procname = "vmware_record_panic_msg",
+ .data = &vmware_record_panic_msg,
+ .maxlen = sizeof(vmware_record_panic_msg),
+ .mode = 0644,
+ .proc_handler = proc_dobool,
+ },
+};
+
static int vmware_panic_log_notify(struct notifier_block *nb,
unsigned long action, void *data)
{
@@ -311,6 +322,10 @@ static int __init vmware_panic_log_init(void)
vmware_panic_page = NULL;
}
+ if (vmware_panic_page && IS_ENABLED(CONFIG_SYSCTL) &&
+ !register_sysctl("kernel", vmware_panic_sysctls))
+ pr_err("failed to register panic log sysctl\n");
+
return 0;
}
early_initcall(vmware_panic_log_init);
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH v3 4/4] x86/vmware: Report guest crashes after kmsg dumpers
2026-11-09 5:47 [PATCH v3 0/4] panic, x86/vmware: Preserve crash logs before kdump Zack Rusin
` (2 preceding siblings ...)
2026-11-09 5:47 ` [PATCH v3 3/4] x86/vmware: Add the vmware_record_panic_msg sysctl Zack Rusin
@ 2026-11-09 5:47 ` Zack Rusin
3 siblings, 0 replies; 5+ messages in thread
From: Zack Rusin @ 2026-11-09 5:47 UTC (permalink / raw)
To: Andrew Morton, Petr Mladek, Baoquan He, Mike Rapoport,
Pasha Tatashin, Pratyush Yadav, Dave Young
Cc: Borislav Petkov, Ajay Kaher, Alexey Makhalov, x86, Joel Granados,
Thomas Gleixner, Ingo Molnar, Dave Hansen, H. Peter Anvin,
virtualization, bcm-kernel-feedback-list, linux-kernel,
John Ogness, Steven Rostedt, Sergey Senozhatsky, Kees Cook,
Jonathan Corbet, Bo Gan, Brennan Lamoreaux, kexec, linux-doc,
Guilherme G. Piccoli, Maaz Mombasawala, Shuah Khan, Randy Dunlap,
Stephen Brennan, Michael Kelley, Ian Forbes, Bradley Morgan
VMware accepts a structured guest-crash event, but a host configured with
backdoor.coredumpOnCrash may terminate the VM before the hypercall
returns. Keep this event separate from the log sender, which runs
earlier in panic.
Register a panic-only kmsg dumper with late_initcall_sync(), after built-in
dumpers registered by then. Skip the event while a crash kernel is loaded
so the host cannot terminate the guest before kdump saves its vmcore.
Issue the event at most once. With CONFIG_PRINTK=n, use a late INT_MIN
panic notifier. An unexpected dumper registration failure with printk
enabled leaves reporting disabled rather than overtaking working dumpers.
Link: https://lore.kernel.org/r/20260309235250.2611115-4-alexey.makhalov@broadcom.com
Co-developed-by: Brennan Lamoreaux <brennan.lamoreaux@broadcom.com>
Signed-off-by: Brennan Lamoreaux <brennan.lamoreaux@broadcom.com>
Co-developed-by: Alexey Makhalov <alexey.makhalov@broadcom.com>
Signed-off-by: Alexey Makhalov <alexey.makhalov@broadcom.com>
Signed-off-by: Zack Rusin <zack.rusin@broadcom.com>
---
v3: Rebase. No code change from v2.
arch/x86/include/asm/vmware.h | 1 +
arch/x86/kernel/cpu/vmware.c | 62 +++++++++++++++++++++++++++++++++++
2 files changed, 63 insertions(+)
diff --git a/arch/x86/include/asm/vmware.h b/arch/x86/include/asm/vmware.h
index 598d4cd448ec..ea2ce5272a00 100644
--- a/arch/x86/include/asm/vmware.h
+++ b/arch/x86/include/asm/vmware.h
@@ -61,6 +61,7 @@
#define VMWARE_CMD_GETHZ 45
#define VMWARE_CMD_GETVCPU_INFO 68
#define VMWARE_CMD_STEALCLOCK 91
+#define VMWARE_CMD_REPORTGUESTCRASH 102
/*
* Hypercall command mask:
* bits [6:0] command, range [0, 127]
diff --git a/arch/x86/kernel/cpu/vmware.c b/arch/x86/kernel/cpu/vmware.c
index 8c8b6dd7c3e8..ead9f50cf89e 100644
--- a/arch/x86/kernel/cpu/vmware.c
+++ b/arch/x86/kernel/cpu/vmware.c
@@ -22,9 +22,12 @@
*/
#include <linux/dmi.h>
+#include <linux/atomic.h>
+#include <linux/crash_core.h>
#include <linux/init.h>
#include <linux/export.h>
#include <linux/kmsg_dump.h>
+#include <linux/limits.h>
#include <linux/mm.h>
#include <linux/panic_notifier.h>
#include <linux/clocksource.h>
@@ -330,6 +333,65 @@ static int __init vmware_panic_log_init(void)
}
early_initcall(vmware_panic_log_init);
+static atomic_t vmware_crash_reported = ATOMIC_INIT(0);
+
+static void vmware_report_guest_crash(void)
+{
+ if (kexec_crash_loaded())
+ return;
+ if (atomic_xchg(&vmware_crash_reported, 1))
+ return;
+
+ vmware_hypercall1(VMWARE_CMD_REPORTGUESTCRASH, 0);
+}
+
+static void vmware_crash_report_dump(struct kmsg_dumper *dumper,
+ struct kmsg_dump_detail *detail)
+{
+ vmware_report_guest_crash();
+}
+
+static struct kmsg_dumper vmware_crash_report_dumper = {
+ .dump = vmware_crash_report_dump,
+ .max_reason = KMSG_DUMP_PANIC,
+};
+
+static int vmware_crash_report_notify(struct notifier_block *nb,
+ unsigned long action, void *data)
+{
+ vmware_report_guest_crash();
+ return NOTIFY_DONE;
+}
+
+static struct notifier_block vmware_crash_report_nb = {
+ .notifier_call = vmware_crash_report_notify,
+ .priority = INT_MIN,
+};
+
+static int __init vmware_crash_report_init(void)
+{
+ int ret;
+
+ if (!hypervisor_is_type(X86_HYPER_VMWARE))
+ return 0;
+
+ ret = kmsg_dump_register(&vmware_crash_report_dumper);
+ if (!ret)
+ return 0;
+ if (IS_ENABLED(CONFIG_PRINTK)) {
+ pr_err("failed to register crash report dumper: %d\n", ret);
+ return 0;
+ }
+
+ ret = atomic_notifier_chain_register(&panic_notifier_list,
+ &vmware_crash_report_nb);
+ if (ret)
+ pr_err("failed to register crash report notifier: %d\n", ret);
+
+ return 0;
+}
+late_initcall_sync(vmware_crash_report_init);
+
#ifdef CONFIG_PARAVIRT
static struct cyc2ns_data vmware_cyc2ns __ro_after_init;
static bool vmw_sched_clock __initdata = true;
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2026-11-09 5:48 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-11-09 5:47 [PATCH v3 0/4] panic, x86/vmware: Preserve crash logs before kdump Zack Rusin
2026-11-09 5:47 ` [PATCH v3 1/4] panic: Add a platform panic notifier list Zack Rusin
2026-11-09 5:47 ` [PATCH v3 2/4] x86/vmware: Add a bounded panic log sender Zack Rusin
2026-11-09 5:47 ` [PATCH v3 3/4] x86/vmware: Add the vmware_record_panic_msg sysctl Zack Rusin
2026-11-09 5:47 ` [PATCH v3 4/4] x86/vmware: Report guest crashes after kmsg dumpers Zack Rusin
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®