Pass the kbuf fields to crash_prepare_headers() and set elf_headers before kexec_add_buffer(), so the error path needs no vfree() because arch_kimage_file_post_load_cleanup() will do it.
Cc: Huacai Chen <[email protected]> Cc: Baoquan He <[email protected]> Signed-off-by: Jinjie Ruan <[email protected]> --- arch/loongarch/kernel/machine_kexec_file.c | 38 +++++++++------------- 1 file changed, 16 insertions(+), 22 deletions(-) diff --git a/arch/loongarch/kernel/machine_kexec_file.c b/arch/loongarch/kernel/machine_kexec_file.c index 3beb6977ecc6..6ea60e0faa2c 100644 --- a/arch/loongarch/kernel/machine_kexec_file.c +++ b/arch/loongarch/kernel/machine_kexec_file.c @@ -127,11 +127,12 @@ int load_other_segments(struct kimage *image, unsigned long initrd_load_addr = 0; unsigned long orig_segments = image->nr_segments; 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; + struct kexec_buf kbuf = { + .image = image, + /* Don't allocate anything below the kernel */ + .buf_min = kernel_load_addr + kernel_size, + .buf_max = ULONG_MAX, + }; modified_cmdline = kzalloc(COMMAND_LINE_SIZE, GFP_KERNEL); if (!modified_cmdline) @@ -144,35 +145,28 @@ 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); + ret = crash_prepare_headers(true, &kbuf.buffer, &kbuf.bufsz, NULL); if (ret < 0) { pr_err("Preparing elf core header failed\n"); goto out_err; } - kbuf.buffer = headers; - kbuf.bufsz = headers_sz; + 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 = headers_sz; + kbuf.memsz = kbuf.bufsz; kbuf.buf_align = SZ_64K; /* largest supported page size */ - kbuf.buf_max = ULONG_MAX; kbuf.top_down = true; ret = kexec_add_buffer(&kbuf); - if (ret < 0) { - vfree(headers); + if (ret < 0) 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); @@ -181,7 +175,7 @@ int load_other_segments(struct kimage *image, 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, headers_sz); + cmdline_add_elfcorehdr(image, &cmdline_tmplen, modified_cmdline, kbuf.bufsz); } #endif -- 2.34.1
