From b2b569151867bca996656380a0d773cbf92719ef Mon Sep 17 00:00:00 2001 Message-Id: In-Reply-To: References: From: AKASHI Takahiro Date: Wed, 22 Apr 2015 11:21:05 +0900 Subject: [PATCH 13/15] arm64: remove restriction on the segments order Done by changing locate_hole() to add_buffer_phys_virt() in load_other_segments() since locate_hole() assumes that the segments in struct info be sorted properly. This also simplifies the difference between kexec case and kdump case. --- kexec/arch/arm64/kexec-arm64.c | 57 +++++++++++++++--------------------------- 1 file changed, 20 insertions(+), 37 deletions(-) diff --git a/kexec/arch/arm64/kexec-arm64.c b/kexec/arch/arm64/kexec-arm64.c index 190037c75186..d884c7c1707d 100644 --- a/kexec/arch/arm64/kexec-arm64.c +++ b/kexec/arch/arm64/kexec-arm64.c @@ -590,11 +590,10 @@ int arm64_load_other_segments(struct kexec_info *info, { int result; struct mem_ehdr ehdr; - unsigned long dtb_max; unsigned long dtb_base; + unsigned long hole_min, hole_max; char *initrd_buf = NULL; uint64_t purgatory_sink; - unsigned long purgatory_base; struct dtb dtb_1 = {.name = "dtb_1"}; struct dtb dtb_2 = {.name = "dtb_2"}; char command_line[COMMAND_LINE_SIZE] = ""; @@ -648,27 +647,15 @@ int arm64_load_other_segments(struct kexec_info *info, * to the DTB size for any DTB growth. */ - dtb_max = dtb_2.size + 2 * 1024; - - if (info->kexec_flags & KEXEC_ON_CRASH) - dtb_base = locate_dtb_in_crashmem(info, dtb_max); - else - dtb_base = locate_hole(info, dtb_max, 128UL * 1024, - arm64_mem.memstart + arm64_mem.text_offset - + arm64_mem.image_size, - _ALIGN_UP(arm64_mem.memstart + arm64_mem.text_offset, - 512UL * 1024 * 1024), - 1); - - dbgprintf("dtb: base %lx, size %lxh (%ld)\n", dtb_base, dtb_2.size, - dtb_2.size); - - if (dtb_base == ULONG_MAX) - return -ENOMEM; - - purgatory_base = dtb_base + dtb_2.size; - initrd_base = 0; - initrd_size = 0; + if (info->kexec_flags & KEXEC_ON_CRASH) { + hole_min = crash_reserved_mem.start + arm64_mem.text_offset + + arm64_mem.image_size; + hole_max = crash_reserved_mem.end; + } else { + hole_min = arm64_mem.memstart + arm64_mem.text_offset + + arm64_mem.image_size; + hole_max = ULONG_MAX; + } if (arm64_opts.initrd) { initrd_buf = slurp_file(arm64_opts.initrd, &initrd_size); @@ -679,8 +666,9 @@ int arm64_load_other_segments(struct kexec_info *info, /* Put the initrd after the DTB with an alignment of * page size. */ - initrd_base = locate_hole(info, initrd_size, 0, - dtb_base + dtb_max, -1, 1); + initrd_base = add_buffer_phys_virt(info, initrd_buf, + initrd_size, initrd_size, 0, + hole_min, hole_max, 1, 0); dbgprintf("initrd: base %lx, size %lxh (%ld)\n", initrd_base, initrd_size, initrd_size); @@ -694,22 +682,17 @@ int arm64_load_other_segments(struct kexec_info *info, if (result) return result; - - purgatory_base = initrd_base + initrd_size; } } - if (dtb_2.size > dtb_max) { - fprintf(stderr, "%s: Error: Too many DTB mods.\n", __func__); - return -EINVAL; - } + dtb_base = add_buffer_phys_virt(info, dtb_2.buf, dtb_2.size, dtb_2.size, + 128UL * 1024, hole_min, hole_max, 1, 0); - add_segment_phys_virt(info, dtb_2.buf, dtb_2.size, dtb_base, - dtb_2.size, 0); + dbgprintf("dtb: base %lx, size %lxh (%ld)\n", dtb_base, dtb_2.size, + dtb_2.size); - if (arm64_opts.initrd) - add_segment_phys_virt(info, initrd_buf, initrd_size, - initrd_base, initrd_size, 0); + if (dtb_base == ULONG_MAX) + return -ENOMEM; if (arm64_opts.lite) info->entry = (void *)kernel_entry; @@ -724,7 +707,7 @@ int arm64_load_other_segments(struct kexec_info *info, } elf_rel_build_load(info, &info->rhdr, purgatory, purgatory_size, - purgatory_base, ULONG_MAX, 1, 0); + hole_min, hole_max, 1, 0); info->entry = (void *)elf_rel_get_addr(&info->rhdr, "purgatory_start"); -- 2.1.0