[PATCH v8 04/11] LoongArch: kexec_file: Load the other segments with common helpers
Jinjie Ruan
ruanjinjie at huawei.com
Thu Nov 12 05:34:11 PST 2026
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 at kernel.org>
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/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 at start parameter to the command line */
cmdline_add_mem(&cmdline_tmplen, modified_cmdline);
/* Add the elfcorehdr=size at 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
More information about the linux-riscv
mailing list