linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 0/2] kexec: history: track previous kernel version and kexec boot count
@ 2026-01-02 14:53 Breno Leitao
  2026-01-02 14:53 ` [PATCH v2 1/2] kexec: history: track previous kernel version Breno Leitao
  2026-01-02 14:53 ` [PATCH v2 2/2] kexec: history: track kexec boot counter Breno Leitao
  0 siblings, 2 replies; 13+ messages in thread
From: Breno Leitao @ 2026-01-02 14:53 UTC (permalink / raw)
  To: Alexander Graf, Mike Rapoport, Pasha Tatashin, Pratyush Yadav
  Cc: linux-kernel, kexec, linux-mm, usamaarif642, rmikey, clm, riel,
	Breno Leitao, kernel-team

Use Kexec Handover (KHO) to pass the previous kernel's version string
and the number of kexec reboots since the last cold boot to the next
kernel, and print it at boot time.

Example
=======
	[    0.000000] Linux version 6.19.0-rc3-upstream-00047-ge5d992347849
	...
        [    0.000000] KHO: This kernel was kexec'ed from kernel release: 6.19.0-rc3-upstream-00048-geda7d9110f99 (kexec count: 3)

Motivation
==========

Bugs that only reproduce when kexecing from specific kernel versions
are difficult to diagnose. These issues occur when a buggy kernel
kexecs into a new kernel, with the bug manifesting only in the second
kernel.

