[PATCH v7 15/15] riscv: kexec_file: Use kexec_load_other_segments() to simplify code
Jinjie Ruan
ruanjinjie at huawei.com
Mon Oct 26 00:52:01 PDT 2026
Replace load_extra_segments() with the common helper.
The purgatory, DTB and kdump command line move to the setup hook. And the elf
core header is now 64K aligned.
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 | 11 ++++-
arch/riscv/kernel/kexec_image.c | 11 ++++-
arch/riscv/kernel/machine_kexec_file.c | 65 ++++++--------------------
4 files changed, 31 insertions(+), 60 deletions(-)
diff --git a/arch/riscv/include/asm/kexec.h b/arch/riscv/include/asm/kexec.h
index b9ee8346cc8c..b0400de9acfd 100644
--- a/arch/riscv/include/asm/kexec.h
+++ b/arch/riscv/include/asm/kexec.h
@@ -69,10 +69,6 @@ struct kimage;
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);
#endif
#endif
diff --git a/arch/riscv/kernel/kexec_elf.c b/arch/riscv/kernel/kexec_elf.c
index 3e9a32acb8f2..202600760f91 100644
--- a/arch/riscv/kernel/kexec_elf.c
+++ b/arch/riscv/kernel/kexec_elf.c
@@ -110,6 +110,12 @@ static void *elf_kexec_load(struct kimage *image, char *kernel_buf,
unsigned long new_kernel_pbase = 0UL;
struct elfhdr ehdr;
struct kexec_elf_info elf_info;
+ struct kexec_load_params params = {
+ .initrd = initrd,
+ .initrd_len = initrd_len,
+ .cmdline = cmdline,
+ .cmdline_len = cmdline_len,
+ };
ret = kexec_build_elf_info(kernel_buf, kernel_len, &ehdr, &elf_info);
if (ret)
@@ -126,8 +132,9 @@ 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);
+ params.kernel_load_addr = image->start;
+ params.kernel_size = kernel_len;
+ ret = kexec_load_other_segments(image, ¶ms, true);
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 51dc89259f16..e0d0aa912a76 100644
--- a/arch/riscv/kernel/kexec_image.c
+++ b/arch/riscv/kernel/kexec_image.c
@@ -42,6 +42,12 @@ static void *image_load(struct kimage *image,
u64 flags;
bool be_image, be_kernel;
struct kexec_buf kbuf = {};
+ struct kexec_load_params params = {
+ .initrd = initrd,
+ .initrd_len = initrd_len,
+ .cmdline = cmdline,
+ .cmdline_len = cmdline_len,
+ };
int ret;
/* Check Image header */
@@ -83,8 +89,9 @@ 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);
+ params.kernel_load_addr = kbuf.mem;
+ params.kernel_size = kbuf.memsz;
+ ret = kexec_load_other_segments(image, ¶ms, true);
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 d191351c6055..e79b71a8b7aa 100644
--- a/arch/riscv/kernel/machine_kexec_file.c
+++ b/arch/riscv/kernel/machine_kexec_file.c
@@ -234,51 +234,26 @@ int arch_kexec_apply_relocations_add(struct purgatory_info *pi,
return 0;
}
-
-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)
+int arch_kexec_setup_other_segments(struct kimage *image,
+ struct kexec_load_params *params,
+ unsigned long initrd_load_addr)
{
- int ret;
- void *fdt;
- unsigned long initrd_pbase = 0UL;
- char *modified_cmdline = NULL;
+ unsigned long kernel_start = params->kernel_load_addr;
+ char *cmdline = params->cmdline;
struct kexec_buf kbuf = {
.image = image,
- .buf_min = kernel_start + kernel_len,
+ .buf_min = kernel_start + params->kernel_size,
.buf_max = PFN_PHYS(max_low_pfn),
};
+ char *modified_cmdline = NULL;
+ void *fdt;
+ int ret;
#ifdef CONFIG_CRASH_DUMP
- /* Add elfcorehdr */
+ /* Setup cmdline for kdump kernel case */
if (image->type == KEXEC_TYPE_CRASH) {
- ret = crash_prepare_headers(true, &kbuf.buffer, &kbuf.bufsz, NULL);
- if (ret) {
- pr_err("Preparing elf core header failed\n");
- goto out;
- }
-
- image->elf_headers = kbuf.buffer;
- image->elf_headers_sz = kbuf.bufsz;
-
- kbuf.mem = KEXEC_BUF_MEM_UNKNOWN;
- kbuf.memsz = kbuf.bufsz;
- kbuf.buf_align = ELF_CORE_HEADER_ALIGN;
- kbuf.top_down = true;
-
- ret = kexec_add_buffer(&kbuf);
- if (ret)
- goto out;
-
- image->elf_load_addr = kbuf.mem;
-
- 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);
+ params->cmdline_len);
if (!modified_cmdline) {
pr_err("Setting up cmdline for kdump kernel failed\n");
ret = -EINVAL;
@@ -306,23 +281,9 @@ int load_extra_segments(struct kimage *image, unsigned long kernel_start,
pr_err("Error update purgatory ret=%d\n", ret);
#endif /* CONFIG_ARCH_SUPPORTS_KEXEC_PURGATORY */
- /* Add the initrd to the image */
- if (initrd != NULL) {
- kbuf.buffer = initrd;
- kbuf.bufsz = kbuf.memsz = initrd_len;
- kbuf.buf_align = PAGE_SIZE;
- kbuf.top_down = true;
- kbuf.mem = KEXEC_BUF_MEM_UNKNOWN;
- ret = kexec_add_buffer(&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);
+ fdt = of_kexec_alloc_and_setup_fdt(image, initrd_load_addr,
+ params->initrd_len, cmdline, 0);
if (!fdt) {
pr_err("Error setting up the new device tree.\n");
ret = -EINVAL;
--
2.34.1
More information about the kexec
mailing list