Replace the local copy with the common helper.

The retry loop stays. And the DTB and the dm-crypt keys move to the setup
hook and the keys are loaded after the initrd now.

Cc: Catalin Marinas <[email protected]>
Cc: Will Deacon <[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/arm64/include/asm/kexec.h         |  5 --
 arch/arm64/kernel/kexec_image.c        | 12 +++-
 arch/arm64/kernel/machine_kexec_file.c | 95 ++++----------------------
 3 files changed, 23 insertions(+), 89 deletions(-)

diff --git a/arch/arm64/include/asm/kexec.h b/arch/arm64/include/asm/kexec.h
index 892e5bebda95..8fc04e0e7dad 100644
--- a/arch/arm64/include/asm/kexec.h
+++ b/arch/arm64/include/asm/kexec.h
@@ -123,11 +123,6 @@ extern const struct kexec_file_ops kexec_image_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);
 #endif
 
 #endif /* __ASSEMBLER__ */
diff --git a/arch/arm64/kernel/kexec_image.c b/arch/arm64/kernel/kexec_image.c
index 6ed1991e3142..f5a7f1f92afc 100644
--- a/arch/arm64/kernel/kexec_image.c
+++ b/arch/arm64/kernel/kexec_image.c
@@ -44,6 +44,12 @@ static void *image_load(struct kimage *image,
        struct kexec_buf kbuf = {};
        unsigned long text_offset, kernel_segment_number;
        struct kexec_segment *kernel_segment;
+       struct kexec_load_params params = {
+               .initrd = initrd,
+               .initrd_len = initrd_len,
+               .cmdline = cmdline,
+               .cmdline_len = cmdline_len,
+       };
        int ret;
 
        /*
@@ -101,9 +107,9 @@ static void *image_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);
+               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/arm64/kernel/machine_kexec_file.c 
b/arch/arm64/kernel/machine_kexec_file.c
index e7f280915e8d..44754b380bf1 100644
--- a/arch/arm64/kernel/machine_kexec_file.c
+++ b/arch/arm64/kernel/machine_kexec_file.c
@@ -63,91 +63,30 @@ int arch_crash_populate_cmem(struct crash_mem *cmem)
 }
 #endif
 
-/*
- * Tries to add the initrd and DTB 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)
+int arch_kexec_setup_other_segments(struct kimage *image,
+                                   struct kexec_load_params *params,
+                                   unsigned long initrd_load_addr)
 {
        struct kexec_buf kbuf = {
                .image = image,
-               /* not allocate anything below the kernel */
-               .buf_min = kernel_load_addr + kernel_size,
-               .buf_max = ULONG_MAX,
+               .buf_min = params->kernel_load_addr + params->kernel_size,
        };
-       void *dtb = NULL;
-       unsigned long initrd_load_addr = 0, dtb_len,
-                     orig_segments = image->nr_segments;
-       int ret = 0;
+       unsigned long dtb_len;
+       void *dtb;
+       int ret;
 
-#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) {
-                       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)
-                       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);
-
                ret = crash_load_dm_crypt_keys(image);
                if (ret)
-                       goto out_err;
-       }
-#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)
-                       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);
+                       return ret;
        }
 
        /* load dtb */
        dtb = of_kexec_alloc_and_setup_fdt(image, initrd_load_addr,
-                                          initrd_len, cmdline, 0);
+                                          params->initrd_len, params->cmdline, 
0);
        if (!dtb) {
                pr_err("Preparing for new dtb failed\n");
-               ret = -EINVAL;
-               goto out_err;
+               return -EINVAL;
        }
 
        /* trim it */
@@ -163,8 +102,10 @@ int load_other_segments(struct kimage *image,
        kbuf.top_down = true;
 
        ret = kexec_add_buffer(&kbuf);
-       if (ret)
-               goto out_err;
+       if (ret) {
+               kvfree(dtb);
+               return ret;
+       }
        image->arch.dtb = dtb;
        image->arch.dtb_mem = kbuf.mem;
 
@@ -172,12 +113,4 @@ int load_other_segments(struct kimage *image,
                      kbuf.mem, kbuf.bufsz, kbuf.memsz);
 
        return 0;
-
-out_err:
-       while (image->nr_segments > orig_segments) {
-               kexec_free_segment_cma(image, image->nr_segments - 1);
-               image->nr_segments--;
-       }
-       kvfree(dtb);
-       return ret;
 }
-- 
2.34.1


Reply via email to