Recent examples include:

 * eb2266312507 ("x86/boot: Fix page table access in 5-level to 4-level
   paging transition")
 * 77d48d39e991 ("efistub/tpm: Use ACPI reclaim memory for event log to
   avoid corruption")
 * 64b45dd46e15 ("x86/efi: skip memattr table on kexec boot")

As kexec-based reboots become more common, these version-dependent bugs
are appearing more frequently. At scale, correlating crashes to the
previous kernel version is challenging, especially when issues only
occur in specific transition scenarios.

Some bugs manifest only after multiple consecutive kexec reboots.
Tracking the kexec count helps identify these cases (this metric is
already used by live update sub-system).

KHO provides a reliable mechanism to pass information between kernels.
By carrying the previous kernel's release string and kexec count
forward, we can print this context at boot time to aid debugging.

Signed-off-by: Breno Leitao <leitao@debian.org>
---
Changes from v1 to RFC
- Track the number of kexecs since cold boot (Pasha)
- Change the printk() order compared to KHO
- Rewording of the commit summary
- Link to RFC: https://patch.msgid.link/20251230-kho-v1-1-4d795a24da9e@debian.org

---
Breno Leitao (2):
      kexec: history: track previous kernel version
      kexec: history: track kexec boot counter

 kernel/Kconfig.kexec               | 13 ++++++++++
 kernel/liveupdate/kexec_handover.c | 50 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 63 insertions(+)
---
base-commit: 7620f9ccfabbdaf07620381264d8b8d91412542f
change-id: 20251230-kho-7707e8a2ef1e

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



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

* [PATCH v2 1/2] kexec: history: track previous kernel version
  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
  2026-01-02 15:02   ` Usama Arif
                     ` (2 more replies)
  2026-01-02 14:53 ` [PATCH v2 2/2] kexec: history: track kexec boot counter Breno Leitao
  1 sibling, 3 replies; 13+ messages in thread
From: Breno Leitao @ 2026-01-02 14:53 UTC (permalink / raw)
  To: Alexander Graf, Mike Rapoport, Pasha Tatashin, Pratyush Yadav
  Cc: linux-kernel, kexec, linux-mm, usamaarif642, rmikey, clm, riel,
	Breno Leitao, kernel-team

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



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

* [PATCH v2 2/2] kexec: history: track kexec boot counter
  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 ` [PATCH v2 1/2] kexec: history: track previous kernel version Breno Leitao
@ 2026-01-02 14:53 ` Breno Leitao
  2026-01-02 15:09   ` Usama Arif
                     ` (2 more replies)
  1 sibling, 3 replies; 13+ messages in thread
From: Breno Leitao @ 2026-01-02 14:53 UTC (permalink / raw)
  To: Alexander Graf, Mike Rapoport, Pasha Tatashin, Pratyush Yadav
  Cc: linux-kernel, kexec, linux-mm, usamaarif642, rmikey, clm, riel,
	Breno Leitao, kernel-team

Track and display the number of kexec boots since the last cold reboot
when CONFIG_KEXEC_HISTORY is enabled.

This extends the previous kernel release tracking feature by adding
a counter that increments with each kexec boot. The counter provides
visibility into the kexec chain depth, which is useful for understanding
boot history in production environments.

Add a new property, "kexec-count" in KHO FDT alongside the existing
"previous-release" property. The counter is:

 - Initialized to 0 when kho_in is instantiated.
 - Incremented by 1 on each subsequent kexec.
 - Printed alongside the previous kernel release version.

The counter is stored as a 32-bit unsigned integer in FDT format and is
only active when CONFIG_KEXEC_HISTORY is enabled.

Signed-off-by: Breno Leitao <leitao@debian.org>
Suggested-by: Pasha Tatashin <pasha.tatashin@soleen.com>
---
 kernel/liveupdate/kexec_handover.c | 25 +++++++++++++++++++++++--
 1 file changed, 23 insertions(+), 2 deletions(-)

diff --git a/kernel/liveupdate/kexec_handover.c b/kernel/liveupdate/kexec_handover.c
index 06d99627bb3c..fe5a2c5c4c86 100644
--- a/kernel/liveupdate/kexec_handover.c
+++ b/kernel/liveupdate/kexec_handover.c
@@ -38,6 +38,7 @@
 #define PROP_PRESERVED_MEMORY_MAP "preserved-memory-map"
 #define PROP_SUB_FDT "fdt"
 #define PROP_PREVIOUS_RELEASE "previous-release"
+#define PROP_KEXEC_COUNT "kexec-count"
 
 #define KHO_PAGE_MAGIC 0x4b484f50U /* ASCII for 'KHOP' */
 
@@ -1257,6 +1258,7 @@ struct kho_in {
 	phys_addr_t scratch_phys;
 #ifdef CONFIG_KEXEC_HISTORY
 	char previous_release[__NEW_UTS_LEN + 1];
+	u32 kexec_count;
 #endif
 	struct kho_debugfs dbg;
 };
@@ -1330,6 +1332,9 @@ static __init int kho_out_fdt_setup(void)
 	void *root = kho_out.fdt;
 	u64 empty_mem_map = 0;
 	int err;
+#ifdef CONFIG_KEXEC_HISTORY
+	u32 kexec_count;
+#endif
 
 	err = fdt_create(root, PAGE_SIZE);
 	err |= fdt_finish_reservemap(root);
@@ -1340,6 +1345,10 @@ static __init int kho_out_fdt_setup(void)
 #ifdef CONFIG_KEXEC_HISTORY
 	err |= fdt_property_string(root, PROP_PREVIOUS_RELEASE,
 				   init_uts_ns.name.release);
+	/* kho_in.kexec_count is set to 0 on cold boot */
+	kexec_count = cpu_to_fdt32(kho_in.kexec_count + 1);
+	err |= fdt_property(root, PROP_KEXEC_COUNT, &kexec_count,
+			    sizeof(kexec_count));
 #endif
 	err |= fdt_end_node(root);
 	err |= fdt_finish(root);
@@ -1468,6 +1477,7 @@ void __init kho_memory_init(void)
 static void __init kho_print_previous_kernel(const void *fdt)
 {
 	const char *prev_release;
+	const u32 *count_ptr;
 	int len;
 
 	prev_release = fdt_getprop(fdt, 0, PROP_PREVIOUS_RELEASE, &len);
@@ -1476,8 +1486,19 @@ static void __init kho_print_previous_kernel(const void *fdt)
 
 	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);
+
+	/* Read the kexec count from the previous kernel */
+	count_ptr = fdt_getprop(fdt, 0, PROP_KEXEC_COUNT, &len);
+	if (WARN_ON_ONCE(!count_ptr || len <= 0))
+		/*
+		 * PROP_KEXEC_COUNT should exist if PROP_PREVIOUS_RELEASE
+		 * exists.
+		 */
+		return;
+	kho_in.kexec_count = fdt32_to_cpu(*count_ptr);
+
+	pr_info("This kernel was kexec'ed from kernel release: %s (kexec count: %u)\n",
+		kho_in.previous_release, kho_in.kexec_count);
 }
 #else
 static void __init kho_print_previous_kernel(const void *fdt) { }

-- 
2.47.3



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

* Re: [PATCH v2 1/2] kexec: history: track previous kernel version
  2026-01-02 14:53 ` [PATCH v2 1/2] kexec: history: track previous kernel version Breno Leitao
@ 2026-01-02 15:02   ` Usama Arif
  2026-01-02 15:14     ` Breno Leitao
  2026-01-02 16:18   ` Pasha Tatashin
  2026-01-02 20:17   ` Pratyush Yadav
  2 siblings, 1 reply; 13+ messages in thread
From: Usama Arif @ 2026-01-02 15:02 UTC (permalink / raw)
  To: Breno Leitao, Alexander Graf, Mike Rapoport, Pasha Tatashin,
	Pratyush Yadav
  Cc: linux-kernel, kexec, linux-mm, rmikey, clm, riel, kernel-team



On 02/01/2026 17:53, Breno Leitao wrote:
> 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.
> +


I think we should make this default if KHO is enabled, i.e. not have a Kconfig
option for this. The cost of storing the char array is negligable.

>  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);

Maybe s/release/version everywhere? It might not be a release, but no strong opinion.

> +}
> +#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)
> 



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

* Re: [PATCH v2 2/2] kexec: history: track kexec boot counter
  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 16:20   ` Pasha Tatashin
  2026-01-02 20:23   ` Pratyush Yadav
  2 siblings, 1 reply; 13+ messages in thread
From: Usama Arif @ 2026-01-02 15:09 UTC (permalink / raw)
  To: Breno Leitao, Alexander Graf, Mike Rapoport, Pasha Tatashin,
	Pratyush Yadav
  Cc: linux-kernel, kexec, linux-mm, rmikey, clm, riel, kernel-team



On 02/01/2026 17:53, Breno Leitao wrote:
> Track and display the number of kexec boots since the last cold reboot
> when CONFIG_KEXEC_HISTORY is enabled.
> 
> This extends the previous kernel release tracking feature by adding
> a counter that increments with each kexec boot. The counter provides
> visibility into the kexec chain depth, which is useful for understanding
> boot history in production environments.
> 
> Add a new property, "kexec-count" in KHO FDT alongside the existing
> "previous-release" property. The counter is:
> 
>  - Initialized to 0 when kho_in is instantiated.
>  - Incremented by 1 on each subsequent kexec.
>  - Printed alongside the previous kernel release version.
> 
> The counter is stored as a 32-bit unsigned integer in FDT format and is
> only active when CONFIG_KEXEC_HISTORY is enabled.
> 
> Signed-off-by: Breno Leitao <leitao@debian.org>
> Suggested-by: Pasha Tatashin <pasha.tatashin@soleen.com>
> ---
>  kernel/liveupdate/kexec_handover.c | 25 +++++++++++++++++++++++--
>  1 file changed, 23 insertions(+), 2 deletions(-)
> 
> diff --git a/kernel/liveupdate/kexec_handover.c b/kernel/liveupdate/kexec_handover.c
> index 06d99627bb3c..fe5a2c5c4c86 100644
> --- a/kernel/liveupdate/kexec_handover.c
> +++ b/kernel/liveupdate/kexec_handover.c
> @@ -38,6 +38,7 @@
>  #define PROP_PRESERVED_MEMORY_MAP "preserved-memory-map"
>  #define PROP_SUB_FDT "fdt"
>  #define PROP_PREVIOUS_RELEASE "previous-release"
> +#define PROP_KEXEC_COUNT "kexec-count"
>  
>  #define KHO_PAGE_MAGIC 0x4b484f50U /* ASCII for 'KHOP' */
>  
> @@ -1257,6 +1258,7 @@ struct kho_in {
>  	phys_addr_t scratch_phys;
>  #ifdef CONFIG_KEXEC_HISTORY
>  	char previous_release[__NEW_UTS_LEN + 1];
> +	u32 kexec_count;
>  #endif
>  	struct kho_debugfs dbg;
>  };
> @@ -1330,6 +1332,9 @@ static __init int kho_out_fdt_setup(void)
>  	void *root = kho_out.fdt;
>  	u64 empty_mem_map = 0;
>  	int err;
> +#ifdef CONFIG_KEXEC_HISTORY
> +	u32 kexec_count;
> +#endif
>  
>  	err = fdt_create(root, PAGE_SIZE);
>  	err |= fdt_finish_reservemap(root);
> @@ -1340,6 +1345,10 @@ static __init int kho_out_fdt_setup(void)
>  #ifdef CONFIG_KEXEC_HISTORY
>  	err |= fdt_property_string(root, PROP_PREVIOUS_RELEASE,
>  				   init_uts_ns.name.release);
> +	/* kho_in.kexec_count is set to 0 on cold boot */
> +	kexec_count = cpu_to_fdt32(kho_in.kexec_count + 1);

Should this be kexec_count = cpu_to_fdt32(kho_in.kexec_count) + 1; ?

> +	err |= fdt_property(root, PROP_KEXEC_COUNT, &kexec_count,
> +			    sizeof(kexec_count));
>  #endif
>  	err |= fdt_end_node(root);
>  	err |= fdt_finish(root);
> @@ -1468,6 +1477,7 @@ void __init kho_memory_init(void)
>  static void __init kho_print_previous_kernel(const void *fdt)
>  {
>  	const char *prev_release;
> +	const u32 *count_ptr;
>  	int len;
>  
>  	prev_release = fdt_getprop(fdt, 0, PROP_PREVIOUS_RELEASE, &len);
> @@ -1476,8 +1486,19 @@ static void __init kho_print_previous_kernel(const void *fdt)
>  
>  	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);
> +
> +	/* Read the kexec count from the previous kernel */
> +	count_ptr = fdt_getprop(fdt, 0, PROP_KEXEC_COUNT, &len);
> +	if (WARN_ON_ONCE(!count_ptr || len <= 0))
> +		/*
> +		 * PROP_KEXEC_COUNT should exist if PROP_PREVIOUS_RELEASE
> +		 * exists.
> +		 */
> +		return;
> +	kho_in.kexec_count = fdt32_to_cpu(*count_ptr);
> +
> +	pr_info("This kernel was kexec'ed from kernel release: %s (kexec count: %u)\n",
> +		kho_in.previous_release, kho_in.kexec_count);
>  }
>  #else
>  static void __init kho_print_previous_kernel(const void *fdt) { }
> 



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

* Re: [PATCH v2 1/2] kexec: history: track previous kernel version
  2026-01-02 15:02   ` Usama Arif
@ 2026-01-02 15:14     ` Breno Leitao
  2026-01-02 15:33       ` Usama Arif
  0 siblings, 1 reply; 13+ messages in thread
From: Breno Leitao @ 2026-01-02 15:14 UTC (permalink / raw)
  To: Usama Arif
  Cc: Alexander Graf, Mike Rapoport, Pasha Tatashin, Pratyush Yadav,
	linux-kernel, kexec, linux-mm, rmikey, clm, riel, kernel-team

Hello Usama,

On Fri, Jan 02, 2026 at 06:02:39PM +0300, Usama Arif wrote:
> On 02/01/2026 17:53, Breno Leitao wrote:
> I think we should make this default if KHO is enabled, i.e. not have a Kconfig
> option for this. The cost of storing the char array is negligable.

Sure, I can get it enabled by default once KHO gets enabled. Thanks for
the feedback.

> > +	pr_info("This kernel was kexec'ed from kernel release: %s\n",
> > +		kho_in.previous_release);
> 
> Maybe s/release/version everywhere? It might not be a release, but no strong opinion.

As I understand, in the kernel parlance, "version" is something
different from "release", and what we want here is "release". Here is an
example of uname, which also matches with kernel source code and UTS.

  # uname --kernel-version
  #1 SMP Mon Nov 17 07:00:42 PST 2025

  # uname --kernel-release
  6.16.1-0_gc0739ee5037a

Thanks for the review,
--breno


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

* Re: [PATCH v2 2/2] kexec: history: track kexec boot counter
  2026-01-02 15:09   ` Usama Arif
@ 2026-01-02 15:24     ` Breno Leitao
  2026-01-02 15:31       ` Usama Arif
  0 siblings, 1 reply; 13+ messages in thread
From: Breno Leitao @ 2026-01-02 15:24 UTC (permalink / raw)
  To: Usama Arif
  Cc: Alexander Graf, Mike Rapoport, Pasha Tatashin, Pratyush Yadav,
	linux-kernel, kexec, linux-mm, rmikey, clm, riel, kernel-team

Hello Usama,

On Fri, Jan 02, 2026 at 06:09:57PM +0300, Usama Arif wrote:
> 
> On 02/01/2026 17:53, Breno Leitao wrote:
> > Track and display the number of kexec boots since the last cold reboot
> > when CONFIG_KEXEC_HISTORY is enabled.
> > 
> > This extends the previous kernel release tracking feature by adding
> > a counter that increments with each kexec boot. The counter provides
> > visibility into the kexec chain depth, which is useful for understanding
> > boot history in production environments.
> > 
> > Add a new property, "kexec-count" in KHO FDT alongside the existing
> > "previous-release" property. The counter is:
> > 
> >  - Initialized to 0 when kho_in is instantiated.
> >  - Incremented by 1 on each subsequent kexec.
> >  - Printed alongside the previous kernel release version.
> > 
> > The counter is stored as a 32-bit unsigned integer in FDT format and is
> > only active when CONFIG_KEXEC_HISTORY is enabled.
> > 
> > Signed-off-by: Breno Leitao <leitao@debian.org>
> > Suggested-by: Pasha Tatashin <pasha.tatashin@soleen.com>
> > ---
> >  kernel/liveupdate/kexec_handover.c | 25 +++++++++++++++++++++++--
> >  1 file changed, 23 insertions(+), 2 deletions(-)
> > 
> > diff --git a/kernel/liveupdate/kexec_handover.c b/kernel/liveupdate/kexec_handover.c
> > index 06d99627bb3c..fe5a2c5c4c86 100644
> > --- a/kernel/liveupdate/kexec_handover.c
> > +++ b/kernel/liveupdate/kexec_handover.c
> > @@ -38,6 +38,7 @@
> >  #define PROP_PRESERVED_MEMORY_MAP "preserved-memory-map"
> >  #define PROP_SUB_FDT "fdt"
> >  #define PROP_PREVIOUS_RELEASE "previous-release"
> > +#define PROP_KEXEC_COUNT "kexec-count"
> >  
> >  #define KHO_PAGE_MAGIC 0x4b484f50U /* ASCII for 'KHOP' */
> >  
> > @@ -1257,6 +1258,7 @@ struct kho_in {
> >  	phys_addr_t scratch_phys;
> >  #ifdef CONFIG_KEXEC_HISTORY
> >  	char previous_release[__NEW_UTS_LEN + 1];
> > +	u32 kexec_count;
> >  #endif
> >  	struct kho_debugfs dbg;
> >  };
> > @@ -1330,6 +1332,9 @@ static __init int kho_out_fdt_setup(void)
> >  	void *root = kho_out.fdt;
> >  	u64 empty_mem_map = 0;
> >  	int err;
> > +#ifdef CONFIG_KEXEC_HISTORY
> > +	u32 kexec_count;
> > +#endif
> >  
> >  	err = fdt_create(root, PAGE_SIZE);
> >  	err |= fdt_finish_reservemap(root);
> > @@ -1340,6 +1345,10 @@ static __init int kho_out_fdt_setup(void)
> >  #ifdef CONFIG_KEXEC_HISTORY
> >  	err |= fdt_property_string(root, PROP_PREVIOUS_RELEASE,
> >  				   init_uts_ns.name.release);
> > +	/* kho_in.kexec_count is set to 0 on cold boot */
> > +	kexec_count = cpu_to_fdt32(kho_in.kexec_count + 1);
> 
> Should this be kexec_count = cpu_to_fdt32(kho_in.kexec_count) + 1; ?

I don't think so. Basically we want to increment the counter in native
endianess and then convert to the Big Endian (FDT/DT are big endian
AFAIK) and then store (line below) to the DT.

If we convert to big endian and then sum 1, it will mess with the
result. 

> +    err |= fdt_property(root, PROP_KEXEC_COUNT, &kexec_count,
> > +                sizeof(kexec_count));

Thanks for the review,
--breno


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

* Re: [PATCH v2 2/2] kexec: history: track kexec boot counter
  2026-01-02 15:24     ` Breno Leitao
@ 2026-01-02 15:31       ` Usama Arif
  0 siblings, 0 replies; 13+ messages in thread
From: Usama Arif @ 2026-01-02 15:31 UTC (permalink / raw)
  To: Breno Leitao
  Cc: Alexander Graf, Mike Rapoport, Pasha Tatashin, Pratyush Yadav,
	linux-kernel, kexec, linux-mm, rmikey, clm, riel, kernel-team



On 02/01/2026 18:24, Breno Leitao wrote:
> Hello Usama,
> 
> On Fri, Jan 02, 2026 at 06:09:57PM +0300, Usama Arif wrote:
>>
>> On 02/01/2026 17:53, Breno Leitao wrote:
>>> Track and display the number of kexec boots since the last cold reboot
>>> when CONFIG_KEXEC_HISTORY is enabled.
>>>
>>> This extends the previous kernel release tracking feature by adding
>>> a counter that increments with each kexec boot. The counter provides
>>> visibility into the kexec chain depth, which is useful for understanding
>>> boot history in production environments.
>>>
>>> Add a new property, "kexec-count" in KHO FDT alongside the existing
>>> "previous-release" property. The counter is:
>>>
>>>  - Initialized to 0 when kho_in is instantiated.
>>>  - Incremented by 1 on each subsequent kexec.
>>>  - Printed alongside the previous kernel release version.
>>>
>>> The counter is stored as a 32-bit unsigned integer in FDT format and is
>>> only active when CONFIG_KEXEC_HISTORY is enabled.
>>>
>>> Signed-off-by: Breno Leitao <leitao@debian.org>
>>> Suggested-by: Pasha Tatashin <pasha.tatashin@soleen.com>
>>> ---
>>>  kernel/liveupdate/kexec_handover.c | 25 +++++++++++++++++++++++--
>>>  1 file changed, 23 insertions(+), 2 deletions(-)
>>>
>>> diff --git a/kernel/liveupdate/kexec_handover.c b/kernel/liveupdate/kexec_handover.c
>>> index 06d99627bb3c..fe5a2c5c4c86 100644
>>> --- a/kernel/liveupdate/kexec_handover.c
>>> +++ b/kernel/liveupdate/kexec_handover.c
>>> @@ -38,6 +38,7 @@
>>>  #define PROP_PRESERVED_MEMORY_MAP "preserved-memory-map"
>>>  #define PROP_SUB_FDT "fdt"
>>>  #define PROP_PREVIOUS_RELEASE "previous-release"
>>> +#define PROP_KEXEC_COUNT "kexec-count"
>>>  
>>>  #define KHO_PAGE_MAGIC 0x4b484f50U /* ASCII for 'KHOP' */
>>>  
>>> @@ -1257,6 +1258,7 @@ struct kho_in {
>>>  	phys_addr_t scratch_phys;
>>>  #ifdef CONFIG_KEXEC_HISTORY
>>>  	char previous_release[__NEW_UTS_LEN + 1];
>>> +	u32 kexec_count;
>>>  #endif
>>>  	struct kho_debugfs dbg;
>>>  };
>>> @@ -1330,6 +1332,9 @@ static __init int kho_out_fdt_setup(void)
>>>  	void *root = kho_out.fdt;
>>>  	u64 empty_mem_map = 0;
>>>  	int err;
>>> +#ifdef CONFIG_KEXEC_HISTORY
>>> +	u32 kexec_count;
>>> +#endif
>>>  
>>>  	err = fdt_create(root, PAGE_SIZE);
>>>  	err |= fdt_finish_reservemap(root);
>>> @@ -1340,6 +1345,10 @@ static __init int kho_out_fdt_setup(void)
>>>  #ifdef CONFIG_KEXEC_HISTORY
>>>  	err |= fdt_property_string(root, PROP_PREVIOUS_RELEASE,
>>>  				   init_uts_ns.name.release);
>>> +	/* kho_in.kexec_count is set to 0 on cold boot */
>>> +	kexec_count = cpu_to_fdt32(kho_in.kexec_count + 1);
>>
>> Should this be kexec_count = cpu_to_fdt32(kho_in.kexec_count) + 1; ?
> 
> I don't think so. Basically we want to increment the counter in native
> endianess and then convert to the Big Endian (FDT/DT are big endian
> AFAIK) and then store (line below) to the DT.
> 
> If we convert to big endian and then sum 1, it will mess with the
> result. 

ack, Thanks for explaining, I didnt think of endianess!

> 
>> +    err |= fdt_property(root, PROP_KEXEC_COUNT, &kexec_count,
>>> +                sizeof(kexec_count));
> 
> Thanks for the review,
> --breno



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

* Re: [PATCH v2 1/2] kexec: history: track previous kernel version
  2026-01-02 15:14     ` Breno Leitao
@ 2026-01-02 15:33       ` Usama Arif
  0 siblings, 0 replies; 13+ messages in thread
From: Usama Arif @ 2026-01-02 15:33 UTC (permalink / raw)
  To: Breno Leitao
  Cc: Alexander Graf, Mike Rapoport, Pasha Tatashin, Pratyush Yadav,
	linux-kernel, kexec, linux-mm, rmikey, clm, riel, kernel-team



On 02/01/2026 18:14, Breno Leitao wrote:
> Hello Usama,
> 
> On Fri, Jan 02, 2026 at 06:02:39PM +0300, Usama Arif wrote:
>> On 02/01/2026 17:53, Breno Leitao wrote:
>> I think we should make this default if KHO is enabled, i.e. not have a Kconfig
>> option for this. The cost of storing the char array is negligable.
> 
> Sure, I can get it enabled by default once KHO gets enabled. Thanks for
> the feedback.
> 
>>> +	pr_info("This kernel was kexec'ed from kernel release: %s\n",
>>> +		kho_in.previous_release);
>>
>> Maybe s/release/version everywhere? It might not be a release, but no strong opinion.
> 
> As I understand, in the kernel parlance, "version" is something
> different from "release", and what we want here is "release". Here is an
> example of uname, which also matches with kernel source code and UTS.
> 
>   # uname --kernel-version
>   #1 SMP Mon Nov 17 07:00:42 PST 2025
> 
>   # uname --kernel-release
>   6.16.1-0_gc0739ee5037a
>

ack



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

* Re: [PATCH v2 1/2] kexec: history: track previous kernel version
  2026-01-02 14:53 ` [PATCH v2 1/2] kexec: history: track previous kernel version Breno Leitao
  2026-01-02 15:02   ` Usama Arif
@ 2026-01-02 16:18   ` Pasha Tatashin
  2026-01-02 20:17   ` Pratyush Yadav
  2 siblings, 0 replies; 13+ messages in thread
From: Pasha Tatashin @ 2026-01-02 16:18 UTC (permalink / raw)
  To: Breno Leitao
  Cc: Alexander Graf, Mike Rapoport, Pratyush Yadav, linux-kernel,
	kexec, linux-mm, usamaarif642, rmikey, clm, riel, kernel-team

On Fri, Jan 2, 2026 at 9:53 AM Breno Leitao <leitao@debian.org> wrote:
>
> Add CONFIG_KEXEC_HISTORY to store and display the kernel version from
> the previous kexec boot.

I do not think we need a config. Let's just enable this by default, as
I suggested in RFC.

>
> 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);

May be reduce the message slightly:
i.e. "kexec from: %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");

This message is not needed if the previous kernel version is always printed.

> +       kho_print_previous_kernel(fdt);
>
>  out:
>         if (fdt)
>
> --
> 2.47.3
>


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

