From: Breno Leitao <leitao@debian.org>
To: Alexander Graf <graf@amazon.com>, Mike Rapoport <rppt@kernel.org>,
Pasha Tatashin <pasha.tatashin@soleen.com>,
Pratyush Yadav <pratyush@kernel.org>
Cc: linux-kernel@vger.kernel.org, kexec@lists.infradead.org,
linux-mm@kvack.org, usamaarif642@gmail.com, rmikey@meta.com,
clm@fb.com, riel@surriel.com, Breno Leitao <leitao@debian.org>,
kernel-team@meta.com
Subject: [PATCH v2 1/2] kexec: history: track previous kernel version
Date: Fri, 02 Jan 2026 06:53:23 -0800 [thread overview]
Message-ID: <20260102-kho-v2-1-1747b1a3a1d6@debian.org> (raw)
In-Reply-To: <20260102-kho-v2-0-1747b1a3a1d6@debian.org>
Add CONFIG_KEXEC_HISTORY to store and display the kernel version from
the previous kexec boot.
When enabled, the current kernel's release string is saved to the
"previous-release" property in the KHO device tree before kexec. On
the next boot, if this property exists, the previous kernel version
is retrieved and printed during early boot.
This helps diagnose bugs that only manifest when kexecing from
specific kernel versions, making it easier to correlate crashes with
the kernel that initiated the kexec.
Disabled by default to avoid overhead for users who don't need this
information.
Signed-off-by: Breno Leitao <leitao@debian.org>
---
kernel/Kconfig.kexec | 13 +++++++++++++
kernel/liveupdate/kexec_handover.c | 29 +++++++++++++++++++++++++++++
2 files changed, 42 insertions(+)
diff --git a/kernel/Kconfig.kexec b/kernel/Kconfig.kexec
index 15632358bcf7..b770c68a3800 100644
--- a/kernel/Kconfig.kexec
+++ b/kernel/Kconfig.kexec
@@ -94,6 +94,19 @@ config KEXEC_JUMP
Jump between original kernel and kexeced kernel and invoke
code in physical address mode via KEXEC
+config KEXEC_HISTORY
+ bool "Track kexec kernel history"
+ depends on KEXEC_HANDOVER
+ help
+ When enabled, the kernel will store its release version in the
+ KHO FDT before kexec, and the newly booted kernel will read and
+ print this information during early boot.
+
+ This is useful for debugging and auditing to know which kernel
+ version performed the kexec that booted the current kernel.
+
+ If unsure, say N.
+
config CRASH_DUMP
bool "kernel crash dumps"
default ARCH_DEFAULT_CRASH_DUMP
diff --git a/kernel/liveupdate/kexec_handover.c b/kernel/liveupdate/kexec_handover.c
index 73da00aeaa99..06d99627bb3c 100644
--- a/kernel/liveupdate/kexec_handover.c
+++ b/kernel/liveupdate/kexec_handover.c
@@ -21,6 +21,7 @@
#include <linux/page-isolation.h>
#include <linux/unaligned.h>
#include <linux/vmalloc.h>
+#include <linux/utsname.h>
#include <asm/early_ioremap.h>
@@ -36,6 +37,7 @@
#define KHO_FDT_COMPATIBLE "kho-v1"
#define PROP_PRESERVED_MEMORY_MAP "preserved-memory-map"
#define PROP_SUB_FDT "fdt"
+#define PROP_PREVIOUS_RELEASE "previous-release"
#define KHO_PAGE_MAGIC 0x4b484f50U /* ASCII for 'KHOP' */
@@ -1253,6 +1255,9 @@ bool kho_finalized(void)
struct kho_in {
phys_addr_t fdt_phys;
phys_addr_t scratch_phys;
+#ifdef CONFIG_KEXEC_HISTORY
+ char previous_release[__NEW_UTS_LEN + 1];
+#endif
struct kho_debugfs dbg;
};
@@ -1332,6 +1337,10 @@ static __init int kho_out_fdt_setup(void)
err |= fdt_property_string(root, "compatible", KHO_FDT_COMPATIBLE);
err |= fdt_property(root, PROP_PRESERVED_MEMORY_MAP, &empty_mem_map,
sizeof(empty_mem_map));
+#ifdef CONFIG_KEXEC_HISTORY
+ err |= fdt_property_string(root, PROP_PREVIOUS_RELEASE,
+ init_uts_ns.name.release);
+#endif
err |= fdt_end_node(root);
err |= fdt_finish(root);
@@ -1455,6 +1464,25 @@ void __init kho_memory_init(void)
}
}
+#ifdef CONFIG_KEXEC_HISTORY
+static void __init kho_print_previous_kernel(const void *fdt)
+{
+ const char *prev_release;
+ int len;
+
+ prev_release = fdt_getprop(fdt, 0, PROP_PREVIOUS_RELEASE, &len);
+ if (!prev_release || len <= 0)
+ return;
+
+ strscpy(kho_in.previous_release, prev_release,
+ sizeof(kho_in.previous_release));
+ pr_info("This kernel was kexec'ed from kernel release: %s\n",
+ kho_in.previous_release);
+}
+#else
+static void __init kho_print_previous_kernel(const void *fdt) { }
+#endif
+
void __init kho_populate(phys_addr_t fdt_phys, u64 fdt_len,
phys_addr_t scratch_phys, u64 scratch_len)
{
@@ -1527,6 +1555,7 @@ void __init kho_populate(phys_addr_t fdt_phys, u64 fdt_len,
kho_in.scratch_phys = scratch_phys;
kho_scratch_cnt = scratch_cnt;
pr_info("found kexec handover data.\n");
+ kho_print_previous_kernel(fdt);
out:
if (fdt)
--
2.47.3
next prev parent reply other threads:[~2026-01-02 14:53 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-01-02 14:53 [PATCH v2 0/2] kexec: history: track previous kernel version and kexec boot count Breno Leitao
2026-01-02 14:53 ` Breno Leitao [this message]
2026-01-02 15:02 ` [PATCH v2 1/2] kexec: history: track previous kernel version Usama Arif
2026-01-02 15:14 ` Breno Leitao
2026-01-02 15:33 ` Usama Arif
2026-01-02 16:18 ` Pasha Tatashin
2026-01-02 14:53 ` [PATCH v2 2/2] kexec: history: track kexec boot counter Breno Leitao
2026-01-02 15:09 ` Usama Arif
2026-01-02 15:24 ` Breno Leitao
2026-01-02 15:31 ` Usama Arif
2026-01-02 16:20 ` Pasha Tatashin
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=20260102-kho-v2-1-1747b1a3a1d6@debian.org \
--to=leitao@debian.org \
--cc=clm@fb.com \
--cc=graf@amazon.com \
--cc=kernel-team@meta.com \
--cc=kexec@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=pasha.tatashin@soleen.com \
--cc=pratyush@kernel.org \
--cc=riel@surriel.com \
--cc=rmikey@meta.com \
--cc=rppt@kernel.org \
--cc=usamaarif642@gmail.com \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox