[PATCH v8 09/11] kexec: Add kexec_rollback_segments() helper

Jinjie Ruan ruanjinjie at huawei.com
Thu Nov 12 05:34:16 PST 2026


A load attempt that cannot place all of its segments drops the segments
it added, but the CMA pages backing them become unreachable.

Add a helper that releases those pages and truncates nr_segments,
so the loaders do not have to open code it.

The helper also invalidates the recorded elfcorehdr segment index when
the header is among the dropped segments, so that a retry does not leave
a stale index behind for crash hotplug.

Cc: Andrew Morton <akpm at linux-foundation.org>
Cc: Baoquan He <baoquan.he at linux.dev>
Cc: Mike Rapoport <rppt at kernel.org>
Suggested-by: Mike Rapoport <rppt at kernel.org>
Signed-off-by: Jinjie Ruan <ruanjinjie at huawei.com>
---
 include/linux/kexec.h |  1 +
 kernel/kexec_file.c   | 12 ++++++++++++
 2 files changed, 13 insertions(+)

diff --git a/include/linux/kexec.h b/include/linux/kexec.h
index be7c827e8f7e..464ab4dd36b1 100644
--- a/include/linux/kexec.h
+++ b/include/linux/kexec.h
@@ -259,6 +259,7 @@ int kexec_kernel_verify_pe_sig(const char *kernel, unsigned long kernel_len);
 extern int kexec_add_buffer(struct kexec_buf *kbuf);
 int kexec_locate_mem_hole(struct kexec_buf *kbuf);
 int kexec_add_initrd(struct kimage *image, struct kexec_buf *kbuf);
+void kexec_rollback_segments(struct kimage *image, unsigned long nr_segments);
 #ifdef CONFIG_CRASH_DUMP
 int kexec_prepare_elf_core_header(struct kimage *image, bool need_kernel_map,
 				  unsigned long *nr_ranges);
diff --git a/kernel/kexec_file.c b/kernel/kexec_file.c
index 25c9bef639d2..b4fe5c418842 100644
--- a/kernel/kexec_file.c
+++ b/kernel/kexec_file.c
@@ -1419,3 +1419,15 @@ int kexec_purgatory_get_set_symbol(struct kimage *image, const char *name,
 	return 0;
 }
 #endif /* CONFIG_ARCH_SUPPORTS_KEXEC_PURGATORY */
+
+/*
+ * Undo a partial load attempt: release the CMA pages backing
+ * the segments above @nr_segments and drop them from the image.
+ */
+void kexec_rollback_segments(struct kimage *image, unsigned long nr_segments)
+{
+	while (image->nr_segments > nr_segments) {
+		kexec_free_segment_cma(image, image->nr_segments - 1);
+		image->nr_segments--;
+	}
+}
-- 
2.34.1




More information about the linux-riscv mailing list