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: Catalin Marinas <[email protected]> Cc: Will Deacon <[email protected]> Cc: Baoquan He <[email protected]> Cc: Breno Leitao <[email protected]> Signed-off-by: Jinjie Ruan <[email protected]> --- arch/arm64/kernel/machine_kexec_file.c | 35 +++++++++++--------------- 1 file changed, 15 insertions(+), 20 deletions(-) diff --git a/arch/arm64/kernel/machine_kexec_file.c b/arch/arm64/kernel/machine_kexec_file.c index 2f750e5f4fcc..d3d191a5ac89 100644 --- a/arch/arm64/kernel/machine_kexec_file.c +++ b/arch/arm64/kernel/machine_kexec_file.c @@ -78,47 +78,42 @@ int load_other_segments(struct kimage *image, char *initrd, unsigned long initrd_len, char *cmdline) { - struct kexec_buf kbuf = {}; + 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); + ret = crash_prepare_headers(true, &kbuf.buffer, &kbuf.bufsz, NULL); if (ret) { 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) { - vfree(headers); + if (ret) 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); -- 2.34.1
