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, &params, 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, &params, 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


Reply via email to