* Re: [PATCH v2 2/2] kexec: history: track kexec boot counter
  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 16:20   ` Pasha Tatashin
  2026-01-02 20:23   ` Pratyush Yadav
  2 siblings, 0 replies; 13+ messages in thread
From: Pasha Tatashin @ 2026-01-02 16:20 UTC (permalink / raw)
  To: Breno Leitao
  Cc: Alexander Graf, Mike Rapoport, Pratyush Yadav, linux-kernel,
	kexec, linux-mm, usamaarif642, rmikey, clm, riel, kernel-team

On Fri, Jan 2, 2026 at 9:53 AM Breno Leitao <leitao@debian.org> wrote:
>
> Track and display the number of kexec boots since the last cold reboot
> when CONFIG_KEXEC_HISTORY is enabled.
>
> This extends the previous kernel release tracking feature by adding
> a counter that increments with each kexec boot. The counter provides
> visibility into the kexec chain depth, which is useful for understanding
> boot history in production environments.
>
> Add a new property, "kexec-count" in KHO FDT alongside the existing
> "previous-release" property. The counter is:
>
>  - Initialized to 0 when kho_in is instantiated.
>  - Incremented by 1 on each subsequent kexec.
>  - Printed alongside the previous kernel release version.
>
> The counter is stored as a 32-bit unsigned integer in FDT format and is
> only active when CONFIG_KEXEC_HISTORY is enabled.
>
> Signed-off-by: Breno Leitao <leitao@debian.org>
> Suggested-by: Pasha Tatashin <pasha.tatashin@soleen.com>
> ---
>  kernel/liveupdate/kexec_handover.c | 25 +++++++++++++++++++++++--
>  1 file changed, 23 insertions(+), 2 deletions(-)
>
> diff --git a/kernel/liveupdate/kexec_handover.c b/kernel/liveupdate/kexec_handover.c
> index 06d99627bb3c..fe5a2c5c4c86 100644
> --- a/kernel/liveupdate/kexec_handover.c
> +++ b/kernel/liveupdate/kexec_handover.c
> @@ -38,6 +38,7 @@
>  #define PROP_PRESERVED_MEMORY_MAP "preserved-memory-map"
>  #define PROP_SUB_FDT "fdt"
>  #define PROP_PREVIOUS_RELEASE "previous-release"
> +#define PROP_KEXEC_COUNT "kexec-count"
>
>  #define KHO_PAGE_MAGIC 0x4b484f50U /* ASCII for 'KHOP' */
>
> @@ -1257,6 +1258,7 @@ struct kho_in {
>         phys_addr_t scratch_phys;
>  #ifdef CONFIG_KEXEC_HISTORY
>         char previous_release[__NEW_UTS_LEN + 1];
> +       u32 kexec_count;
>  #endif
>         struct kho_debugfs dbg;
>  };
> @@ -1330,6 +1332,9 @@ static __init int kho_out_fdt_setup(void)
>         void *root = kho_out.fdt;
>         u64 empty_mem_map = 0;
>         int err;
> +#ifdef CONFIG_KEXEC_HISTORY
> +       u32 kexec_count;
> +#endif
>
>         err = fdt_create(root, PAGE_SIZE);
>         err |= fdt_finish_reservemap(root);
> @@ -1340,6 +1345,10 @@ static __init int kho_out_fdt_setup(void)
>  #ifdef CONFIG_KEXEC_HISTORY
>         err |= fdt_property_string(root, PROP_PREVIOUS_RELEASE,
>                                    init_uts_ns.name.release);
> +       /* kho_in.kexec_count is set to 0 on cold boot */
> +       kexec_count = cpu_to_fdt32(kho_in.kexec_count + 1);

For KHO preserved data we use native endiness, so do not bother with
cpu_to_fdt32.

> +       err |= fdt_property(root, PROP_KEXEC_COUNT, &kexec_count,
> +                           sizeof(kexec_count));
>  #endif
>         err |= fdt_end_node(root);
>         err |= fdt_finish(root);
> @@ -1468,6 +1477,7 @@ void __init kho_memory_init(void)
>  static void __init kho_print_previous_kernel(const void *fdt)
>  {
>         const char *prev_release;
> +       const u32 *count_ptr;
>         int len;
>
>         prev_release = fdt_getprop(fdt, 0, PROP_PREVIOUS_RELEASE, &len);
> @@ -1476,8 +1486,19 @@ static void __init kho_print_previous_kernel(const void *fdt)
>
>         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);
> +
> +       /* Read the kexec count from the previous kernel */
> +       count_ptr = fdt_getprop(fdt, 0, PROP_KEXEC_COUNT, &len);
> +       if (WARN_ON_ONCE(!count_ptr || len <= 0))

This function is called only once anway.

