[PATCH v9 05/11] arm64: kexec_file: load initrd and device-tree
From: james.morse@arm.com (James Morse)
Date: 2018-05-18 16:02:25
Also in:
kexec, lkml
Hi Akashi, On 18/05/18 08:42, AKASHI Takahiro wrote:
On Fri, May 18, 2018 at 04:11:35PM +0900, AKASHI Takahiro wrote:quoted
On Tue, May 15, 2018 at 05:20:00PM +0100, James Morse wrote:quoted
On 25/04/18 07:26, AKASHI Takahiro wrote:quoted
diff --git a/arch/arm64/kernel/machine_kexec_file.c b/arch/arm64/kernel/machine_kexec_file.c index f9ebf54ca247..b3b9b1725d8a 100644 --- a/arch/arm64/kernel/machine_kexec_file.c +++ b/arch/arm64/kernel/machine_kexec_file.c
quoted
quoted
quoted
@@ -55,3 +74,144 @@ int arch_kexec_walk_mem(struct kexec_buf *kbuf,
quoted
quoted
quoted
+ buf = vmalloc(buf_size); + if (!buf) { + ret = -ENOMEM; + goto out_err; + } + + ret = fdt_open_into(initial_boot_params, buf, buf_size); + if (ret) + goto out_err; + + nodeoffset = fdt_path_offset(buf, "/chosen"); + if (nodeoffset < 0) + goto out_err; + + /* add bootargs */ + if (cmdline) { + ret = fdt_setprop(buf, nodeoffset, "bootargs", + cmdline, cmdline_len + 1);fdt_setprop_string()?OKcmdline_len is passed by system call, kexec_file_load(), and this means that we can't believe that cmdline is always terminated with '\0'.
Yuck, we expect user-space to tell us how long the string is. It may be worth a comment that it isn't necessarily null-terminated, as that is surprising! (I assume the DT's property length is enough to make that safe for the new kernel to read).
quoted
quoted
quoted
+ /* within 1GB-aligned window of up to 32GB in size */ + kbuf.buf_max = round_down(kern_seg->mem, 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; + + pr_debug("Loaded initrd at 0x%lx bufsz=0x%lx memsz=0x%lx\n", + initrd_load_addr, initrd_len, initrd_len); + } + + /* load dtb blob */ + ret = setup_dtb(image, initrd_load_addr, initrd_len, + cmdline, cmdline_len, &dtb, &dtb_len); + if (ret) { + pr_err("Preparing for new dtb failed\n"); + goto out_err; + } + + kbuf.buffer = dtb; + kbuf.bufsz = dtb_len; + kbuf.memsz = dtb_len; + /* not across 2MB boundary */ + kbuf.buf_align = SZ_2M; + kbuf.buf_max = ULONG_MAX; + kbuf.top_down = true; + + ret = kexec_add_buffer(&kbuf); + if (ret) + goto out_err; + image->arch.dtb_mem = kbuf.mem; + image->arch.dtb_buf = dtb; + + pr_debug("Loaded dtb at 0x%lx bufsz=0x%lx memsz=0x%lx\n", + kbuf.mem, dtb_len, dtb_len); + + return 0; + +out_err: + vfree(dtb); + image->arch.dtb_buf = NULL;Won't kimage_file_post_load_cleanup() always be called if we return an error here? Why not leave the free()ing until then?Right. The reason why I left the code here was that we'd better locally clean up all the stuff that were locally allocated if we trivially need to (and can) do so. As it's redundant, I will remove it.will remove only "image->arch.dtb_buf = NULL."
Ah, because you haven't set the arch.dtb_buf pointer yet. What about in patch 7 where you expect kimage_file_prepare_segments() to call arch_kimage_file_post_load_cleanup() to free the arch.elf_headers? I'd expect the free()ing to always happen in one place. Thanks, James