[PATCH v8 03/11] arm64: kexec_file: Load the other segments with common helpers
Jinjie Ruan
ruanjinjie at huawei.com
Thu Nov 12 05:34:10 PST 2026
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 at arm.com>
Cc: Will Deacon <will 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/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
More information about the linux-riscv
mailing list