> +               /*
> +                * PROP_KEXEC_COUNT should exist if PROP_PREVIOUS_RELEASE
> +                * exists.
> +                */
> +               return;
> +       kho_in.kexec_count = fdt32_to_cpu(*count_ptr);
> +
> +       pr_info("This kernel was kexec'ed from kernel release: %s (kexec count: %u)\n",
> +               kho_in.previous_release, kho_in.kexec_count);
>  }
>  #else
>  static void __init kho_print_previous_kernel(const void *fdt) { }
>
> --
> 2.47.3
>


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

* Re: [PATCH v2 1/2] kexec: history: track previous kernel version
  2026-01-02 14:53 ` [PATCH v2 1/2] kexec: history: track previous kernel version Breno Leitao
  2026-01-02 15:02   ` Usama Arif
  2026-01-02 16:18   ` Pasha Tatashin
@ 2026-01-02 20:17   ` Pratyush Yadav
  2 siblings, 0 replies; 13+ messages in thread
From: Pratyush Yadav @ 2026-01-02 20:17 UTC (permalink / raw)
  To: Breno Leitao
  Cc: Alexander Graf, Mike Rapoport, Pasha Tatashin, Pratyush Yadav,
	linux-kernel, kexec, linux-mm, usamaarif642, rmikey, clm, riel,
	kernel-team


> Subject: [PATCH v2 1/2] kexec: history: track previous kernel version

Nit: please use the prefix "kho: " for KHO patches.

On Fri, Jan 02 2026, Breno Leitao wrote:

> 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.

Why can't you use journalctl to figure out which kernel was running
previously?

For example, you can do:

	$ journalctl --list-boots
	-2 a1d93be939b64ac4b7b26aa003bfdb93 Wed 2025-12-24 21:34:22 CET  Thu 2025-12-25 02:04:07 CET
	-1 dbbedcf8fff54d5990c6f2a6399cfce1 Fri 2025-12-26 11:46:23 CET  Fri 2025-12-26 11:46:54 CET
	 0 d002d51c28e748d9a7c6c8cdd391aa73 Fri 2025-12-26 17:40:52 CET  Fri 2026-01-02 21:12:09 CET
	[...]

	$ journalctl -k -b -1

This will show you the full logs of the previous boot, or the one
before, and so on. And when you're debugging, you'd likely want to view
previous boot logs anyway.

Everything you add to the KHO FDT is ABI. While we do have some
flexibility in changing the ABI, I'd rather not add something that can
easily be queried by existing userspace tools.

>
> Disabled by default to avoid overhead for users who don't need this
> information.
>
> Signed-off-by: Breno Leitao <leitao@debian.org>
[...]

-- 
Regards,
Pratyush Yadav


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

* Re: [PATCH v2 2/2] kexec: history: track kexec boot counter
  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 16:20   ` Pasha Tatashin
@ 2026-01-02 20:23   ` Pratyush Yadav
  2 siblings, 0 replies; 13+ messages in thread
From: Pratyush Yadav @ 2026-01-02 20:23 UTC (permalink / raw)
  To: Breno Leitao
  Cc: Alexander Graf, Mike Rapoport, Pasha Tatashin, Pratyush Yadav,
	linux-kernel, kexec, linux-mm, usamaarif642, rmikey, clm, riel,
	kernel-team

On Fri, Jan 02 2026, Breno Leitao wrote:

> Track and display the number of kexec boots since the last cold reboot

Nit: this does not track kexec boots, it tracks KHO boots. None of this
can work on normal kexec boots. Can you please update the wording to
make that clear?

> when CONFIG_KEXEC_HISTORY is enabled.
>
> This extends the previous kernel release tracking feature by adding
> a counter that increments with each kexec boot. The counter provides
> visibility into the kexec chain depth, which is useful for understanding
> boot history in production environments.
>
> Add a new property, "kexec-count" in KHO FDT alongside the existing
> "previous-release" property. The counter is:
>
>  - Initialized to 0 when kho_in is instantiated.
>  - Incremented by 1 on each subsequent kexec.
>  - Printed alongside the previous kernel release version.
>
> The counter is stored as a 32-bit unsigned integer in FDT format and is
> only active when CONFIG_KEXEC_HISTORY is enabled.

We have such a counter for LUO as well from the properly
"liveupdate-number". If you're using LUO, why can't you use that counter
directly?

If you're not using LUO, I'm curious, what's your use case? Right now
KHO only supports reserve-mem outside of LUO. Is that what you plan to
use?

Also, do we want to keep both counters independently? Or do we have one
and drop the other? Pasha, what do you think?

[...]

-- 
Regards,
Pratyush Yadav


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

end of thread, other threads:[~2026-01-02 20:23 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
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 ` [PATCH v2 1/2] kexec: history: track previous kernel version Breno Leitao
2026-01-02 15:02   ` 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 20:17   ` Pratyush Yadav
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
2026-01-02 20:23   ` Pratyush Yadav

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