Blame SOURCES/kexec-tools-2.0.8-arm64-remove-restriction-on-the-segments-order.patch

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