[PATCH v8 05/11] riscv: kexec_file: Load the extra segments with common helpers
Jinjie Ruan
ruanjinjie at huawei.com
Thu Nov 12 05:34:12 PST 2026
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 at rivosinc.com>
Cc: Alexandre Ghiti <alexghiti at rivosinc.com>
Cc: Andrew Morton <akpm at linux-foundation.org>
Cc: Baoquan He <baoquan.he at linux.dev>
Cc: Mike Rapoport <rppt at kernel.org>
Signed-off-by: Jinjie Ruan <ruanjinjie at 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
More information about the linux-riscv
mailing list