* [PATCH v8 01/11] kexec: Free the elf core header in kimage_file_post_load_cleanup()
2026-11-12 13:34 [PATCH v8 00/11] kexec: Rework segment loading and fix CMA retries Jinjie Ruan
@ 2026-11-12 13:34 ` Jinjie Ruan
2026-11-12 13:47 ` sashiko-bot
2026-11-12 13:34 ` [PATCH v8 02/11] kexec: Add helpers to load the elf core header, initrd and FDT Jinjie Ruan
` (9 subsequent siblings)
10 siblings, 1 reply; 23+ messages in thread
From: Jinjie Ruan @ 2026-11-12 13:34 UTC (permalink / raw)
To: catalin.marinas, will, mark.rutland, chenhuacai, kernel, maddy,
mpe, npiggin, chleroy, ritesh.list, sshegde, pjw, palmer, aou,
alex, tglx, mingo, bp, dave.hansen, hpa, akpm, baoquan.he, rppt,
pasha.tatashin, pratyush, ruanjinjie, leitao, yeoreum.yun,
mpilaniy, robh, coiby.xu, Yeking, prudo, brads, sourabhjain,
mkchauras, blum, adityag, qirui.001, hui.wang, sohammetha01,
guoren, gaohan, ionut.nechita, vishal.l.verma, seanjc, ardb,
richard.lyu, arnd, tzimmermann, rick.p.edgecombe, kai.huang, kas,
piliu, thuth, shradhagupta, ebiggers, jbouron, me, mclapinski,
graf, tangyouling, x86, linux-arm-kernel, linux-kernel, loongarch,
linuxppc-dev, linux-riscv, kexec
The elf core header buffer is generic state, but arm64, LoongArch,
RISC-V, x86 and powerpc each free it in their post-load cleanup. Move
it into the generic cleanup, which also gives the loader a helper to
release it on error.
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will@kernel.org>
Cc: Huacai Chen <chenhuacai@kernel.org>
Cc: Palmer Dabbelt <palmer@rivosinc.com>
Cc: Alexandre Ghiti <alexghiti@rivosinc.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Dave Hansen <dave.hansen@linux.intel.com>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Nicholas Piggin <npiggin@gmail.com>
Cc: Christophe Leroy <christophe.leroy@csgroup.eu>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Baoquan He <baoquan.he@linux.dev>
Cc: Mike Rapoport <rppt@kernel.org>
Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>
---
arch/arm64/kernel/machine_kexec_file.c | 4 ----
arch/loongarch/kernel/machine_kexec_file.c | 4 ----
arch/powerpc/kexec/file_load_64.c | 4 ----
arch/riscv/kernel/machine_kexec_file.c | 4 ----
arch/x86/kernel/machine_kexec_64.c | 4 ----
kernel/kexec_file.c | 9 +++++++++
6 files changed, 9 insertions(+), 20 deletions(-)
diff --git a/arch/arm64/kernel/machine_kexec_file.c b/arch/arm64/kernel/machine_kexec_file.c
index 14f453dd0946..097ee397e949 100644
--- a/arch/arm64/kernel/machine_kexec_file.c
+++ b/arch/arm64/kernel/machine_kexec_file.c
@@ -32,10 +32,6 @@ int arch_kimage_file_post_load_cleanup(struct kimage *image)
kvfree(image->arch.dtb);
image->arch.dtb = NULL;
- vfree(image->elf_headers);
- image->elf_headers = NULL;
- image->elf_headers_sz = 0;
-
return kexec_image_post_load_cleanup_default(image);
}
diff --git a/arch/loongarch/kernel/machine_kexec_file.c b/arch/loongarch/kernel/machine_kexec_file.c
index 0fe60907b97f..f16d9ab14726 100644
--- a/arch/loongarch/kernel/machine_kexec_file.c
+++ b/arch/loongarch/kernel/machine_kexec_file.c
@@ -28,10 +28,6 @@ const struct kexec_file_ops * const kexec_file_loaders[] = {
int arch_kimage_file_post_load_cleanup(struct kimage *image)
{
- vfree(image->elf_headers);
- image->elf_headers = NULL;
- image->elf_headers_sz = 0;
-
return kexec_image_post_load_cleanup_default(image);
}
diff --git a/arch/powerpc/kexec/file_load_64.c b/arch/powerpc/kexec/file_load_64.c
index bd80c5fb1b1f..0cf03cee35a7 100644
--- a/arch/powerpc/kexec/file_load_64.c
+++ b/arch/powerpc/kexec/file_load_64.c
@@ -841,10 +841,6 @@ int arch_kimage_file_post_load_cleanup(struct kimage *image)
vfree(image->arch.backup_buf);
image->arch.backup_buf = NULL;
- vfree(image->elf_headers);
- image->elf_headers = NULL;
- image->elf_headers_sz = 0;
-
kvfree(image->arch.fdt);
image->arch.fdt = NULL;
diff --git a/arch/riscv/kernel/machine_kexec_file.c b/arch/riscv/kernel/machine_kexec_file.c
index 26cd2a8bd0cd..1d67fb42617a 100644
--- a/arch/riscv/kernel/machine_kexec_file.c
+++ b/arch/riscv/kernel/machine_kexec_file.c
@@ -29,10 +29,6 @@ int arch_kimage_file_post_load_cleanup(struct kimage *image)
kvfree(image->arch.fdt);
image->arch.fdt = NULL;
- vfree(image->elf_headers);
- image->elf_headers = NULL;
- image->elf_headers_sz = 0;
-
return kexec_image_post_load_cleanup_default(image);
}
diff --git a/arch/x86/kernel/machine_kexec_64.c b/arch/x86/kernel/machine_kexec_64.c
index c3f4a389992d..0a66cc268ee7 100644
--- a/arch/x86/kernel/machine_kexec_64.c
+++ b/arch/x86/kernel/machine_kexec_64.c
@@ -600,10 +600,6 @@ int arch_kexec_apply_relocations_add(struct purgatory_info *pi,
int arch_kimage_file_post_load_cleanup(struct kimage *image)
{
- vfree(image->elf_headers);
- image->elf_headers = NULL;
- image->elf_headers_sz = 0;
-
return kexec_image_post_load_cleanup_default(image);
}
#endif /* CONFIG_KEXEC_FILE */
diff --git a/kernel/kexec_file.c b/kernel/kexec_file.c
index b668ce8d68ee..1f128c6e6fa3 100644
--- a/kernel/kexec_file.c
+++ b/kernel/kexec_file.c
@@ -102,6 +102,13 @@ int kexec_image_post_load_cleanup_default(struct kimage *image)
return image->fops->cleanup(image->image_loader_data);
}
+static void kexec_free_elf_headers(struct kimage *image)
+{
+ vfree(image->elf_headers);
+ image->elf_headers = NULL;
+ image->elf_headers_sz = 0;
+}
+
/*
* Free up memory used by kernel, initrd, and command line. This is temporary
* memory allocation which is not needed any more after these buffers have
@@ -120,6 +127,8 @@ void kimage_file_post_load_cleanup(struct kimage *image)
kfree(image->cmdline_buf);
image->cmdline_buf = NULL;
+ kexec_free_elf_headers(image);
+
vfree(pi->purgatory_buf);
pi->purgatory_buf = NULL;
--
2.34.1
^ permalink raw reply related [flat|nested] 23+ messages in thread* Re: [PATCH v8 01/11] kexec: Free the elf core header in kimage_file_post_load_cleanup()
2026-11-12 13:34 ` [PATCH v8 01/11] kexec: Free the elf core header in kimage_file_post_load_cleanup() Jinjie Ruan
@ 2026-11-12 13:47 ` sashiko-bot
0 siblings, 0 replies; 23+ messages in thread
From: sashiko-bot @ 2026-11-12 13:47 UTC (permalink / raw)
To: Jinjie Ruan, catalin.marinas, will, mark.rutland, chenhuacai,
kernel, maddy, mpe, npiggin, chleroy, ritesh.list, sshegde, pjw,
palmer, aou, alex, tglx, mingo, bp, dave.hansen, hpa, akpm,
baoquan.he, rppt, pasha.tatashin, pratyush, leitao, yeoreum.yun,
mpilaniy, robh, coiby.xu, Yeking, prudo, brads, sourabhjain,
mkchauras, blum, adityag, qirui.001, hui.wang, sohammetha01,
guoren, gaohan, ionut.nechita, vishal.l.verma, seanjc, ardb,
richard.lyu, arnd, tzimmermann, rick.p.edgecombe, kai.huang, kas,
piliu, thuth, shradhagupta, ebiggers, jbouron, me, mclapinski,
graf, tangyouling, x86, kexec
> The elf core header buffer is generic state, but arm64, LoongArch,
> RISC-V, x86 and powerpc each free it in their post-load cleanup. Move
> it into the generic cleanup, which also gives the loader a helper to
> release it on error.
>
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Cc: Will Deacon <will@kernel.org>
> Cc: Huacai Chen <chenhuacai@kernel.org>
> Cc: Palmer Dabbelt <palmer@rivosinc.com>
> Cc: Alexandre Ghiti <alexghiti@rivosinc.com>
> Cc: Thomas Gleixner <tglx@linutronix.de>
> Cc: Ingo Molnar <mingo@redhat.com>
> Cc: Borislav Petkov <bp@alien8.de>
> Cc: Dave Hansen <dave.hansen@linux.intel.com>
> Cc: Michael Ellerman <mpe@ellerman.id.au>
> Cc: Nicholas Piggin <npiggin@gmail.com>
> Cc: Christophe Leroy <christophe.leroy@csgroup.eu>
> Cc: Andrew Morton <akpm@linux-foundation.org>
> Cc: Baoquan He <baoquan.he@linux.dev>
> Cc: Mike Rapoport <rppt@kernel.org>
> Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>
Sashiko has reviewed this patch and found no issues.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261112133418.4044428-1-ruanjinjie@huawei.com?part=1
^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH v8 02/11] kexec: Add helpers to load the elf core header, initrd and FDT
2026-11-12 13:34 [PATCH v8 00/11] kexec: Rework segment loading and fix CMA retries Jinjie Ruan
2026-11-12 13:34 ` [PATCH v8 01/11] kexec: Free the elf core header in kimage_file_post_load_cleanup() Jinjie Ruan
@ 2026-11-12 13:34 ` Jinjie Ruan
2026-11-12 13:59 ` sashiko-bot
2026-11-12 13:34 ` [PATCH v8 03/11] arm64: kexec_file: Load the other segments with common helpers Jinjie Ruan
` (8 subsequent siblings)
10 siblings, 1 reply; 23+ messages in thread
From: Jinjie Ruan @ 2026-11-12 13:34 UTC (permalink / raw)
To: catalin.marinas, will, mark.rutland, chenhuacai, kernel, maddy,
mpe, npiggin, chleroy, ritesh.list, sshegde, pjw, palmer, aou,
alex, tglx, mingo, bp, dave.hansen, hpa, akpm, baoquan.he, rppt,
pasha.tatashin, pratyush, ruanjinjie, leitao, yeoreum.yun,
mpilaniy, robh, coiby.xu, Yeking, prudo, brads, sourabhjain,
mkchauras, blum, adityag, qirui.001, hui.wang, sohammetha01,
guoren, gaohan, ionut.nechita, vishal.l.verma, seanjc, ardb,
richard.lyu, arnd, tzimmermann, rick.p.edgecombe, kai.huang, kas,
piliu, thuth, shradhagupta, ebiggers, jbouron, me, mclapinski,
graf, tangyouling, x86, linux-arm-kernel, linux-kernel, loongarch,
linuxppc-dev, linux-riscv, kexec
x86, arm64, LoongArch, RISC-V and powerpc all build an elf core header,
load the initrd by hand before loading the kdump kernel, while arm64 and
RISC-V also duplicate the code that builds the device tree for the kexec
kernel
Add the following 4 helpers for reuse:
- kexec_prepare_elf_core_header() builds the header once per image and
returns the number of memory ranges, which x86 needs to reserve room
for the crash hotplug updates.
- kexec_add_elf_core_header() places the prepared header as a segment.
The caller provides the kexec_buf with its placement policy and the
size to reserve. On success it also records the segment index that
the crash hotplug code uses to find the header.
- kexec_add_initrd() places the initrd from the image with the placement
policy the caller put into the kexec_buf.
- kexec_add_fdt() builds the device tree for the kexec kernel, packs
it and places it with the kexec_buf the caller passes in.
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Baoquan He <baoquan.he@linux.dev>
Cc: Mike Rapoport <rppt@kernel.org>
Link: https://lore.kernel.org/all/179430504583.425130.15302016434972990362.b4-review@b4/
Suggested-by: Mike Rapoport <rppt@kernel.org>
Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>
---
include/linux/kexec.h | 11 +++++
kernel/kexec_file.c | 104 ++++++++++++++++++++++++++++++++++++++++++
2 files changed, 115 insertions(+)
diff --git a/include/linux/kexec.h b/include/linux/kexec.h
index bac11e940e74..89cb47521d6d 100644
--- a/include/linux/kexec.h
+++ b/include/linux/kexec.h
@@ -258,6 +258,17 @@ 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);
+#ifdef CONFIG_CRASH_DUMP
+int kexec_prepare_elf_core_header(struct kimage *image, bool need_kernel_map,
+ unsigned long *nr_ranges);
+int kexec_add_elf_core_header(struct kimage *image, struct kexec_buf *kbuf);
+#endif
+#if defined(CONFIG_OF) && defined(CONFIG_OF_FLATTREE)
+int kexec_add_fdt(struct kimage *image, struct kexec_buf *kbuf,
+ unsigned long initrd_load_addr, const char *cmdline,
+ void **fdt);
+#endif
#ifndef arch_kexec_apply_relocations_add
/*
diff --git a/kernel/kexec_file.c b/kernel/kexec_file.c
index 1f128c6e6fa3..25c9bef639d2 100644
--- a/kernel/kexec_file.c
+++ b/kernel/kexec_file.c
@@ -14,7 +14,9 @@
#include <linux/file.h>
#include <linux/slab.h>
#include <linux/kexec.h>
+#include <linux/libfdt.h>
#include <linux/memblock.h>
+#include <linux/of.h>
#include <linux/mutex.h>
#include <linux/list.h>
#include <linux/fs.h>
@@ -109,6 +111,108 @@ static void kexec_free_elf_headers(struct kimage *image)
image->elf_headers_sz = 0;
}
+#ifdef CONFIG_CRASH_DUMP
+int kexec_prepare_elf_core_header(struct kimage *image, bool need_kernel_map,
+ unsigned long *nr_ranges)
+{
+ int ret;
+
+ if (image->elf_headers)
+ return 0;
+
+ ret = crash_prepare_headers(need_kernel_map, &image->elf_headers,
+ &image->elf_headers_sz, nr_ranges);
+ if (ret)
+ pr_err("Preparing elf core header failed\n");
+
+ return ret;
+}
+
+int kexec_add_elf_core_header(struct kimage *image, struct kexec_buf *kbuf)
+{
+ unsigned long memsz = kbuf->memsz;
+ int ret;
+
+ kbuf->buffer = image->elf_headers;
+ kbuf->bufsz = image->elf_headers_sz;
+ kbuf->mem = KEXEC_BUF_MEM_UNKNOWN;
+
+ ret = kexec_add_buffer(kbuf);
+ if (ret)
+ return ret;
+
+ image->elf_load_addr = kbuf->mem;
+
+ /* The crash hotplug reservation can exceed the header size. */
+ if (memsz > image->elf_headers_sz) {
+ image->elf_headers_sz = memsz;
+#ifdef CONFIG_CRASH_HOTPLUG
+ image->elfcorehdr_index = image->nr_segments - 1;
+#endif
+ }
+
+ kexec_dprintk("Loaded elf core header at 0x%lx bufsz=0x%lx memsz=0x%lx\n",
+ image->elf_load_addr, kbuf->bufsz, kbuf->memsz);
+
+ return 0;
+}
+#endif /* CONFIG_CRASH_DUMP */
+
+int kexec_add_initrd(struct kimage *image, struct kexec_buf *kbuf)
+{
+ int ret;
+
+ kbuf->buffer = image->initrd_buf;
+ kbuf->bufsz = kbuf->memsz = image->initrd_buf_len;
+ kbuf->mem = KEXEC_BUF_MEM_UNKNOWN;
+
+ ret = kexec_add_buffer(kbuf);
+ if (ret)
+ return ret;
+
+ kexec_dprintk("Loaded initrd at 0x%lx bufsz=0x%lx memsz=0x%lx\n",
+ kbuf->mem, kbuf->bufsz, kbuf->memsz);
+
+ return 0;
+}
+
+#if defined(CONFIG_OF) && defined(CONFIG_OF_FLATTREE)
+int kexec_add_fdt(struct kimage *image, struct kexec_buf *kbuf,
+ unsigned long initrd_load_addr, const char *cmdline,
+ void **fdt)
+{
+ void *new_fdt;
+ int ret;
+
+ new_fdt = of_kexec_alloc_and_setup_fdt(image, initrd_load_addr,
+ image->initrd_buf_len,
+ cmdline, 0);
+ if (!new_fdt) {
+ pr_err("Preparing for new dtb failed\n");
+ return -EINVAL;
+ }
+
+ fdt_pack(new_fdt);
+
+ kbuf->buffer = new_fdt;
+ kbuf->bufsz = kbuf->memsz = fdt_totalsize(new_fdt);
+ kbuf->mem = KEXEC_BUF_MEM_UNKNOWN;
+
+ ret = kexec_add_buffer(kbuf);
+ if (ret) {
+ kvfree(new_fdt);
+ return ret;
+ }
+
+ *fdt = new_fdt;
+
+ kexec_dprintk("Loaded dtb at 0x%lx bufsz=0x%lx memsz=0x%lx\n",
+ kbuf->mem, kbuf->bufsz, kbuf->memsz);
+
+ return 0;
+}
+#endif /* CONFIG_OF && CONFIG_OF_FLATTREE */
+
/*
* Free up memory used by kernel, initrd, and command line. This is temporary
* memory allocation which is not needed any more after these buffers have
--
2.34.1
^ permalink raw reply related [flat|nested] 23+ messages in thread* Re: [PATCH v8 02/11] kexec: Add helpers to load the elf core header, initrd and FDT
2026-11-12 13:34 ` [PATCH v8 02/11] kexec: Add helpers to load the elf core header, initrd and FDT Jinjie Ruan
@ 2026-11-12 13:59 ` sashiko-bot
0 siblings, 0 replies; 23+ messages in thread
From: sashiko-bot @ 2026-11-12 13:59 UTC (permalink / raw)
To: Jinjie Ruan, catalin.marinas, will, mark.rutland, chenhuacai,
kernel, maddy, mpe, npiggin, chleroy, ritesh.list, sshegde, pjw,
palmer, aou, alex, tglx, mingo, bp, dave.hansen, hpa, akpm,
baoquan.he, rppt, pasha.tatashin, pratyush, leitao, yeoreum.yun,
mpilaniy, robh, coiby.xu, Yeking, prudo, brads, sourabhjain,
mkchauras, blum, adityag, qirui.001, hui.wang, sohammetha01,
guoren, gaohan, ionut.nechita, vishal.l.verma, seanjc, ardb,
richard.lyu, arnd, tzimmermann, rick.p.edgecombe, kai.huang, kas,
piliu, thuth, shradhagupta, ebiggers, jbouron, me, mclapinski,
graf, tangyouling, x86, kexec
Thank you for your contribution! Sashiko AI review found 1 potential
issue to consider:
- [High] kexec: conditional elfcorehdr_index update in
kexec_add_elf_core_header()
--
commit 4a8f51d9037324bff5c93a895d13b625ecd6ac57
Author: Jinjie Ruan <ruanjinjie@huawei.com>
kexec: Add helpers to load the elf core header, initrd and FDT
This commit adds generic kexec_file helpers to prepare and place the ELF
core header, initrd, and flattened device tree segments.
Link: https://lore.kernel.org/all/179430504583.425130.15302016434972990362.b4-review@b4/
> diff --git a/kernel/kexec_file.c b/kernel/kexec_file.c
> index 1f128c6e6fa39..25c9bef639d27 100644
> --- a/kernel/kexec_file.c
> +++ b/kernel/kexec_file.c
[ ... ]
> +int kexec_add_elf_core_header(struct kimage *image, struct kexec_buf *kbuf)
> +{
> + unsigned long memsz = kbuf->memsz;
> + int ret;
> +
> + kbuf->buffer = image->elf_headers;
> + kbuf->bufsz = image->elf_headers_sz;
> + kbuf->mem = KEXEC_BUF_MEM_UNKNOWN;
> +
> + ret = kexec_add_buffer(kbuf);
> + if (ret)
> + return ret;
> +
> + image->elf_load_addr = kbuf->mem;
> +
> + /* The crash hotplug reservation can exceed the header size. */
> + if (memsz > image->elf_headers_sz) {
> + image->elf_headers_sz = memsz;
> +#ifdef CONFIG_CRASH_HOTPLUG
> + image->elfcorehdr_index = image->nr_segments - 1;
> +#endif
> + }
[Severity: High]
Should image->elfcorehdr_index be set unconditionally under
CONFIG_CRASH_HOTPLUG rather than only when memsz > image->elf_headers_sz?
When a caller passes kbuf->memsz <= image->elf_headers_sz (such as when
kbuf->memsz equals image->elf_headers_sz, or when an unaligned hotplug
size fits within the page-aligned image->elf_headers_sz),
image->elfcorehdr_index remains -1. kexec_calculate_store_digests() then
hashes the elfcorehdr segment into the purgatory digest, so any later CPU
or memory hotplug update in crash_handle_hotplug_event() rewrites the
header in crash memory and causes purgatory SHA verification to fail on
panic.
Also, if a caller passes kbuf->memsz smaller than image->elf_headers_sz,
clamping kbuf->memsz = max(kbuf->memsz, image->elf_headers_sz) before
kexec_add_buffer() is needed so the segment cannot end up with
memsz < bufsz and fail sanity_check_segment_list() with -EINVAL.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261112133418.4044428-1-ruanjinjie@huawei.com?part=2
^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH v8 03/11] arm64: kexec_file: Load the other segments with common helpers
2026-11-12 13:34 [PATCH v8 00/11] kexec: Rework segment loading and fix CMA retries Jinjie Ruan
2026-11-12 13:34 ` [PATCH v8 01/11] kexec: Free the elf core header in kimage_file_post_load_cleanup() Jinjie Ruan
2026-11-12 13:34 ` [PATCH v8 02/11] kexec: Add helpers to load the elf core header, initrd and FDT Jinjie Ruan
@ 2026-11-12 13:34 ` Jinjie Ruan
2026-11-12 13:45 ` sashiko-bot
2026-11-12 13:34 ` [PATCH v8 04/11] LoongArch: " Jinjie Ruan
` (7 subsequent siblings)
10 siblings, 1 reply; 23+ messages in thread
From: Jinjie Ruan @ 2026-11-12 13:34 UTC (permalink / raw)
To: catalin.marinas, will, mark.rutland, chenhuacai, kernel, maddy,
mpe, npiggin, chleroy, ritesh.list, sshegde, pjw, palmer, aou,
alex, tglx, mingo, bp, dave.hansen, hpa, akpm, baoquan.he, rppt,
pasha.tatashin, pratyush, ruanjinjie, leitao, yeoreum.yun,
mpilaniy, robh, coiby.xu, Yeking, prudo, brads, sourabhjain,
mkchauras, blum, adityag, qirui.001, hui.wang, sohammetha01,
guoren, gaohan, ionut.nechita, vishal.l.verma, seanjc, ardb,
richard.lyu, arnd, tzimmermann, rick.p.edgecombe, kai.huang, kas,
piliu, thuth, shradhagupta, ebiggers, jbouron, me, mclapinski,
graf, tangyouling, x86, linux-arm-kernel, linux-kernel, loongarch,
linuxppc-dev, linux-riscv, kexec
Use the common segment helpers to load the elf core header, the initrd
and the DTB instead of open coding them.
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will@kernel.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Baoquan He <baoquan.he@linux.dev>
Cc: Mike Rapoport <rppt@kernel.org>
Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>
---
arch/arm64/include/asm/kexec.h | 4 +-
arch/arm64/kernel/kexec_image.c | 3 +-
arch/arm64/kernel/machine_kexec_file.c | 81 ++++++--------------------
3 files changed, 20 insertions(+), 68 deletions(-)
diff --git a/arch/arm64/include/asm/kexec.h b/arch/arm64/include/asm/kexec.h
index 892e5bebda95..e7c4604a999f 100644
--- a/arch/arm64/include/asm/kexec.h
+++ b/arch/arm64/include/asm/kexec.h
@@ -125,9 +125,7 @@ int arch_kimage_file_post_load_cleanup(struct kimage *image);
#define arch_kimage_file_post_load_cleanup arch_kimage_file_post_load_cleanup
extern int load_other_segments(struct kimage *image,
- unsigned long kernel_load_addr, unsigned long kernel_size,
- char *initrd, unsigned long initrd_len,
- char *cmdline);
+ unsigned long kernel_load_addr, unsigned long kernel_size);
#endif
#endif /* __ASSEMBLER__ */
diff --git a/arch/arm64/kernel/kexec_image.c b/arch/arm64/kernel/kexec_image.c
index f4ad22447259..a2a7c283b331 100644
--- a/arch/arm64/kernel/kexec_image.c
+++ b/arch/arm64/kernel/kexec_image.c
@@ -104,8 +104,7 @@ static void *image_load(struct kimage *image,
/* Try to load additional data */
kernel_segment = &image->segment[kernel_segment_number];
ret = load_other_segments(image, kernel_segment->mem,
- kernel_segment->memsz, initrd,
- initrd_len, cmdline);
+ kernel_segment->memsz);
if (!ret)
break;
diff --git a/arch/arm64/kernel/machine_kexec_file.c b/arch/arm64/kernel/machine_kexec_file.c
index 097ee397e949..82122ded1467 100644
--- a/arch/arm64/kernel/machine_kexec_file.c
+++ b/arch/arm64/kernel/machine_kexec_file.c
@@ -68,54 +68,33 @@ int arch_crash_populate_cmem(struct crash_mem *cmem)
* valid locations, this function will undo changes to the image and return non
* zero.
*/
-int load_other_segments(struct kimage *image,
- unsigned long kernel_load_addr,
- unsigned long kernel_size,
- char *initrd, unsigned long initrd_len,
- char *cmdline)
+int load_other_segments(struct kimage *image, unsigned long kernel_load_addr,
+ unsigned long kernel_size)
{
- struct kexec_buf kbuf = {};
+ unsigned long initrd_load_addr = 0, orig_segments = image->nr_segments;
+ struct kexec_buf kbuf = {
+ .image = image,
+ /* not allocate anything below the kernel */
+ .buf_min = kernel_load_addr + kernel_size,
+ .buf_max = ULONG_MAX,
+ };
void *dtb = NULL;
- unsigned long initrd_load_addr = 0, dtb_len,
- orig_segments = image->nr_segments;
int ret = 0;
- kbuf.image = image;
- /* not allocate anything below the kernel */
- kbuf.buf_min = kernel_load_addr + kernel_size;
-
#ifdef CONFIG_CRASH_DUMP
/* load elf core header */
- void *headers;
- unsigned long headers_sz;
if (image->type == KEXEC_TYPE_CRASH) {
- ret = crash_prepare_headers(true, &headers, &headers_sz, NULL);
- if (ret) {
- pr_err("Preparing elf core header failed\n");
+ ret = kexec_prepare_elf_core_header(image, true, NULL);
+ if (ret)
goto out_err;
- }
- kbuf.buffer = headers;
- kbuf.bufsz = headers_sz;
- kbuf.mem = KEXEC_BUF_MEM_UNKNOWN;
- kbuf.memsz = headers_sz;
kbuf.buf_align = SZ_64K; /* largest supported page size */
- kbuf.buf_max = ULONG_MAX;
kbuf.top_down = true;
+ kbuf.memsz = image->elf_headers_sz;
- ret = kexec_add_buffer(&kbuf);
- if (ret) {
- vfree(headers);
+ ret = kexec_add_elf_core_header(image, &kbuf);
+ if (ret)
goto out_err;
- }
-
- vfree(image->elf_headers);
- image->elf_headers = headers;
- image->elf_load_addr = kbuf.mem;
- image->elf_headers_sz = headers_sz;
-
- kexec_dprintk("Loaded elf core header at 0x%lx bufsz=0x%lx memsz=0x%lx\n",
- image->elf_load_addr, kbuf.bufsz, kbuf.memsz);
ret = crash_load_dm_crypt_keys(image);
if (ret)
@@ -124,56 +103,32 @@ int load_other_segments(struct kimage *image,
#endif
/* load initrd */
- if (initrd) {
- kbuf.buffer = initrd;
- kbuf.bufsz = initrd_len;
- kbuf.mem = KEXEC_BUF_MEM_UNKNOWN;
- kbuf.memsz = initrd_len;
+ if (image->initrd_buf) {
kbuf.buf_align = 0;
/* within 1GB-aligned window of up to 32GB in size */
kbuf.buf_max = round_down(kernel_load_addr, SZ_1G)
+ (unsigned long)SZ_1G * 32;
kbuf.top_down = false;
- ret = kexec_add_buffer(&kbuf);
+ ret = kexec_add_initrd(image, &kbuf);
if (ret)
goto out_err;
initrd_load_addr = kbuf.mem;
-
- kexec_dprintk("Loaded initrd at 0x%lx bufsz=0x%lx memsz=0x%lx\n",
- initrd_load_addr, kbuf.bufsz, kbuf.memsz);
}
/* load dtb */
- dtb = of_kexec_alloc_and_setup_fdt(image, initrd_load_addr,
- initrd_len, cmdline, 0);
- if (!dtb) {
- pr_err("Preparing for new dtb failed\n");
- ret = -EINVAL;
- goto out_err;
- }
-
- /* trim it */
- fdt_pack(dtb);
- dtb_len = fdt_totalsize(dtb);
- kbuf.buffer = dtb;
- kbuf.bufsz = dtb_len;
- kbuf.mem = KEXEC_BUF_MEM_UNKNOWN;
- kbuf.memsz = dtb_len;
/* not across 2MB boundary */
kbuf.buf_align = SZ_2M;
kbuf.buf_max = ULONG_MAX;
kbuf.top_down = true;
- ret = kexec_add_buffer(&kbuf);
+ ret = kexec_add_fdt(image, &kbuf, initrd_load_addr, image->cmdline_buf,
+ &dtb);
if (ret)
goto out_err;
image->arch.dtb = dtb;
image->arch.dtb_mem = kbuf.mem;
- kexec_dprintk("Loaded dtb at 0x%lx bufsz=0x%lx memsz=0x%lx\n",
- kbuf.mem, kbuf.bufsz, kbuf.memsz);
-
return 0;
out_err:
--
2.34.1
^ permalink raw reply related [flat|nested] 23+ messages in thread* Re: [PATCH v8 03/11] arm64: kexec_file: Load the other segments with common helpers
2026-11-12 13:34 ` [PATCH v8 03/11] arm64: kexec_file: Load the other segments with common helpers Jinjie Ruan
@ 2026-11-12 13:45 ` sashiko-bot
0 siblings, 0 replies; 23+ messages in thread
From: sashiko-bot @ 2026-11-12 13:45 UTC (permalink / raw)
To: Jinjie Ruan, catalin.marinas, will, mark.rutland, chenhuacai,
kernel, maddy, mpe, npiggin, chleroy, ritesh.list, sshegde, pjw,
palmer, aou, alex, tglx, mingo, bp, dave.hansen, hpa, akpm,
baoquan.he, rppt, pasha.tatashin, pratyush, leitao, yeoreum.yun,
mpilaniy, robh, coiby.xu, Yeking, prudo, brads, sourabhjain,
mkchauras, blum, adityag, qirui.001, hui.wang, sohammetha01,
guoren, gaohan, ionut.nechita, vishal.l.verma, seanjc, ardb,
richard.lyu, arnd, tzimmermann, rick.p.edgecombe, kai.huang, kas,
piliu, thuth, shradhagupta, ebiggers, jbouron, me, mclapinski,
graf, tangyouling, x86, kexec
> Use the common segment helpers to load the elf core header, the initrd
> and the DTB instead of open coding them.
>
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Cc: Will Deacon <will@kernel.org>
> Cc: Andrew Morton <akpm@linux-foundation.org>
> Cc: Baoquan He <baoquan.he@linux.dev>
> Cc: Mike Rapoport <rppt@kernel.org>
> Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>
Sashiko has reviewed this patch and found no issues.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261112133418.4044428-1-ruanjinjie@huawei.com?part=3
^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH v8 04/11] LoongArch: kexec_file: Load the other segments with common helpers
2026-11-12 13:34 [PATCH v8 00/11] kexec: Rework segment loading and fix CMA retries Jinjie Ruan
` (2 preceding siblings ...)
2026-11-12 13:34 ` [PATCH v8 03/11] arm64: kexec_file: Load the other segments with common helpers Jinjie Ruan
@ 2026-11-12 13:34 ` Jinjie Ruan
2026-11-12 13:52 ` sashiko-bot
2026-11-12 13:34 ` [PATCH v8 05/11] riscv: kexec_file: Load the extra " Jinjie Ruan
` (6 subsequent siblings)
10 siblings, 1 reply; 23+ messages in thread
From: Jinjie Ruan @ 2026-11-12 13:34 UTC (permalink / raw)
To: catalin.marinas, will, mark.rutland, chenhuacai, kernel, maddy,
mpe, npiggin, chleroy, ritesh.list, sshegde, pjw, palmer, aou,
alex, tglx, mingo, bp, dave.hansen, hpa, akpm, baoquan.he, rppt,
pasha.tatashin, pratyush, ruanjinjie, leitao, yeoreum.yun,
mpilaniy, robh, coiby.xu, Yeking, prudo, brads, sourabhjain,
mkchauras, blum, adityag, qirui.001, hui.wang, sohammetha01,
guoren, gaohan, ionut.nechita, vishal.l.verma, seanjc, ardb,
richard.lyu, arnd, tzimmermann, rick.p.edgecombe, kai.huang, kas,
piliu, thuth, shradhagupta, ebiggers, jbouron, me, mclapinski,
graf, tangyouling, x86, linux-arm-kernel, linux-kernel, loongarch,
linuxppc-dev, linux-riscv, kexec
Use the common segment helpers to load the elf core header and the initrd
instead of open coding them. The initrd and the command line come from
the image.
Cc: Huacai Chen <chenhuacai@kernel.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Baoquan He <baoquan.he@linux.dev>
Cc: Mike Rapoport <rppt@kernel.org>
Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>
---
arch/loongarch/include/asm/kexec.h | 3 +-
arch/loongarch/kernel/kexec_efi.c | 3 +-
arch/loongarch/kernel/kexec_elf.c | 3 +-
arch/loongarch/kernel/machine_kexec_file.c | 74 +++++++---------------
4 files changed, 27 insertions(+), 56 deletions(-)
diff --git a/arch/loongarch/include/asm/kexec.h b/arch/loongarch/include/asm/kexec.h
index 6be136e9f0a0..b000e97c95f6 100644
--- a/arch/loongarch/include/asm/kexec.h
+++ b/arch/loongarch/include/asm/kexec.h
@@ -51,8 +51,7 @@ int arch_kimage_file_post_load_cleanup(struct kimage *image);
#define arch_kimage_file_post_load_cleanup arch_kimage_file_post_load_cleanup
extern int load_other_segments(struct kimage *image,
- unsigned long kernel_load_addr, unsigned long kernel_size,
- char *initrd, unsigned long initrd_len, char *cmdline, unsigned long cmdline_len);
+ unsigned long kernel_load_addr, unsigned long kernel_size);
#endif
typedef void (*do_kexec_t)(unsigned long efi_boot,
diff --git a/arch/loongarch/kernel/kexec_efi.c b/arch/loongarch/kernel/kexec_efi.c
index 28a1d0420ba3..4824c47907ac 100644
--- a/arch/loongarch/kernel/kexec_efi.c
+++ b/arch/loongarch/kernel/kexec_efi.c
@@ -77,8 +77,7 @@ static void *efi_kexec_load(struct kimage *image,
/* Try to load additional data */
kernel_segment = &image->segment[kernel_segment_number];
ret = load_other_segments(image, kernel_segment->mem,
- kernel_segment->memsz, initrd,
- initrd_len, cmdline, cmdline_len);
+ kernel_segment->memsz);
if (!ret)
break;
diff --git a/arch/loongarch/kernel/kexec_elf.c b/arch/loongarch/kernel/kexec_elf.c
index 1b6b64744c7f..6fda49de330f 100644
--- a/arch/loongarch/kernel/kexec_elf.c
+++ b/arch/loongarch/kernel/kexec_elf.c
@@ -83,8 +83,7 @@ static void *elf_kexec_load(struct kimage *image,
/* Load additional data */
kernel_segment = &image->segment[kernel_segment_number];
- ret = load_other_segments(image, kernel_segment->mem, kernel_segment->memsz,
- initrd, initrd_len, cmdline, cmdline_len);
+ ret = load_other_segments(image, kernel_segment->mem, kernel_segment->memsz);
if (ret < 0)
goto out;
diff --git a/arch/loongarch/kernel/machine_kexec_file.c b/arch/loongarch/kernel/machine_kexec_file.c
index f16d9ab14726..5a3d5026303e 100644
--- a/arch/loongarch/kernel/machine_kexec_file.c
+++ b/arch/loongarch/kernel/machine_kexec_file.c
@@ -115,19 +115,20 @@ static void cmdline_add_elfcorehdr(struct kimage *image, unsigned long *cmdline_
* locations, this function will undo changes to the image and return non zero.
*/
int load_other_segments(struct kimage *image,
- unsigned long kernel_load_addr, unsigned long kernel_size,
- char *initrd, unsigned long initrd_len, char *cmdline, unsigned long cmdline_len)
+ unsigned long kernel_load_addr, unsigned long kernel_size)
{
- int ret = 0;
+ struct kexec_buf kbuf = {
+ .image = image,
+ /* Don't allocate anything below the kernel */
+ .buf_min = kernel_load_addr + kernel_size,
+ .buf_max = ULONG_MAX,
+ };
unsigned long cmdline_tmplen = 0;
unsigned long initrd_load_addr = 0;
unsigned long orig_segments = image->nr_segments;
+ char *cmdline = image->cmdline_buf;
char *modified_cmdline = NULL;
- struct kexec_buf kbuf = {};
-
- kbuf.image = image;
- /* Don't allocate anything below the kernel */
- kbuf.buf_min = kernel_load_addr + kernel_size;
+ int ret = 0;
modified_cmdline = kzalloc(COMMAND_LINE_SIZE, GFP_KERNEL);
if (!modified_cmdline)
@@ -140,79 +141,52 @@ int load_other_segments(struct kimage *image,
#ifdef CONFIG_CRASH_DUMP
/* Load elf core header */
if (image->type == KEXEC_TYPE_CRASH) {
- void *headers;
- unsigned long headers_sz;
-
- ret = crash_prepare_headers(true, &headers, &headers_sz, NULL);
- if (ret < 0) {
- pr_err("Preparing elf core header failed\n");
+ ret = kexec_prepare_elf_core_header(image, true, NULL);
+ if (ret)
goto out_err;
- }
- kbuf.buffer = headers;
- kbuf.bufsz = headers_sz;
- kbuf.mem = KEXEC_BUF_MEM_UNKNOWN;
- kbuf.memsz = headers_sz;
kbuf.buf_align = SZ_64K; /* largest supported page size */
- kbuf.buf_max = ULONG_MAX;
kbuf.top_down = true;
+ kbuf.memsz = image->elf_headers_sz;
- ret = kexec_add_buffer(&kbuf);
- if (ret < 0) {
- vfree(headers);
+ ret = kexec_add_elf_core_header(image, &kbuf);
+ if (ret)
goto out_err;
- }
-
- if (unlikely(image->elf_headers))
- vfree(image->elf_headers);
-
- image->elf_headers = headers;
- image->elf_load_addr = kbuf.mem;
- image->elf_headers_sz = headers_sz;
-
- kexec_dprintk("Loaded elf core header at 0x%lx bufsz=0x%lx memsz=0x%lx\n",
- image->elf_load_addr, kbuf.bufsz, kbuf.memsz);
/* Add the mem=size@start parameter to the command line */
cmdline_add_mem(&cmdline_tmplen, modified_cmdline);
/* Add the elfcorehdr=size@start parameter to the command line */
- cmdline_add_elfcorehdr(image, &cmdline_tmplen, modified_cmdline, headers_sz);
+ cmdline_add_elfcorehdr(image, &cmdline_tmplen, modified_cmdline,
+ image->elf_headers_sz);
}
#endif
/* Load initrd */
- if (initrd) {
- kbuf.buffer = initrd;
- kbuf.bufsz = initrd_len;
- kbuf.mem = KEXEC_BUF_MEM_UNKNOWN;
- kbuf.memsz = initrd_len;
+ if (image->initrd_buf) {
kbuf.buf_align = 0;
/* within 1GB-aligned window of up to 32GB in size */
kbuf.buf_max = round_down(kernel_load_addr, SZ_1G) + (unsigned long)SZ_1G * 32;
kbuf.top_down = false;
- ret = kexec_add_buffer(&kbuf);
- if (ret < 0)
+ ret = kexec_add_initrd(image, &kbuf);
+ if (ret)
goto out_err;
initrd_load_addr = kbuf.mem;
- kexec_dprintk("Loaded initrd at 0x%lx bufsz=0x%lx memsz=0x%lx\n",
- initrd_load_addr, kbuf.bufsz, kbuf.memsz);
-
/* Add the initrd=start,size parameter to the command line */
- cmdline_add_initrd(image, &cmdline_tmplen, modified_cmdline, initrd_load_addr);
+ cmdline_add_initrd(image, &cmdline_tmplen, modified_cmdline,
+ initrd_load_addr);
}
- if (cmdline_len + cmdline_tmplen > COMMAND_LINE_SIZE) {
+ if (image->cmdline_buf_len + cmdline_tmplen > COMMAND_LINE_SIZE) {
pr_err("Appending command line exceeds COMMAND_LINE_SIZE\n");
ret = -EINVAL;
goto out_err;
}
- memcpy(modified_cmdline + cmdline_tmplen, cmdline, cmdline_len);
- cmdline = modified_cmdline;
- image->arch.cmdline_ptr = (unsigned long)cmdline;
+ memcpy(modified_cmdline + cmdline_tmplen, cmdline, image->cmdline_buf_len);
+ image->arch.cmdline_ptr = (unsigned long)modified_cmdline;
return 0;
--
2.34.1
^ permalink raw reply related [flat|nested] 23+ messages in thread* Re: [PATCH v8 04/11] LoongArch: kexec_file: Load the other segments with common helpers
2026-11-12 13:34 ` [PATCH v8 04/11] LoongArch: " Jinjie Ruan
@ 2026-11-12 13:52 ` sashiko-bot
0 siblings, 0 replies; 23+ messages in thread
From: sashiko-bot @ 2026-11-12 13:52 UTC (permalink / raw)
To: Jinjie Ruan, catalin.marinas, will, mark.rutland, chenhuacai,
kernel, maddy, mpe, npiggin, chleroy, ritesh.list, sshegde, pjw,
palmer, aou, alex, tglx, mingo, bp, dave.hansen, hpa, akpm,
baoquan.he, rppt, pasha.tatashin, pratyush, leitao, yeoreum.yun,
mpilaniy, robh, coiby.xu, Yeking, prudo, brads, sourabhjain,
mkchauras, blum, adityag, qirui.001, hui.wang, sohammetha01,
guoren, gaohan, ionut.nechita, vishal.l.verma, seanjc, ardb,
richard.lyu, arnd, tzimmermann, rick.p.edgecombe, kai.huang, kas,
piliu, thuth, shradhagupta, ebiggers, jbouron, me, mclapinski,
graf, tangyouling, x86, kexec
> Use the common segment helpers to load the elf core header and the initrd
> instead of open coding them. The initrd and the command line come from
> the image.
>
> Cc: Huacai Chen <chenhuacai@kernel.org>
> Cc: Andrew Morton <akpm@linux-foundation.org>
> Cc: Baoquan He <baoquan.he@linux.dev>
> Cc: Mike Rapoport <rppt@kernel.org>
> Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>
Sashiko has reviewed this patch and found no issues.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261112133418.4044428-1-ruanjinjie@huawei.com?part=4
^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH v8 05/11] riscv: kexec_file: Load the extra segments with common helpers
2026-11-12 13:34 [PATCH v8 00/11] kexec: Rework segment loading and fix CMA retries Jinjie Ruan
` (3 preceding siblings ...)
2026-11-12 13:34 ` [PATCH v8 04/11] LoongArch: " Jinjie Ruan
@ 2026-11-12 13:34 ` Jinjie Ruan
2026-11-12 13:53 ` sashiko-bot
2026-11-12 13:34 ` [PATCH v8 06/11] x86: kexec_file: Use the common segment helpers Jinjie Ruan
` (5 subsequent siblings)
10 siblings, 1 reply; 23+ messages in thread
From: Jinjie Ruan @ 2026-11-12 13:34 UTC (permalink / raw)
To: catalin.marinas, will, mark.rutland, chenhuacai, kernel, maddy,
mpe, npiggin, chleroy, ritesh.list, sshegde, pjw, palmer, aou,
alex, tglx, mingo, bp, dave.hansen, hpa, akpm, baoquan.he, rppt,
pasha.tatashin, pratyush, ruanjinjie, leitao, yeoreum.yun,
mpilaniy, robh, coiby.xu, Yeking, prudo, brads, sourabhjain,
mkchauras, blum, adityag, qirui.001, hui.wang, sohammetha01,
guoren, gaohan, ionut.nechita, vishal.l.verma, seanjc, ardb,
richard.lyu, arnd, tzimmermann, rick.p.edgecombe, kai.huang, kas,
piliu, thuth, shradhagupta, ebiggers, jbouron, me, mclapinski,
graf, tangyouling, x86, linux-arm-kernel, linux-kernel, loongarch,
linuxppc-dev, linux-riscv, kexec
Use the common segment helpers to load the elf core header, the initrd
and the DTB instead of open coding them. The initrd and the command line
come from the image.
Cc: Palmer Dabbelt <palmer@rivosinc.com>
Cc: Alexandre Ghiti <alexghiti@rivosinc.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Baoquan He <baoquan.he@linux.dev>
Cc: Mike Rapoport <rppt@kernel.org>
Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>
---
arch/riscv/include/asm/kexec.h | 4 +-
arch/riscv/kernel/kexec_elf.c | 3 +-
arch/riscv/kernel/kexec_image.c | 3 +-
arch/riscv/kernel/machine_kexec_file.c | 79 +++++++-------------------
4 files changed, 24 insertions(+), 65 deletions(-)
diff --git a/arch/riscv/include/asm/kexec.h b/arch/riscv/include/asm/kexec.h
index e218835eb10c..34da4d0e2cdc 100644
--- a/arch/riscv/include/asm/kexec.h
+++ b/arch/riscv/include/asm/kexec.h
@@ -70,9 +70,7 @@ int arch_kimage_file_post_load_cleanup(struct kimage *image);
#define arch_kimage_file_post_load_cleanup arch_kimage_file_post_load_cleanup
int load_extra_segments(struct kimage *image, unsigned long kernel_start,
- unsigned long kernel_len, char *initrd,
- unsigned long initrd_len, char *cmdline,
- unsigned long cmdline_len);
+ unsigned long kernel_len);
#endif
#ifdef CONFIG_CRASH_HOTPLUG
diff --git a/arch/riscv/kernel/kexec_elf.c b/arch/riscv/kernel/kexec_elf.c
index ca5abbad59e5..2071a22b846c 100644
--- a/arch/riscv/kernel/kexec_elf.c
+++ b/arch/riscv/kernel/kexec_elf.c
@@ -126,8 +126,7 @@ static void *elf_kexec_load(struct kimage *image, char *kernel_buf,
if (ret)
goto out;
- ret = load_extra_segments(image, image->start, kernel_len,
- initrd, initrd_len, cmdline, cmdline_len);
+ ret = load_extra_segments(image, image->start, kernel_len);
out:
kexec_free_elf_info(&elf_info);
return ret ? ERR_PTR(ret) : NULL;
diff --git a/arch/riscv/kernel/kexec_image.c b/arch/riscv/kernel/kexec_image.c
index 963a25f5b55b..010a84085cf8 100644
--- a/arch/riscv/kernel/kexec_image.c
+++ b/arch/riscv/kernel/kexec_image.c
@@ -83,8 +83,7 @@ static void *image_load(struct kimage *image,
pr_info("Loaded kernel at 0x%lx bufsz=0x%lx memsz=0x%lx\n",
kbuf.mem, kbuf.bufsz, kbuf.memsz);
- ret = load_extra_segments(image, kbuf.mem, kbuf.memsz,
- initrd, initrd_len, cmdline, cmdline_len);
+ ret = load_extra_segments(image, kbuf.mem, kbuf.memsz);
out:
return ret ? ERR_PTR(ret) : NULL;
diff --git a/arch/riscv/kernel/machine_kexec_file.c b/arch/riscv/kernel/machine_kexec_file.c
index 1d67fb42617a..8a122476f056 100644
--- a/arch/riscv/kernel/machine_kexec_file.c
+++ b/arch/riscv/kernel/machine_kexec_file.c
@@ -236,53 +236,37 @@ int arch_kexec_apply_relocations_add(struct purgatory_info *pi,
int load_extra_segments(struct kimage *image, unsigned long kernel_start,
- unsigned long kernel_len, char *initrd,
- unsigned long initrd_len, char *cmdline,
- unsigned long cmdline_len)
+ unsigned long kernel_len)
{
- int ret;
- void *fdt;
+ struct kexec_buf kbuf = {
+ .image = image,
+ .buf_min = kernel_start + kernel_len,
+ .buf_max = PFN_PHYS(max_low_pfn),
+ };
unsigned long initrd_pbase = 0UL;
- struct kexec_buf kbuf = {};
+ char *cmdline = image->cmdline_buf;
char *modified_cmdline = NULL;
-
- kbuf.image = image;
- kbuf.buf_min = kernel_start + kernel_len;
- kbuf.buf_max = PFN_PHYS(max_low_pfn);
+ void *fdt = NULL;
+ int ret = 0;
#ifdef CONFIG_CRASH_DUMP
/* Add elfcorehdr */
if (image->type == KEXEC_TYPE_CRASH) {
- void *headers;
- unsigned long headers_sz;
- ret = crash_prepare_headers(true, &headers, &headers_sz, NULL);
- if (ret) {
- pr_err("Preparing elf core header failed\n");
+ ret = kexec_prepare_elf_core_header(image, true, NULL);
+ if (ret)
goto out;
- }
- kbuf.buffer = headers;
- kbuf.bufsz = headers_sz;
- kbuf.mem = KEXEC_BUF_MEM_UNKNOWN;
- kbuf.memsz = headers_sz;
kbuf.buf_align = ELF_CORE_HEADER_ALIGN;
kbuf.top_down = true;
+ kbuf.memsz = image->elf_headers_sz;
- ret = kexec_add_buffer(&kbuf);
- if (ret) {
- vfree(headers);
+ ret = kexec_add_elf_core_header(image, &kbuf);
+ if (ret)
goto out;
- }
- image->elf_headers = headers;
- image->elf_load_addr = kbuf.mem;
- image->elf_headers_sz = headers_sz;
-
- kexec_dprintk("Loaded elf core header at 0x%lx bufsz=0x%lx memsz=0x%lx\n",
- image->elf_load_addr, kbuf.bufsz, kbuf.memsz);
/* Setup cmdline for kdump kernel case */
modified_cmdline = setup_kdump_cmdline(image, cmdline,
- cmdline_len);
+ image->cmdline_buf_len);
if (!modified_cmdline) {
pr_err("Setting up cmdline for kdump kernel failed\n");
ret = -EINVAL;
@@ -311,46 +295,25 @@ int load_extra_segments(struct kimage *image, unsigned long kernel_start,
#endif /* CONFIG_ARCH_SUPPORTS_KEXEC_PURGATORY */
/* Add the initrd to the image */
- if (initrd != NULL) {
- kbuf.buffer = initrd;
- kbuf.bufsz = kbuf.memsz = initrd_len;
+ if (image->initrd_buf) {
kbuf.buf_align = PAGE_SIZE;
kbuf.top_down = true;
- kbuf.mem = KEXEC_BUF_MEM_UNKNOWN;
- ret = kexec_add_buffer(&kbuf);
+ ret = kexec_add_initrd(image, &kbuf);
if (ret)
goto out;
initrd_pbase = kbuf.mem;
- kexec_dprintk("Loaded initrd at 0x%lx\n", initrd_pbase);
}
/* Add the DTB to the image */
- fdt = of_kexec_alloc_and_setup_fdt(image, initrd_pbase,
- initrd_len, cmdline, 0);
- if (!fdt) {
- pr_err("Error setting up the new device tree.\n");
- ret = -EINVAL;
- goto out;
- }
-
- fdt_pack(fdt);
- kbuf.buffer = fdt;
- kbuf.bufsz = kbuf.memsz = fdt_totalsize(fdt);
kbuf.buf_align = PAGE_SIZE;
- kbuf.mem = KEXEC_BUF_MEM_UNKNOWN;
kbuf.top_down = true;
- ret = kexec_add_buffer(&kbuf);
- if (ret) {
- pr_err("Error add DTB kbuf ret=%d\n", ret);
- goto out_free_fdt;
- }
+ ret = kexec_add_fdt(image, &kbuf, initrd_pbase, cmdline, &fdt);
+ if (ret)
+ goto out;
+
/* Cache the fdt buffer address for memory cleanup */
image->arch.fdt = fdt;
- kexec_dprintk("Loaded device tree at 0x%lx\n", kbuf.mem);
- goto out;
-out_free_fdt:
- kvfree(fdt);
out:
kfree(modified_cmdline);
return ret;
--
2.34.1
^ permalink raw reply related [flat|nested] 23+ messages in thread* Re: [PATCH v8 05/11] riscv: kexec_file: Load the extra segments with common helpers
2026-11-12 13:34 ` [PATCH v8 05/11] riscv: kexec_file: Load the extra " Jinjie Ruan
@ 2026-11-12 13:53 ` sashiko-bot
0 siblings, 0 replies; 23+ messages in thread
From: sashiko-bot @ 2026-11-12 13:53 UTC (permalink / raw)
To: Jinjie Ruan, catalin.marinas, will, mark.rutland, chenhuacai,
kernel, maddy, mpe, npiggin, chleroy, ritesh.list, sshegde, pjw,
palmer, aou, alex, tglx, mingo, bp, dave.hansen, hpa, akpm,
baoquan.he, rppt, pasha.tatashin, pratyush, leitao, yeoreum.yun,
mpilaniy, robh, coiby.xu, Yeking, prudo, brads, sourabhjain,
mkchauras, blum, adityag, qirui.001, hui.wang, sohammetha01,
guoren, gaohan, ionut.nechita, vishal.l.verma, seanjc, ardb,
richard.lyu, arnd, tzimmermann, rick.p.edgecombe, kai.huang, kas,
piliu, thuth, shradhagupta, ebiggers, jbouron, me, mclapinski,
graf, tangyouling, x86, kexec
> Use the common segment helpers to load the elf core header, the initrd
> and the DTB instead of open coding them. The initrd and the command line
> come from the image.
>
> Cc: Palmer Dabbelt <palmer@rivosinc.com>
> Cc: Alexandre Ghiti <alexghiti@rivosinc.com>
> Cc: Andrew Morton <akpm@linux-foundation.org>
> Cc: Baoquan He <baoquan.he@linux.dev>
> Cc: Mike Rapoport <rppt@kernel.org>
> Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>
Sashiko has reviewed this patch and found no issues.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261112133418.4044428-1-ruanjinjie@huawei.com?part=5
^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH v8 06/11] x86: kexec_file: Use the common segment helpers
2026-11-12 13:34 [PATCH v8 00/11] kexec: Rework segment loading and fix CMA retries Jinjie Ruan
` (4 preceding siblings ...)
2026-11-12 13:34 ` [PATCH v8 05/11] riscv: kexec_file: Load the extra " Jinjie Ruan
@ 2026-11-12 13:34 ` Jinjie Ruan
2026-11-12 14:08 ` sashiko-bot
2026-11-12 13:34 ` [PATCH v8 07/11] powerpc: " Jinjie Ruan
` (4 subsequent siblings)
10 siblings, 1 reply; 23+ messages in thread
From: Jinjie Ruan @ 2026-11-12 13:34 UTC (permalink / raw)
To: catalin.marinas, will, mark.rutland, chenhuacai, kernel, maddy,
mpe, npiggin, chleroy, ritesh.list, sshegde, pjw, palmer, aou,
alex, tglx, mingo, bp, dave.hansen, hpa, akpm, baoquan.he, rppt,
pasha.tatashin, pratyush, ruanjinjie, leitao, yeoreum.yun,
mpilaniy, robh, coiby.xu, Yeking, prudo, brads, sourabhjain,
mkchauras, blum, adityag, qirui.001, hui.wang, sohammetha01,
guoren, gaohan, ionut.nechita, vishal.l.verma, seanjc, ardb,
richard.lyu, arnd, tzimmermann, rick.p.edgecombe, kai.huang, kas,
piliu, thuth, shradhagupta, ebiggers, jbouron, me, mclapinski,
graf, tangyouling, x86, linux-arm-kernel, linux-kernel, loongarch,
linuxppc-dev, linux-riscv, kexec
crash_load_segments() open codes the elf core header loading: it builds
the header, accounts for crash hotplug and places the segment.
Use kexec_prepare_elf_core_header() and kexec_add_elf_core_header()
instead.
bzImage64_load() also loads the initrd by hand, use kexec_add_initrd()
for it.
Cc: Thomas Gleixner <tglx@kernel.org>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Dave Hansen <dave.hansen@linux.intel.com>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: x86@kernel.org
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Baoquan He <baoquan.he@linux.dev>
Cc: Mike Rapoport <rppt@kernel.org>
Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>
---
arch/x86/kernel/crash.c | 25 +++++--------------------
arch/x86/kernel/kexec-bzimage64.c | 8 +-------
2 files changed, 6 insertions(+), 27 deletions(-)
diff --git a/arch/x86/kernel/crash.c b/arch/x86/kernel/crash.c
index e6f23933a6df..8d56d39ebbd5 100644
--- a/arch/x86/kernel/crash.c
+++ b/arch/x86/kernel/crash.c
@@ -354,14 +354,12 @@ int crash_load_segments(struct kimage *image)
.buf_max = ULONG_MAX, .top_down = false };
/* Prepare elf headers and add a segment */
- ret = crash_prepare_headers(IS_ENABLED(CONFIG_X86_64), &kbuf.buffer,
- &kbuf.bufsz, &pnum);
+ ret = kexec_prepare_elf_core_header(image, IS_ENABLED(CONFIG_X86_64),
+ &pnum);
if (ret)
return ret;
- image->elf_headers = kbuf.buffer;
- image->elf_headers_sz = kbuf.bufsz;
- kbuf.memsz = kbuf.bufsz;
+ kbuf.memsz = image->elf_headers_sz;
#ifdef CONFIG_CRASH_HOTPLUG
/*
@@ -374,28 +372,15 @@ int crash_load_segments(struct kimage *image)
pnum += 2 + CONFIG_NR_CPUS;
if (pnum < (unsigned long)PN_XNUM) {
- kbuf.memsz = pnum * sizeof(Elf64_Phdr);
- kbuf.memsz += sizeof(Elf64_Ehdr);
-
- image->elfcorehdr_index = image->nr_segments;
-
- /* Mark as usable to crash kernel, else crash kernel fails on boot */
- image->elf_headers_sz = kbuf.memsz;
+ kbuf.memsz = pnum * sizeof(Elf64_Phdr) + sizeof(Elf64_Ehdr);
} else {
pr_err("number of Phdrs %lu exceeds max\n", pnum);
}
#endif
kbuf.buf_align = ELF_CORE_HEADER_ALIGN;
- kbuf.mem = KEXEC_BUF_MEM_UNKNOWN;
- ret = kexec_add_buffer(&kbuf);
- if (ret)
- return ret;
- image->elf_load_addr = kbuf.mem;
- kexec_dprintk("Loaded ELF headers at 0x%lx bufsz=0x%lx memsz=0x%lx\n",
- image->elf_load_addr, kbuf.bufsz, kbuf.memsz);
- return ret;
+ return kexec_add_elf_core_header(image, &kbuf);
}
#endif /* CONFIG_KEXEC_FILE */
diff --git a/arch/x86/kernel/kexec-bzimage64.c b/arch/x86/kernel/kexec-bzimage64.c
index 3aa77006adab..c8e285c9a4c6 100644
--- a/arch/x86/kernel/kexec-bzimage64.c
+++ b/arch/x86/kernel/kexec-bzimage64.c
@@ -626,19 +626,13 @@ static void *bzImage64_load(struct kimage *image, char *kernel,
/* Load initrd high */
if (initrd) {
- kbuf.buffer = initrd;
- kbuf.bufsz = kbuf.memsz = initrd_len;
kbuf.buf_align = PAGE_SIZE;
kbuf.buf_min = MIN_INITRD_LOAD_ADDR;
- kbuf.mem = KEXEC_BUF_MEM_UNKNOWN;
- ret = kexec_add_buffer(&kbuf);
+ ret = kexec_add_initrd(image, &kbuf);
if (ret)
goto out_free_params;
initrd_load_addr = kbuf.mem;
- kexec_dprintk("Loaded initrd at 0x%lx bufsz=0x%lx memsz=0x%lx\n",
- initrd_load_addr, initrd_len, initrd_len);
-
setup_initrd(params, initrd_load_addr, initrd_len);
}
--
2.34.1
^ permalink raw reply related [flat|nested] 23+ messages in thread* Re: [PATCH v8 06/11] x86: kexec_file: Use the common segment helpers
2026-11-12 13:34 ` [PATCH v8 06/11] x86: kexec_file: Use the common segment helpers Jinjie Ruan
@ 2026-11-12 14:08 ` sashiko-bot
0 siblings, 0 replies; 23+ messages in thread
From: sashiko-bot @ 2026-11-12 14:08 UTC (permalink / raw)
To: Jinjie Ruan, catalin.marinas, will, mark.rutland, chenhuacai,
kernel, maddy, mpe, npiggin, chleroy, ritesh.list, sshegde, pjw,
palmer, aou, alex, tglx, mingo, bp, dave.hansen, hpa, akpm,
baoquan.he, rppt, pasha.tatashin, pratyush, leitao, yeoreum.yun,
mpilaniy, robh, coiby.xu, Yeking, prudo, brads, sourabhjain,
mkchauras, blum, adityag, qirui.001, hui.wang, sohammetha01,
guoren, gaohan, ionut.nechita, vishal.l.verma, seanjc, ardb,
richard.lyu, arnd, tzimmermann, rick.p.edgecombe, kai.huang, kas,
piliu, thuth, shradhagupta, ebiggers, jbouron, me, mclapinski,
graf, tangyouling, x86, kexec
Thank you for your contribution! Sashiko AI review found 1 potential
issue to consider:
- [High] x86/crash: unset elfcorehdr_index in crash_load_segments()
breaks hotplug
--
commit 1b8e09baefdcc28fe15998b5723b09d361d15f6e
Author: Jinjie Ruan <ruanjinjie@huawei.com>
x86: kexec_file: Use the common segment helpers
This commit replaces open-coded ELF core header and initrd segment loading
in x86 kexec_file with the common kexec_prepare_elf_core_header(),
kexec_add_elf_core_header(), and kexec_add_initrd() helpers.
> diff --git a/arch/x86/kernel/crash.c b/arch/x86/kernel/crash.c
> index e6f23933a6df2..8d56d39ebbd53 100644
> --- a/arch/x86/kernel/crash.c
> +++ b/arch/x86/kernel/crash.c
> @@ -354,14 +354,12 @@ int crash_load_segments(struct kimage *image)
> .buf_max = ULONG_MAX, .top_down = false };
>
> /* Prepare elf headers and add a segment */
> - ret = crash_prepare_headers(IS_ENABLED(CONFIG_X86_64), &kbuf.buffer,
> - &kbuf.bufsz, &pnum);
> + ret = kexec_prepare_elf_core_header(image, IS_ENABLED(CONFIG_X86_64),
> + &pnum);
> if (ret)
> return ret;
>
> - image->elf_headers = kbuf.buffer;
> - image->elf_headers_sz = kbuf.bufsz;
> - kbuf.memsz = kbuf.bufsz;
> + kbuf.memsz = image->elf_headers_sz;
>
> #ifdef CONFIG_CRASH_HOTPLUG
> /*
> @@ -374,28 +372,15 @@ int crash_load_segments(struct kimage *image)
> pnum += 2 + CONFIG_NR_CPUS;
>
> if (pnum < (unsigned long)PN_XNUM) {
> - kbuf.memsz = pnum * sizeof(Elf64_Phdr);
> - kbuf.memsz += sizeof(Elf64_Ehdr);
> -
> - image->elfcorehdr_index = image->nr_segments;
> -
> - /* Mark as usable to crash kernel, else crash kernel fails on boot */
> - image->elf_headers_sz = kbuf.memsz;
> + kbuf.memsz = pnum * sizeof(Elf64_Phdr) + sizeof(Elf64_Ehdr);
> } else {
> pr_err("number of Phdrs %lu exceeds max\n", pnum);
> }
> #endif
>
> kbuf.buf_align = ELF_CORE_HEADER_ALIGN;
> - kbuf.mem = KEXEC_BUF_MEM_UNKNOWN;
> - ret = kexec_add_buffer(&kbuf);
> - if (ret)
> - return ret;
> - image->elf_load_addr = kbuf.mem;
> - kexec_dprintk("Loaded ELF headers at 0x%lx bufsz=0x%lx memsz=0x%lx\n",
> - image->elf_load_addr, kbuf.bufsz, kbuf.memsz);
>
> - return ret;
> + return kexec_add_elf_core_header(image, &kbuf);
> }
[Severity: High]
Can this leave image->elfcorehdr_index unset (-1) when CONFIG_CRASH_HOTPLUG
is enabled?
kexec_prepare_elf_core_header() -> crash_prepare_headers() ->
crash_prepare_elf64_headers() aligns image->elf_headers_sz up to
ELF_CORE_HEADER_ALIGN (4096), whereas crash_load_segments() computes an
unaligned kbuf.memsz for the hotplug reservation. In
kexec_add_elf_core_header(), image->elfcorehdr_index is only updated when
memsz strictly exceeds image->elf_headers_sz:
kernel/kexec_file.c:kexec_add_elf_core_header() {
...
/* The crash hotplug reservation can exceed the header size. */
if (memsz > image->elf_headers_sz) {
image->elf_headers_sz = memsz;
#ifdef CONFIG_CRASH_HOTPLUG
image->elfcorehdr_index = image->nr_segments - 1;
#endif
}
...
}
Whenever the unaligned hotplug kbuf.memsz fits within the same 4096-byte
multiple as the initial header (for example, when CONFIG_MEMORY_HOTPLUG is
disabled and CONFIG_NR_CPUS equals num_possible_cpus()), memsz <=
image->elf_headers_sz and image->elfcorehdr_index remains -1.
kexec_calculate_store_digests() then includes the elfcorehdr segment in the
purgatory SHA-256 digest, so any later CPU or memory hotplug update to
elfcorehdr causes purgatory digest verification to fail on crash.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261112133418.4044428-1-ruanjinjie@huawei.com?part=6
^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH v8 07/11] powerpc: kexec_file: Use the common segment helpers
2026-11-12 13:34 [PATCH v8 00/11] kexec: Rework segment loading and fix CMA retries Jinjie Ruan
` (5 preceding siblings ...)
2026-11-12 13:34 ` [PATCH v8 06/11] x86: kexec_file: Use the common segment helpers Jinjie Ruan
@ 2026-11-12 13:34 ` Jinjie Ruan
2026-11-12 14:01 ` sashiko-bot
2026-11-12 13:34 ` [PATCH v8 08/11] kexec: Extract kexec_free_segment_cma() from kimage_free_cma() Jinjie Ruan
` (3 subsequent siblings)
10 siblings, 1 reply; 23+ messages in thread
From: Jinjie Ruan @ 2026-11-12 13:34 UTC (permalink / raw)
To: catalin.marinas, will, mark.rutland, chenhuacai, kernel, maddy,
mpe, npiggin, chleroy, ritesh.list, sshegde, pjw, palmer, aou,
alex, tglx, mingo, bp, dave.hansen, hpa, akpm, baoquan.he, rppt,
pasha.tatashin, pratyush, ruanjinjie, leitao, yeoreum.yun,
mpilaniy, robh, coiby.xu, Yeking, prudo, brads, sourabhjain,
mkchauras, blum, adityag, qirui.001, hui.wang, sohammetha01,
guoren, gaohan, ionut.nechita, vishal.l.verma, seanjc, ardb,
richard.lyu, arnd, tzimmermann, rick.p.edgecombe, kai.huang, kas,
piliu, thuth, shradhagupta, ebiggers, jbouron, me, mclapinski,
graf, tangyouling, x86, linux-arm-kernel, linux-kernel, loongarch,
linuxppc-dev, linux-riscv, kexec
load_elfcorehdr_segment() builds the elf core header from the powerpc
crash memory ranges and places it as a segment. The header needs
powerpc specific post processing, so keep building it here, but use
kexec_add_elf_core_header() to place it.
elf64_load() also loads the initrd by hand, use kexec_add_initrd()
for it.
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Nicholas Piggin <npiggin@gmail.com>
Cc: Christophe Leroy <chleroy@kernel.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Baoquan He <baoquan.he@linux.dev>
Cc: Mike Rapoport <rppt@kernel.org>
Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>
---
arch/powerpc/kexec/elf_64.c | 9 ++-------
arch/powerpc/kexec/file_load_64.c | 14 ++++----------
2 files changed, 6 insertions(+), 17 deletions(-)
diff --git a/arch/powerpc/kexec/elf_64.c b/arch/powerpc/kexec/elf_64.c
index d9a466cd602e..1ef444494641 100644
--- a/arch/powerpc/kexec/elf_64.c
+++ b/arch/powerpc/kexec/elf_64.c
@@ -96,18 +96,13 @@ static void *elf64_load(struct kimage *image, char *kernel_buf,
kexec_dprintk("Command line: %s", cmdline ? cmdline : "");
- if (initrd != NULL) {
- kbuf.buffer = initrd;
- kbuf.bufsz = kbuf.memsz = initrd_len;
+ if (initrd) {
kbuf.buf_align = PAGE_SIZE;
kbuf.top_down = false;
- kbuf.mem = KEXEC_BUF_MEM_UNKNOWN;
- ret = kexec_add_buffer(&kbuf);
+ ret = kexec_add_initrd(image, &kbuf);
if (ret)
goto out;
initrd_load_addr = kbuf.mem;
-
- kexec_dprintk("Loaded initrd at 0x%lx\n", initrd_load_addr);
}
ret = get_reserved_memory_ranges(&rmem);
diff --git a/arch/powerpc/kexec/file_load_64.c b/arch/powerpc/kexec/file_load_64.c
index 0cf03cee35a7..77652db7d1ca 100644
--- a/arch/powerpc/kexec/file_load_64.c
+++ b/arch/powerpc/kexec/file_load_64.c
@@ -416,9 +416,8 @@ static int load_elfcorehdr_segment(struct kimage *image, struct kexec_buf *kbuf)
/* Fix the offset for backup region in the ELF header */
sync_backup_region_phdr(image, headers, false);
- kbuf->buffer = headers;
- kbuf->mem = KEXEC_BUF_MEM_UNKNOWN;
- kbuf->bufsz = headers_sz;
+ image->elf_headers = headers;
+ image->elf_headers_sz = headers_sz;
/*
* Account for extra space required to accommodate additional memory
@@ -427,13 +426,9 @@ static int load_elfcorehdr_segment(struct kimage *image, struct kexec_buf *kbuf)
kbuf->memsz = headers_sz + kdump_extra_elfcorehdr_size(cmem);
kbuf->top_down = false;
- ret = kexec_add_buffer(kbuf);
- if (ret) {
- vfree(headers);
+ ret = kexec_add_elf_core_header(image, kbuf);
+ if (ret)
goto out;
- }
-
- image->elf_load_addr = kbuf->mem;
/*
* If CONFIG_CRASH_HOTPLUG is enabled, the elfcorehdr kexec segment
@@ -442,7 +437,6 @@ static int load_elfcorehdr_segment(struct kimage *image, struct kexec_buf *kbuf)
* memory in the FDT prepared for kdump.
*/
image->elf_headers_sz = kbuf->memsz;
- image->elf_headers = headers;
out:
kfree(cmem);
return ret;
--
2.34.1
^ permalink raw reply related [flat|nested] 23+ messages in thread* Re: [PATCH v8 07/11] powerpc: kexec_file: Use the common segment helpers
2026-11-12 13:34 ` [PATCH v8 07/11] powerpc: " Jinjie Ruan
@ 2026-11-12 14:01 ` sashiko-bot
0 siblings, 0 replies; 23+ messages in thread
From: sashiko-bot @ 2026-11-12 14:01 UTC (permalink / raw)
To: Jinjie Ruan, catalin.marinas, will, mark.rutland, chenhuacai,
kernel, maddy, mpe, npiggin, chleroy, ritesh.list, sshegde, pjw,
palmer, aou, alex, tglx, mingo, bp, dave.hansen, hpa, akpm,
baoquan.he, rppt, pasha.tatashin, pratyush, leitao, yeoreum.yun,
mpilaniy, robh, coiby.xu, Yeking, prudo, brads, sourabhjain,
mkchauras, blum, adityag, qirui.001, hui.wang, sohammetha01,
guoren, gaohan, ionut.nechita, vishal.l.verma, seanjc, ardb,
richard.lyu, arnd, tzimmermann, rick.p.edgecombe, kai.huang, kas,
piliu, thuth, shradhagupta, ebiggers, jbouron, me, mclapinski,
graf, tangyouling, x86, kexec
> load_elfcorehdr_segment() builds the elf core header from the powerpc
> crash memory ranges and places it as a segment. The header needs
> powerpc specific post processing, so keep building it here, but use
> kexec_add_elf_core_header() to place it.
>
> elf64_load() also loads the initrd by hand, use kexec_add_initrd()
> for it.
>
> Cc: Michael Ellerman <mpe@ellerman.id.au>
> Cc: Nicholas Piggin <npiggin@gmail.com>
> Cc: Christophe Leroy <chleroy@kernel.org>
> Cc: Andrew Morton <akpm@linux-foundation.org>
> Cc: Baoquan He <baoquan.he@linux.dev>
> Cc: Mike Rapoport <rppt@kernel.org>
> Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>
Sashiko has reviewed this patch and found no issues.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261112133418.4044428-1-ruanjinjie@huawei.com?part=7
^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH v8 08/11] kexec: Extract kexec_free_segment_cma() from kimage_free_cma()
2026-11-12 13:34 [PATCH v8 00/11] kexec: Rework segment loading and fix CMA retries Jinjie Ruan
` (6 preceding siblings ...)
2026-11-12 13:34 ` [PATCH v8 07/11] powerpc: " Jinjie Ruan
@ 2026-11-12 13:34 ` Jinjie Ruan
2026-11-12 14:07 ` sashiko-bot
2026-11-12 13:34 ` [PATCH v8 09/11] kexec: Add kexec_rollback_segments() helper Jinjie Ruan
` (2 subsequent siblings)
10 siblings, 1 reply; 23+ messages in thread
From: Jinjie Ruan @ 2026-11-12 13:34 UTC (permalink / raw)
To: catalin.marinas, will, mark.rutland, chenhuacai, kernel, maddy,
mpe, npiggin, chleroy, ritesh.list, sshegde, pjw, palmer, aou,
alex, tglx, mingo, bp, dave.hansen, hpa, akpm, baoquan.he, rppt,
pasha.tatashin, pratyush, ruanjinjie, leitao, yeoreum.yun,
mpilaniy, robh, coiby.xu, Yeking, prudo, brads, sourabhjain,
mkchauras, blum, adityag, qirui.001, hui.wang, sohammetha01,
guoren, gaohan, ionut.nechita, vishal.l.verma, seanjc, ardb,
richard.lyu, arnd, tzimmermann, rick.p.edgecombe, kai.huang, kas,
piliu, thuth, shradhagupta, ebiggers, jbouron, me, mclapinski,
graf, tangyouling, x86, linux-arm-kernel, linux-kernel, loongarch,
linuxppc-dev, linux-riscv, kexec
Arch loaders truncate nr_segments when a placement fails, so the CMA
pages of the dropped segments become unreachable. Export a per-segment
helper so they can be released first.
No functional change intended.
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Baoquan He <baoquan.he@linux.dev>
Cc: Mike Rapoport <rppt@kernel.org>
Cc: Pasha Tatashin <pasha.tatashin@soleen.com>
Cc: Pratyush Yadav <pratyush@kernel.org>
Cc: Breno Leitao <leitao@debian.org>
Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>
---
include/linux/kexec.h | 2 ++
kernel/kexec_core.c | 25 ++++++++++++++-----------
2 files changed, 16 insertions(+), 11 deletions(-)
diff --git a/include/linux/kexec.h b/include/linux/kexec.h
index 89cb47521d6d..be7c827e8f7e 100644
--- a/include/linux/kexec.h
+++ b/include/linux/kexec.h
@@ -529,6 +529,7 @@ extern bool kexec_file_dbg_print;
extern void *kimage_map_segment(struct kimage *image, int idx);
extern void kimage_unmap_segment(void *buffer);
+void kexec_free_segment_cma(struct kimage *image, unsigned long idx);
#else /* !CONFIG_KEXEC_CORE */
struct pt_regs;
struct task_struct;
@@ -540,6 +541,7 @@ static inline int kexec_crash_loaded(void) { return 0; }
static inline void *kimage_map_segment(struct kimage *image, int idx)
{ return NULL; }
static inline void kimage_unmap_segment(void *buffer) { }
+static inline void kexec_free_segment_cma(struct kimage *image, unsigned long idx) { }
#define kexec_in_progress false
static inline bool kexec_is_in_progress(void) { return false; }
#endif /* CONFIG_KEXEC_CORE */
diff --git a/kernel/kexec_core.c b/kernel/kexec_core.c
index f4a31565c447..03b396869e34 100644
--- a/kernel/kexec_core.c
+++ b/kernel/kexec_core.c
@@ -571,22 +571,25 @@ static void kimage_free_entry(kimage_entry_t entry)
kimage_free_pages(page);
}
-static void kimage_free_cma(struct kimage *image)
+void kexec_free_segment_cma(struct kimage *image, unsigned long idx)
{
- unsigned long i;
+ u32 nr_pages = image->segment[idx].memsz >> PAGE_SHIFT;
+ struct page *cma = image->segment_cma[idx];
- for (i = 0; i < image->nr_segments; i++) {
- struct page *cma = image->segment_cma[i];
- u32 nr_pages = image->segment[i].memsz >> PAGE_SHIFT;
+ if (!cma)
+ return;
- if (!cma)
- continue;
+ arch_kexec_pre_free_pages(page_address(cma), nr_pages);
+ dma_release_from_contiguous(NULL, cma, nr_pages);
+ image->segment_cma[idx] = NULL;
+}
- arch_kexec_pre_free_pages(page_address(cma), nr_pages);
- dma_release_from_contiguous(NULL, cma, nr_pages);
- image->segment_cma[i] = NULL;
- }
+static void kimage_free_cma(struct kimage *image)
+{
+ unsigned long i;
+ for (i = 0; i < image->nr_segments; i++)
+ kexec_free_segment_cma(image, i);
}
void kimage_free(struct kimage *image)
--
2.34.1
^ permalink raw reply related [flat|nested] 23+ messages in thread* Re: [PATCH v8 08/11] kexec: Extract kexec_free_segment_cma() from kimage_free_cma()
2026-11-12 13:34 ` [PATCH v8 08/11] kexec: Extract kexec_free_segment_cma() from kimage_free_cma() Jinjie Ruan
@ 2026-11-12 14:07 ` sashiko-bot
0 siblings, 0 replies; 23+ messages in thread
From: sashiko-bot @ 2026-11-12 14:07 UTC (permalink / raw)
To: Jinjie Ruan, catalin.marinas, will, mark.rutland, chenhuacai,
kernel, maddy, mpe, npiggin, chleroy, ritesh.list, sshegde, pjw,
palmer, aou, alex, tglx, mingo, bp, dave.hansen, hpa, akpm,
baoquan.he, rppt, pasha.tatashin, pratyush, leitao, yeoreum.yun,
mpilaniy, robh, coiby.xu, Yeking, prudo, brads, sourabhjain,
mkchauras, blum, adityag, qirui.001, hui.wang, sohammetha01,
guoren, gaohan, ionut.nechita, vishal.l.verma, seanjc, ardb,
richard.lyu, arnd, tzimmermann, rick.p.edgecombe, kai.huang, kas,
piliu, thuth, shradhagupta, ebiggers, jbouron, me, mclapinski,
graf, tangyouling, x86, kexec
> Arch loaders truncate nr_segments when a placement fails, so the CMA
> pages of the dropped segments become unreachable. Export a per-segment
> helper so they can be released first.
>
> No functional change intended.
>
> Cc: Andrew Morton <akpm@linux-foundation.org>
> Cc: Baoquan He <baoquan.he@linux.dev>
> Cc: Mike Rapoport <rppt@kernel.org>
> Cc: Pasha Tatashin <pasha.tatashin@soleen.com>
> Cc: Pratyush Yadav <pratyush@kernel.org>
> Cc: Breno Leitao <leitao@debian.org>
> Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>
Sashiko has reviewed this patch and found no issues.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261112133418.4044428-1-ruanjinjie@huawei.com?part=8
^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH v8 09/11] kexec: Add kexec_rollback_segments() helper
2026-11-12 13:34 [PATCH v8 00/11] kexec: Rework segment loading and fix CMA retries Jinjie Ruan
` (7 preceding siblings ...)
2026-11-12 13:34 ` [PATCH v8 08/11] kexec: Extract kexec_free_segment_cma() from kimage_free_cma() Jinjie Ruan
@ 2026-11-12 13:34 ` Jinjie Ruan
2026-11-12 14:15 ` sashiko-bot
2026-11-12 13:34 ` [PATCH v8 10/11] arm64: kexec_file: Fix CMA segment placement retries Jinjie Ruan
2026-11-12 13:34 ` [PATCH v8 11/11] LoongArch: " Jinjie Ruan
10 siblings, 1 reply; 23+ messages in thread
From: Jinjie Ruan @ 2026-11-12 13:34 UTC (permalink / raw)
To: catalin.marinas, will, mark.rutland, chenhuacai, kernel, maddy,
mpe, npiggin, chleroy, ritesh.list, sshegde, pjw, palmer, aou,
alex, tglx, mingo, bp, dave.hansen, hpa, akpm, baoquan.he, rppt,
pasha.tatashin, pratyush, ruanjinjie, leitao, yeoreum.yun,
mpilaniy, robh, coiby.xu, Yeking, prudo, brads, sourabhjain,
mkchauras, blum, adityag, qirui.001, hui.wang, sohammetha01,
guoren, gaohan, ionut.nechita, vishal.l.verma, seanjc, ardb,
richard.lyu, arnd, tzimmermann, rick.p.edgecombe, kai.huang, kas,
piliu, thuth, shradhagupta, ebiggers, jbouron, me, mclapinski,
graf, tangyouling, x86, linux-arm-kernel, linux-kernel, loongarch,
linuxppc-dev, linux-riscv, kexec
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@linux-foundation.org>
Cc: Baoquan He <baoquan.he@linux.dev>
Cc: Mike Rapoport <rppt@kernel.org>
Suggested-by: Mike Rapoport <rppt@kernel.org>
Signed-off-by: Jinjie Ruan <ruanjinjie@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
^ permalink raw reply related [flat|nested] 23+ messages in thread* Re: [PATCH v8 09/11] kexec: Add kexec_rollback_segments() helper
2026-11-12 13:34 ` [PATCH v8 09/11] kexec: Add kexec_rollback_segments() helper Jinjie Ruan
@ 2026-11-12 14:15 ` sashiko-bot
0 siblings, 0 replies; 23+ messages in thread
From: sashiko-bot @ 2026-11-12 14:15 UTC (permalink / raw)
To: Jinjie Ruan, catalin.marinas, will, mark.rutland, chenhuacai,
kernel, maddy, mpe, npiggin, chleroy, ritesh.list, sshegde, pjw,
palmer, aou, alex, tglx, mingo, bp, dave.hansen, hpa, akpm,
baoquan.he, rppt, pasha.tatashin, pratyush, leitao, yeoreum.yun,
mpilaniy, robh, coiby.xu, Yeking, prudo, brads, sourabhjain,
mkchauras, blum, adityag, qirui.001, hui.wang, sohammetha01,
guoren, gaohan, ionut.nechita, vishal.l.verma, seanjc, ardb,
richard.lyu, arnd, tzimmermann, rick.p.edgecombe, kai.huang, kas,
piliu, thuth, shradhagupta, ebiggers, jbouron, me, mclapinski,
graf, tangyouling, x86, kexec
Thank you for your contribution! Sashiko AI review found 1 potential
issue to consider:
- [Medium] kexec: missing elfcorehdr_index invalidation in
kexec_rollback_segments()
--
commit 67c30192060172d9e9af6c0433ce26a5bea934f3
Author: Jinjie Ruan <ruanjinjie@huawei.com>
kexec: Add kexec_rollback_segments() helper
This commit adds a kexec_rollback_segments() helper to release CMA pages
and truncate image->nr_segments when rolling back a partial load attempt.
> diff --git a/kernel/kexec_file.c b/kernel/kexec_file.c
> index 25c9bef639d27..b4fe5c4188421 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--;
> + }
> +}
[Severity: Medium]
Does kexec_rollback_segments() leave a stale image->elfcorehdr_index when
the ELF core header segment is among the dropped segments?
The commit message notes that the helper invalidates the recorded
elfcorehdr segment index when dropped, but the implementation does not
reset image->elfcorehdr_index to -1. Moreover, kexec_add_elf_core_header()
only records image->elfcorehdr_index when memsz > image->elf_headers_sz
and updates image->elf_headers_sz on the first attempt:
kernel/kexec_file.c:kexec_add_elf_core_header() {
...
if (memsz > image->elf_headers_sz) {
image->elf_headers_sz = memsz;
#ifdef CONFIG_CRASH_HOTPLUG
image->elfcorehdr_index = image->nr_segments - 1;
#endif
}
...
}
If a rollback drops the ELF core header segment, a retry sees
memsz == image->elf_headers_sz and leaves the old index in place, causing
kexec_calculate_store_digests() and handle_hotplug_event() to skip or
reference the wrong segment.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261112133418.4044428-1-ruanjinjie@huawei.com?part=9
^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH v8 10/11] arm64: kexec_file: Fix CMA segment placement retries
2026-11-12 13:34 [PATCH v8 00/11] kexec: Rework segment loading and fix CMA retries Jinjie Ruan
` (8 preceding siblings ...)
2026-11-12 13:34 ` [PATCH v8 09/11] kexec: Add kexec_rollback_segments() helper Jinjie Ruan
@ 2026-11-12 13:34 ` Jinjie Ruan
2026-11-12 14:14 ` sashiko-bot
2026-11-12 13:34 ` [PATCH v8 11/11] LoongArch: " Jinjie Ruan
10 siblings, 1 reply; 23+ messages in thread
From: Jinjie Ruan @ 2026-11-12 13:34 UTC (permalink / raw)
To: catalin.marinas, will, mark.rutland, chenhuacai, kernel, maddy,
mpe, npiggin, chleroy, ritesh.list, sshegde, pjw, palmer, aou,
alex, tglx, mingo, bp, dave.hansen, hpa, akpm, baoquan.he, rppt,
pasha.tatashin, pratyush, ruanjinjie, leitao, yeoreum.yun,
mpilaniy, robh, coiby.xu, Yeking, prudo, brads, sourabhjain,
mkchauras, blum, adityag, qirui.001, hui.wang, sohammetha01,
guoren, gaohan, ionut.nechita, vishal.l.verma, seanjc, ardb,
richard.lyu, arnd, tzimmermann, rick.p.edgecombe, kai.huang, kas,
piliu, thuth, shradhagupta, ebiggers, jbouron, me, mclapinski,
graf, tangyouling, x86, linux-arm-kernel, linux-kernel, loongarch,
linuxppc-dev, linux-riscv, kexec
The file-based kexec system call places segments with kexec_add_buffer(),
which takes them from CMA when kexec_alloc_contig() succeeds, to avoid
copying the payload at kexec time.
When load_other_segments() cannot place the initrd or the DTB, the
segments of the attempt are dropped but their CMA pages are leaked.
Release them with kexec_rollback_segments() in the retry loop and in the
error path of load_other_segments().
The loop makes progress by advancing buf_min past a segment placed by the
walk. kexec_alloc_contig() ignores buf_min, so once the pages of a CMA
segment are released, the next attempt can get the same region again and
the retry makes no progress. Disable CMA for the retry.
A CMA segment can be anywhere in RAM, so moving buf_min to its end can
raise the walk's lower bound close to the top of memory and leave the
retry with too little space for the initrd and DTB, failing with
-EADDRNOTAVAIL. Only advance buf_min for segments found by the walk.
Tested with a non-crash kexec_file_load() on QEMU virt, 1 GiB RAM and
cma=64M, which places CMA at the top of RAM.
Before the fix:
The retry leaks the CMA pages and kexec_file_load() returns
-EADDRNOTAVAIL even though RAM below CMA is free.
After the fix:
The kernel and initrd are placed below CMA and the second
kernel boots.
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will@kernel.org>
Cc: Breno Leitao <leitao@debian.org>
Cc: Pratyush Yadav <pratyush@kernel.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Yeoreum Yun <yeoreum.yun@arm.com>
Cc: Baoquan He <bhe@redhat.com>
Cc: stable@vger.kernel.org
Fixes: 07d24902977e ("kexec: enable CMA based contiguous allocation")
Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>
---
arch/arm64/kernel/kexec_image.c | 12 ++++++++----
arch/arm64/kernel/machine_kexec_file.c | 2 +-
2 files changed, 9 insertions(+), 5 deletions(-)
diff --git a/arch/arm64/kernel/kexec_image.c b/arch/arm64/kernel/kexec_image.c
index a2a7c283b331..1cbb3c73c6e9 100644
--- a/arch/arm64/kernel/kexec_image.c
+++ b/arch/arm64/kernel/kexec_image.c
@@ -109,11 +109,15 @@ static void *image_load(struct kimage *image,
break;
/*
- * We couldn't find space for the other segments; erase the
- * kernel segment and try the next available hole.
+ * kexec_alloc_contig() ignores buf_min and always returns
+ * CMA memory, so disable it and keep buf_min.
*/
- image->nr_segments -= 1;
- kbuf.buf_min = kernel_segment->mem + kernel_segment->memsz;
+ if (image->segment_cma[kernel_segment_number])
+ image->no_cma = true;
+ else
+ kbuf.buf_min = kernel_segment->mem + kernel_segment->memsz;
+
+ kexec_rollback_segments(image, kernel_segment_number);
kbuf.mem = KEXEC_BUF_MEM_UNKNOWN;
}
diff --git a/arch/arm64/kernel/machine_kexec_file.c b/arch/arm64/kernel/machine_kexec_file.c
index 82122ded1467..8747daa23079 100644
--- a/arch/arm64/kernel/machine_kexec_file.c
+++ b/arch/arm64/kernel/machine_kexec_file.c
@@ -132,7 +132,7 @@ int load_other_segments(struct kimage *image, unsigned long kernel_load_addr,
return 0;
out_err:
- image->nr_segments = orig_segments;
+ kexec_rollback_segments(image, orig_segments);
kvfree(dtb);
return ret;
}
--
2.34.1
^ permalink raw reply related [flat|nested] 23+ messages in thread* Re: [PATCH v8 10/11] arm64: kexec_file: Fix CMA segment placement retries
2026-11-12 13:34 ` [PATCH v8 10/11] arm64: kexec_file: Fix CMA segment placement retries Jinjie Ruan
@ 2026-11-12 14:14 ` sashiko-bot
0 siblings, 0 replies; 23+ messages in thread
From: sashiko-bot @ 2026-11-12 14:14 UTC (permalink / raw)
To: Jinjie Ruan, catalin.marinas, will, mark.rutland, chenhuacai,
kernel, maddy, mpe, npiggin, chleroy, ritesh.list, sshegde, pjw,
palmer, aou, alex, tglx, mingo, bp, dave.hansen, hpa, akpm,
baoquan.he, rppt, pasha.tatashin, pratyush, leitao, yeoreum.yun,
mpilaniy, robh, coiby.xu, Yeking, prudo, brads, sourabhjain,
mkchauras, blum, adityag, qirui.001, hui.wang, sohammetha01,
guoren, gaohan, ionut.nechita, vishal.l.verma, seanjc, ardb,
richard.lyu, arnd, tzimmermann, rick.p.edgecombe, kai.huang, kas,
piliu, thuth, shradhagupta, ebiggers, jbouron, me, mclapinski,
graf, tangyouling, x86, kexec
> The file-based kexec system call places segments with kexec_add_buffer(),
> which takes them from CMA when kexec_alloc_contig() succeeds, to avoid
> copying the payload at kexec time.
>
> When load_other_segments() cannot place the initrd or the DTB, the
> segments of the attempt are dropped but their CMA pages are leaked.
> Release them with kexec_rollback_segments() in the retry loop and in the
> error path of load_other_segments().
>
> The loop makes progress by advancing buf_min past a segment placed by the
> walk. kexec_alloc_contig() ignores buf_min, so once the pages of a CMA
> segment are released, the next attempt can get the same region again and
> the retry makes no progress. Disable CMA for the retry.
>
> A CMA segment can be anywhere in RAM, so moving buf_min to its end can
> [ ... ]
> Cc: Yeoreum Yun <yeoreum.yun@arm.com>
> Cc: Baoquan He <bhe@redhat.com>
> Cc: stable@vger.kernel.org
> Fixes: 07d24902977e ("kexec: enable CMA based contiguous allocation")
> Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>
Sashiko has reviewed this patch and found no issues.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261112133418.4044428-1-ruanjinjie@huawei.com?part=10
^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH v8 11/11] LoongArch: kexec_file: Fix CMA segment placement retries
2026-11-12 13:34 [PATCH v8 00/11] kexec: Rework segment loading and fix CMA retries Jinjie Ruan
` (9 preceding siblings ...)
2026-11-12 13:34 ` [PATCH v8 10/11] arm64: kexec_file: Fix CMA segment placement retries Jinjie Ruan
@ 2026-11-12 13:34 ` Jinjie Ruan
2026-11-12 14:21 ` sashiko-bot
10 siblings, 1 reply; 23+ messages in thread
From: Jinjie Ruan @ 2026-11-12 13:34 UTC (permalink / raw)
To: catalin.marinas, will, mark.rutland, chenhuacai, kernel, maddy,
mpe, npiggin, chleroy, ritesh.list, sshegde, pjw, palmer, aou,
alex, tglx, mingo, bp, dave.hansen, hpa, akpm, baoquan.he, rppt,
pasha.tatashin, pratyush, ruanjinjie, leitao, yeoreum.yun,
mpilaniy, robh, coiby.xu, Yeking, prudo, brads, sourabhjain,
mkchauras, blum, adityag, qirui.001, hui.wang, sohammetha01,
guoren, gaohan, ionut.nechita, vishal.l.verma, seanjc, ardb,
richard.lyu, arnd, tzimmermann, rick.p.edgecombe, kai.huang, kas,
piliu, thuth, shradhagupta, ebiggers, jbouron, me, mclapinski,
graf, tangyouling, x86, linux-arm-kernel, linux-kernel, loongarch,
linuxppc-dev, linux-riscv, kexec
The file-based kexec system call places segments with kexec_add_buffer(),
which takes them from CMA when kexec_alloc_contig() succeeds, to avoid
copying the payload at kexec time.
When load_other_segments() cannot place the initrd, the segments of the
attempt are dropped but their CMA pages are leaked. Release them with
kexec_rollback_segments() in the retry loop and in the error path of
load_other_segments().
The loop makes progress by advancing buf_min past a segment placed by the
walk. kexec_alloc_contig() ignores buf_min, so once the pages of a CMA
segment are released, the next attempt can get the same region again and
the retry makes no progress. Disable CMA for the retry.
A CMA segment can be anywhere in RAM, so moving buf_min to its end can
raise the walk's lower bound close to the top of memory and leave the
retry with too little space for the initrd, failing with -EADDRNOTAVAIL.
Only advance buf_min for segments found by the walk.
Tested with a non-crash kexec_file_load() on QEMU virt, 2 GiB RAM and
cma=64M@0xe8000000, which leaves only 64 MiB above the CMA area.
Before the fix:
The retry leaks the CMA pages and kexec_file_load() returns
-EADDRNOTAVAIL even though RAM below CMA is free.
After the fix:
The kernel and initrd are placed below CMA and the second
kernel boots.
Cc: Huacai Chen <chenhuacai@kernel.org>
Cc: WANG Xuerui <kernel@xen0n.name>
Cc: Youling Tang <tangyouling@kylinos.cn>
Cc: Mike Rapoport (Microsoft) <rppt@kernel.org>
Cc: Sourabh Jain <sourabhjain@linux.ibm.com>
Cc: Kees Cook <kees@kernel.org>
Cc: stable@vger.kernel.org
Link: https://sashiko.dev/#/patchset/20260729031235.2840255-1-ruanjinjie%40huawei.com
Fixes: 55d990f0084c ("LoongArch: Add EFI binary support for kexec_file")
Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>
---
arch/loongarch/kernel/kexec_efi.c | 12 ++++++++----
arch/loongarch/kernel/machine_kexec_file.c | 2 +-
2 files changed, 9 insertions(+), 5 deletions(-)
diff --git a/arch/loongarch/kernel/kexec_efi.c b/arch/loongarch/kernel/kexec_efi.c
index 4824c47907ac..1fbd0ee1deb6 100644
--- a/arch/loongarch/kernel/kexec_efi.c
+++ b/arch/loongarch/kernel/kexec_efi.c
@@ -82,11 +82,15 @@ static void *efi_kexec_load(struct kimage *image,
break;
/*
- * We couldn't find space for the other segments; erase the
- * kernel segment and try the next available hole.
+ * kexec_alloc_contig() ignores buf_min and always returns
+ * CMA memory, so disable it and keep buf_min.
*/
- image->nr_segments -= 1;
- kbuf.buf_min = kernel_segment->mem + kernel_segment->memsz;
+ if (image->segment_cma[kernel_segment_number])
+ image->no_cma = true;
+ else
+ kbuf.buf_min = kernel_segment->mem + kernel_segment->memsz;
+
+ kexec_rollback_segments(image, kernel_segment_number);
kbuf.mem = KEXEC_BUF_MEM_UNKNOWN;
}
diff --git a/arch/loongarch/kernel/machine_kexec_file.c b/arch/loongarch/kernel/machine_kexec_file.c
index 5a3d5026303e..0341dfd04b1f 100644
--- a/arch/loongarch/kernel/machine_kexec_file.c
+++ b/arch/loongarch/kernel/machine_kexec_file.c
@@ -191,7 +191,7 @@ int load_other_segments(struct kimage *image,
return 0;
out_err:
- image->nr_segments = orig_segments;
+ kexec_rollback_segments(image, orig_segments);
kfree(modified_cmdline);
return ret;
}
--
2.34.1
^ permalink raw reply related [flat|nested] 23+ messages in thread* Re: [PATCH v8 11/11] LoongArch: kexec_file: Fix CMA segment placement retries
2026-11-12 13:34 ` [PATCH v8 11/11] LoongArch: " Jinjie Ruan
@ 2026-11-12 14:21 ` sashiko-bot
0 siblings, 0 replies; 23+ messages in thread
From: sashiko-bot @ 2026-11-12 14:21 UTC (permalink / raw)
To: Jinjie Ruan, catalin.marinas, will, mark.rutland, chenhuacai,
kernel, maddy, mpe, npiggin, chleroy, ritesh.list, sshegde, pjw,
palmer, aou, alex, tglx, mingo, bp, dave.hansen, hpa, akpm,
baoquan.he, rppt, pasha.tatashin, pratyush, leitao, yeoreum.yun,
mpilaniy, robh, coiby.xu, Yeking, prudo, brads, sourabhjain,
mkchauras, blum, adityag, qirui.001, hui.wang, sohammetha01,
guoren, gaohan, ionut.nechita, vishal.l.verma, seanjc, ardb,
richard.lyu, arnd, tzimmermann, rick.p.edgecombe, kai.huang, kas,
piliu, thuth, shradhagupta, ebiggers, jbouron, me, mclapinski,
graf, tangyouling, x86, kexec
> The file-based kexec system call places segments with kexec_add_buffer(),
> which takes them from CMA when kexec_alloc_contig() succeeds, to avoid
> copying the payload at kexec time.
>
> When load_other_segments() cannot place the initrd, the segments of the
> attempt are dropped but their CMA pages are leaked. Release them with
> kexec_rollback_segments() in the retry loop and in the error path of
> load_other_segments().
>
> The loop makes progress by advancing buf_min past a segment placed by the
> walk. kexec_alloc_contig() ignores buf_min, so once the pages of a CMA
> segment are released, the next attempt can get the same region again and
> the retry makes no progress. Disable CMA for the retry.
>
> A CMA segment can be anywhere in RAM, so moving buf_min to its end can
> [ ... ]
> Cc: Kees Cook <kees@kernel.org>
> Cc: stable@vger.kernel.org
> Link: https://sashiko.dev/#/patchset/20260729031235.2840255-1-ruanjinjie%40huawei.com
> Fixes: 55d990f0084c ("LoongArch: Add EFI binary support for kexec_file")
> Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>
Sashiko has reviewed this patch and found no issues.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261112133418.4044428-1-ruanjinjie@huawei.com?part=11
^ permalink raw reply [flat|nested] 23+ messages in thread