Replace the local copy with the common helper. The retry loop stays and the command line is built in the setup hook.
Cc: Huacai Chen <[email protected]> Cc: Andrew Morton <[email protected]> Cc: Baoquan He <[email protected]> Cc: Mike Rapoport <[email protected]> Signed-off-by: Jinjie Ruan <[email protected]> --- arch/loongarch/include/asm/kexec.h | 4 - arch/loongarch/kernel/kexec_efi.c | 12 ++- arch/loongarch/kernel/kexec_elf.c | 11 ++- arch/loongarch/kernel/machine_kexec_file.c | 94 ++++------------------ 4 files changed, 32 insertions(+), 89 deletions(-) diff --git a/arch/loongarch/include/asm/kexec.h b/arch/loongarch/include/asm/kexec.h index 6be136e9f0a0..e58cf7e282a9 100644 --- a/arch/loongarch/include/asm/kexec.h +++ b/arch/loongarch/include/asm/kexec.h @@ -49,10 +49,6 @@ extern const struct kexec_file_ops kexec_elf_ops; 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); #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 d42711b895a2..1362e51e9171 100644 --- a/arch/loongarch/kernel/kexec_efi.c +++ b/arch/loongarch/kernel/kexec_efi.c @@ -44,6 +44,12 @@ static void *efi_kexec_load(struct kimage *image, unsigned long text_offset, kernel_segment_number; struct kexec_buf kbuf = {}; struct kexec_segment *kernel_segment; + struct kexec_load_params params = { + .initrd = initrd, + .initrd_len = initrd_len, + .cmdline = cmdline, + .cmdline_len = cmdline_len, + }; struct loongarch_image_header *h; h = (struct loongarch_image_header *)kernel; @@ -76,9 +82,9 @@ static void *efi_kexec_load(struct kimage *image, while ((ret = kexec_add_buffer(&kbuf)) == 0) { /* 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); + params.kernel_load_addr = kernel_segment->mem; + params.kernel_size = kernel_segment->memsz; + ret = kexec_load_other_segments(image, ¶ms, false); if (!ret) break; diff --git a/arch/loongarch/kernel/kexec_elf.c b/arch/loongarch/kernel/kexec_elf.c index 1b6b64744c7f..47272cfa990d 100644 --- a/arch/loongarch/kernel/kexec_elf.c +++ b/arch/loongarch/kernel/kexec_elf.c @@ -62,6 +62,12 @@ static void *elf_kexec_load(struct kimage *image, struct kexec_buf kbuf = {}; struct kexec_elf_info elf_info; struct kexec_segment *kernel_segment; + struct kexec_load_params params = { + .initrd = initrd, + .initrd_len = initrd_len, + .cmdline = cmdline, + .cmdline_len = cmdline_len, + }; ret = kexec_build_elf_info(kernel, kernel_len, &ehdr, &elf_info); if (ret < 0) @@ -83,8 +89,9 @@ 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); + params.kernel_load_addr = kernel_segment->mem; + params.kernel_size = kernel_segment->memsz; + ret = kexec_load_other_segments(image, ¶ms, false); if (ret < 0) goto out; diff --git a/arch/loongarch/kernel/machine_kexec_file.c b/arch/loongarch/kernel/machine_kexec_file.c index c0a799f0d240..d65cb40ef047 100644 --- a/arch/loongarch/kernel/machine_kexec_file.c +++ b/arch/loongarch/kernel/machine_kexec_file.c @@ -110,112 +110,46 @@ static void cmdline_add_elfcorehdr(struct kimage *image, unsigned long *cmdline_ #endif -/* - * Try to add the initrd to the image. If it is not possible to find 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, 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 = 0; unsigned long cmdline_tmplen = 0; - unsigned long initrd_load_addr = 0; - unsigned long orig_segments = image->nr_segments; - char *modified_cmdline = NULL; - 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_len = params->cmdline_len; + const char *cmdline = params->cmdline; + char *modified_cmdline; modified_cmdline = kzalloc(COMMAND_LINE_SIZE, GFP_KERNEL); if (!modified_cmdline) - return -EINVAL; + return -ENOMEM; cmdline_add_loader(&cmdline_tmplen, modified_cmdline); /* Ensure it's null terminated */ modified_cmdline[COMMAND_LINE_SIZE - 1] = '\0'; #ifdef CONFIG_CRASH_DUMP - /* Load elf core header */ if (image->type == KEXEC_TYPE_CRASH) { - ret = crash_prepare_headers(true, &kbuf.buffer, &kbuf.bufsz, NULL); - if (ret < 0) { - pr_err("Preparing elf core header failed\n"); - goto out_err; - } - - if (unlikely(image->elf_headers)) - vfree(image->elf_headers); - - image->elf_headers = kbuf.buffer; - image->elf_headers_sz = kbuf.bufsz; - - kbuf.mem = KEXEC_BUF_MEM_UNKNOWN; - kbuf.memsz = kbuf.bufsz; - kbuf.buf_align = SZ_64K; /* largest supported page size */ - kbuf.top_down = true; - - ret = kexec_add_buffer(&kbuf); - if (ret < 0) - goto out_err; - - 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); - /* 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, kbuf.bufsz); + 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; - 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) - 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 */ + /* Add the initrd=start,size parameter to the command line */ + if (initrd_load_addr) cmdline_add_initrd(image, &cmdline_tmplen, modified_cmdline, initrd_load_addr); - } if (cmdline_len + cmdline_tmplen > COMMAND_LINE_SIZE) { pr_err("Appending command line exceeds COMMAND_LINE_SIZE\n"); - ret = -EINVAL; - goto out_err; + kfree(modified_cmdline); + return -EINVAL; } memcpy(modified_cmdline + cmdline_tmplen, cmdline, cmdline_len); - cmdline = modified_cmdline; - image->arch.cmdline_ptr = (unsigned long)cmdline; + image->arch.cmdline_ptr = (unsigned long)modified_cmdline; return 0; - -out_err: - while (image->nr_segments > orig_segments) { - kexec_free_segment_cma(image, image->nr_segments - 1); - image->nr_segments--; - } - - kfree(modified_cmdline); - return ret; } -- 2.34.1
