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

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