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 <[email protected]> Cc: Baoquan He <[email protected]> Cc: Mike Rapoport <[email protected]> Suggested-by: Mike Rapoport <[email protected]> Signed-off-by: Jinjie Ruan <[email protected]> --- 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
