All of lore.kernel.org
 help / color / mirror / Atom feed
* [RESEND PATCH] arm64: support more than one crash kernel regions
@ 2019-04-08  9:22 Chen Zhou
  2019-04-08  9:36 ` Simon Horman
  0 siblings, 1 reply; 4+ messages in thread
From: Chen Zhou @ 2019-04-08  9:22 UTC (permalink / raw)
  To: horms, takahiro.akashi, kexec; +Cc: Chen Zhou, wangkefeng.wang

When crashkernel is reserved above 4G in memory, kernel should
reserve some amount of low memory for swiotlb and some DMA buffers.
So there may be two crash kernel regions, one is below 4G, the other
is above 4G.

Currently, there is only one crash kernel region on arm64, and pass
"linux,usable-memory-range = <BASE SIZE>" property to crash dump
kernel. Now, we pass
"linux,usable-memory-range = <BASE1 SIZE1 BASE2 SIZE2>" to crash
dump kernel to support two crash kernel regions and load crash
kernel high.

This patch paves the way for the use of arm64 reserving crashkernel
above 4G. The details are as below:
Link: https://lore.kernel.org/linux-arm-kernel/20190403030546.23718-1-chenzhou10@huawei.com/T/#t 

Signed-off-by: Chen Zhou <chenzhou10@huawei.com>
---
 kexec/arch/arm64/crashdump-arm64.c | 44 +++++++++++++++++------------
 kexec/arch/arm64/crashdump-arm64.h |  3 +-
 kexec/arch/arm64/kexec-arm64.c     | 57 +++++++++++++++++++++++++++++---------
 3 files changed, 72 insertions(+), 32 deletions(-)

diff --git a/kexec/arch/arm64/crashdump-arm64.c b/kexec/arch/arm64/crashdump-arm64.c
index 4fd7aa8..158e778 100644
--- a/kexec/arch/arm64/crashdump-arm64.c
+++ b/kexec/arch/arm64/crashdump-arm64.c
@@ -32,11 +32,11 @@ static struct memory_ranges system_memory_rgns = {
 };
 
 /* memory range reserved for crashkernel */
-struct memory_range crash_reserved_mem;
+struct memory_range crash_reserved_mem[CRASH_MAX_RESERVED_RANGES];
 struct memory_ranges usablemem_rgns = {
 	.size = 0,
-	.max_size = 1,
-	.ranges = &crash_reserved_mem,
+	.max_size = CRASH_MAX_RESERVED_RANGES,
+	.ranges = crash_reserved_mem,
 };
 
 struct memory_range elfcorehdr_mem;
@@ -108,7 +108,7 @@ int is_crashkernel_mem_reserved(void)
 	if (!usablemem_rgns.size)
 		kexec_iomem_for_each_line(NULL, iomem_range_callback, NULL);
 
-	return crash_reserved_mem.start != crash_reserved_mem.end;
+	return usablemem_rgns.size;
 }
 
 /*
@@ -122,6 +122,8 @@ int is_crashkernel_mem_reserved(void)
  */
 static int crash_get_memory_ranges(void)
 {
+	int i;
+
 	/*
 	 * First read all memory regions that can be considered as
 	 * system memory including the crash area.
@@ -129,16 +131,19 @@ static int crash_get_memory_ranges(void)
 	if (!usablemem_rgns.size)
 		kexec_iomem_for_each_line(NULL, iomem_range_callback, NULL);
 
-	/* allow only a single region for crash dump kernel */
-	if (usablemem_rgns.size != 1)
+	/* allow one or two region for crash dump kernel */
+	if (!usablemem_rgns.size)
 		return -EINVAL;
 
-	dbgprint_mem_range("Reserved memory range", &crash_reserved_mem, 1);
+	dbgprint_mem_range("Reserved memory range",
+			usablemem_rgns.ranges, usablemem_rgns.size);
 
-	if (mem_regions_exclude(&system_memory_rgns, &crash_reserved_mem)) {
-		fprintf(stderr,
-			"Error: Number of crash memory ranges excedeed the max limit\n");
-		return -ENOMEM;
+	for (i = 0; i < usablemem_rgns.size; i++) {
+		if (mem_regions_exclude(&system_memory_rgns, &crash_reserved_mem[i])) {
+			fprintf(stderr,
+					"Error: Number of crash memory ranges excedeed the max limit\n");
+			return -ENOMEM;
+		}
 	}
 
 	/*
@@ -199,7 +204,8 @@ int load_crashdump_segments(struct kexec_info *info)
 		return EFAILED;
 
 	elfcorehdr = add_buffer_phys_virt(info, buf, bufsz, bufsz, 0,
-		crash_reserved_mem.start, crash_reserved_mem.end,
+		crash_reserved_mem[usablemem_rgns.size - 1].start,
+		crash_reserved_mem[usablemem_rgns.size - 1].end,
 		-1, 0);
 
 	elfcorehdr_mem.start = elfcorehdr;
@@ -217,21 +223,23 @@ int load_crashdump_segments(struct kexec_info *info)
  * virt_to_phys() in add_segment().
  * So let's fix up those values for later use so the memory base
  * (arm64_mm.phys_offset) will be correctly replaced with
- * crash_reserved_mem.start.
+ * crash_reserved_mem[usablemem_rgns.size - 1].start.
  */
 void fixup_elf_addrs(struct mem_ehdr *ehdr)
 {
 	struct mem_phdr *phdr;
 	int i;
 
-	ehdr->e_entry += - arm64_mem.phys_offset + crash_reserved_mem.start;
+	ehdr->e_entry += -arm64_mem.phys_offset +
+		crash_reserved_mem[usablemem_rgns.size - 1].start;
 
 	for (i = 0; i < ehdr->e_phnum; i++) {
 		phdr = &ehdr->e_phdr[i];
 		if (phdr->p_type != PT_LOAD)
 			continue;
 		phdr->p_paddr +=
-			(-arm64_mem.phys_offset + crash_reserved_mem.start);
+			(-arm64_mem.phys_offset +
+			 crash_reserved_mem[usablemem_rgns.size - 1].start);
 	}
 }
 
@@ -240,11 +248,11 @@ int get_crash_kernel_load_range(uint64_t *start, uint64_t *end)
 	if (!usablemem_rgns.size)
 		kexec_iomem_for_each_line(NULL, iomem_range_callback, NULL);
 
-	if (!crash_reserved_mem.end)
+	if (!usablemem_rgns.size)
 		return -1;
 
-	*start = crash_reserved_mem.start;
-	*end = crash_reserved_mem.end;
+	*start = crash_reserved_mem[usablemem_rgns.size - 1].start;
+	*end = crash_reserved_mem[usablemem_rgns.size - 1].end;
 
 	return 0;
 }
diff --git a/kexec/arch/arm64/crashdump-arm64.h b/kexec/arch/arm64/crashdump-arm64.h
index 880b83a..c07233f 100644
--- a/kexec/arch/arm64/crashdump-arm64.h
+++ b/kexec/arch/arm64/crashdump-arm64.h
@@ -15,9 +15,10 @@
 #include "kexec.h"
 
 #define CRASH_MAX_MEMORY_RANGES	32
+#define CRASH_MAX_RESERVED_RANGES	8
 
 extern struct memory_ranges usablemem_rgns;
-extern struct memory_range crash_reserved_mem;
+extern struct memory_range crash_reserved_mem[];
 extern struct memory_range elfcorehdr_mem;
 
 extern int load_crashdump_segments(struct kexec_info *info);
diff --git a/kexec/arch/arm64/kexec-arm64.c b/kexec/arch/arm64/kexec-arm64.c
index 2992bce..2bf8b66 100644
--- a/kexec/arch/arm64/kexec-arm64.c
+++ b/kexec/arch/arm64/kexec-arm64.c
@@ -414,6 +414,34 @@ static int fdt_setprop_range(void *fdt, int nodeoffset,
 	return result;
 }
 
+static int fdt_setprop_ranges(void *fdt, int nodeoffset,
+				const char *name, struct memory_ranges *ranges,
+				uint32_t address_cells, uint32_t size_cells)
+{
+	void *buf, *prop;
+	size_t buf_size;
+	int i, result;
+
+	buf_size = (address_cells + size_cells) * sizeof(uint32_t) *
+		ranges->size;
+	prop = buf = xmalloc(buf_size);
+
+	for (i = 0; i < ranges->size; i++) {
+		fill_property(prop, ranges->ranges[i].start, address_cells);
+		prop += address_cells * sizeof(uint32_t);
+
+		fill_property(prop, ranges->ranges[i].end -
+				ranges->ranges[i].start + 1, size_cells);
+		prop += size_cells * sizeof(uint32_t);
+	}
+
+	result = fdt_setprop(fdt, nodeoffset, name, buf, buf_size);
+
+	free(buf);
+
+	return result;
+}
+
 /**
  * setup_2nd_dtb - Setup the 2nd stage kernel's dtb.
  */
@@ -427,7 +455,7 @@ static int setup_2nd_dtb(struct dtb *dtb, char *command_line, int on_crash)
 	int len, range_len;
 	int nodeoffset;
 	int new_size;
-	int result, kaslr_seed;
+	int i, result, kaslr_seed;
 
 	result = fdt_check_header(dtb->buf);
 
@@ -458,18 +486,21 @@ static int setup_2nd_dtb(struct dtb *dtb, char *command_line, int on_crash)
 		goto on_error;
 	}
 
-	if (!cells_size_fitted(address_cells, size_cells,
-				&crash_reserved_mem)) {
-		fprintf(stderr, "kexec: usable memory range doesn't fit cells-size.\n");
-		result = -EINVAL;
-		goto on_error;
+	for (i = 0; i < usablemem_rgns.size; i++) {
+		if (!cells_size_fitted(address_cells, size_cells,
+					&crash_reserved_mem[i])) {
+			fprintf(stderr,
+					"kexec: usable memory range doesn't fit cells-size.\n");
+			result = -EINVAL;
+			goto on_error;
+		}
 	}
 
 	/* duplicate dt blob */
 	range_len = sizeof(uint32_t) * (address_cells + size_cells);
 	new_size = fdt_totalsize(dtb->buf)
 		+ fdt_prop_len(PROP_ELFCOREHDR, range_len)
-		+ fdt_prop_len(PROP_USABLE_MEM_RANGE, range_len);
+		+ fdt_prop_len(PROP_USABLE_MEM_RANGE, range_len * usablemem_rgns.size);
 
 	new_buf = xmalloc(new_size);
 	result = fdt_open_into(dtb->buf, new_buf, new_size);
@@ -565,8 +596,8 @@ static int setup_2nd_dtb(struct dtb *dtb, char *command_line, int on_crash)
 
 		/* add linux,usable-memory-range */
 		nodeoffset = fdt_path_offset(new_buf, "/chosen");
-		result = fdt_setprop_range(new_buf, nodeoffset,
-				PROP_USABLE_MEM_RANGE, &crash_reserved_mem,
+		result = fdt_setprop_ranges(new_buf, nodeoffset,
+				PROP_USABLE_MEM_RANGE, &usablemem_rgns,
 				address_cells, size_cells);
 		if (result) {
 			dbgprintf("%s: fdt_setprop failed: %s\n", __func__,
@@ -599,13 +630,13 @@ unsigned long arm64_locate_kernel_segment(struct kexec_info *info)
 	if (info->kexec_flags & KEXEC_ON_CRASH) {
 		unsigned long hole_end;
 
-		hole = (crash_reserved_mem.start < mem_min ?
-				mem_min : crash_reserved_mem.start);
+		hole = (crash_reserved_mem[usablemem_rgns.size - 1].start < mem_min ?
+				mem_min : crash_reserved_mem[usablemem_rgns.size - 1].start);
 		hole = _ALIGN_UP(hole, MiB(2));
 		hole_end = hole + arm64_mem.text_offset + arm64_mem.image_size;
 
 		if ((hole_end > mem_max) ||
-		    (hole_end > crash_reserved_mem.end)) {
+		    (hole_end > crash_reserved_mem[usablemem_rgns.size - 1].end)) {
 			dbgprintf("%s: Crash kernel out of range\n", __func__);
 			hole = ULONG_MAX;
 		}
@@ -673,7 +704,7 @@ int arm64_load_other_segments(struct kexec_info *info,
 
 	hole_min = image_base + arm64_mem.image_size;
 	if (info->kexec_flags & KEXEC_ON_CRASH)
-		hole_max = crash_reserved_mem.end;
+		hole_max = crash_reserved_mem[usablemem_rgns.size - 1].end;
 	else
 		hole_max = ULONG_MAX;
 
-- 
2.7.4


_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [RESEND PATCH] arm64: support more than one crash kernel regions
  2019-04-08  9:22 [RESEND PATCH] arm64: support more than one crash kernel regions Chen Zhou
@ 2019-04-08  9:36 ` Simon Horman
  2019-04-09  3:59   ` Bhupesh Sharma
  0 siblings, 1 reply; 4+ messages in thread
From: Simon Horman @ 2019-04-08  9:36 UTC (permalink / raw)
  To: Chen Zhou; +Cc: takahiro.akashi, wangkefeng.wang, kexec

On Mon, Apr 08, 2019 at 05:22:39PM +0800, Chen Zhou wrote:
> When crashkernel is reserved above 4G in memory, kernel should
> reserve some amount of low memory for swiotlb and some DMA buffers.
> So there may be two crash kernel regions, one is below 4G, the other
> is above 4G.
> 
> Currently, there is only one crash kernel region on arm64, and pass
> "linux,usable-memory-range = <BASE SIZE>" property to crash dump
> kernel. Now, we pass
> "linux,usable-memory-range = <BASE1 SIZE1 BASE2 SIZE2>" to crash
> dump kernel to support two crash kernel regions and load crash
> kernel high.
> 
> This patch paves the way for the use of arm64 reserving crashkernel
> above 4G. The details are as below:
> Link: https://lore.kernel.org/linux-arm-kernel/20190403030546.23718-1-chenzhou10@huawei.com/T/#t 
> 
> Signed-off-by: Chen Zhou <chenzhou10@huawei.com>

Thanks, applied.

_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [RESEND PATCH] arm64: support more than one crash kernel regions
  2019-04-08  9:36 ` Simon Horman
@ 2019-04-09  3:59   ` Bhupesh Sharma
  2019-04-10  9:15     ` Simon Horman
  0 siblings, 1 reply; 4+ messages in thread
From: Bhupesh Sharma @ 2019-04-09  3:59 UTC (permalink / raw)
  To: Simon Horman
  Cc: Chen Zhou, AKASHI Takahiro, wangkefeng.wang, kexec mailing list

Hi Simon, Chen,

On Mon, Apr 8, 2019 at 5:36 PM Simon Horman <horms@verge.net.au> wrote:
>
> On Mon, Apr 08, 2019 at 05:22:39PM +0800, Chen Zhou wrote:
> > When crashkernel is reserved above 4G in memory, kernel should
> > reserve some amount of low memory for swiotlb and some DMA buffers.
> > So there may be two crash kernel regions, one is below 4G, the other
> > is above 4G.
> >
> > Currently, there is only one crash kernel region on arm64, and pass
> > "linux,usable-memory-range = <BASE SIZE>" property to crash dump
> > kernel. Now, we pass
> > "linux,usable-memory-range = <BASE1 SIZE1 BASE2 SIZE2>" to crash
> > dump kernel to support two crash kernel regions and load crash
> > kernel high.
> >
> > This patch paves the way for the use of arm64 reserving crashkernel
> > above 4G. The details are as below:
> > Link: https://lore.kernel.org/linux-arm-kernel/20190403030546.23718-1-chenzhou10@huawei.com/T/#t
> >
> > Signed-off-by: Chen Zhou <chenzhou10@huawei.com>
>
> Thanks, applied.

Sorry, but I think the kernel patch which adds this functionality is
still under discussion and review (see [1]).
May be we can wait for the kernel change to be first discussed and
absorbed and then integrate this patch in kexec-tools.

What do you think?

[1]. https://lkml.org/lkml/2019/4/2/1173

Thanks,
Bhupesh

_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [RESEND PATCH] arm64: support more than one crash kernel regions
  2019-04-09  3:59   ` Bhupesh Sharma
@ 2019-04-10  9:15     ` Simon Horman
  0 siblings, 0 replies; 4+ messages in thread
From: Simon Horman @ 2019-04-10  9:15 UTC (permalink / raw)
  To: Bhupesh Sharma
  Cc: Chen Zhou, AKASHI Takahiro, wangkefeng.wang, kexec mailing list

On Tue, Apr 09, 2019 at 11:59:21AM +0800, Bhupesh Sharma wrote:
> Hi Simon, Chen,
> 
> On Mon, Apr 8, 2019 at 5:36 PM Simon Horman <horms@verge.net.au> wrote:
> >
> > On Mon, Apr 08, 2019 at 05:22:39PM +0800, Chen Zhou wrote:
> > > When crashkernel is reserved above 4G in memory, kernel should
> > > reserve some amount of low memory for swiotlb and some DMA buffers.
> > > So there may be two crash kernel regions, one is below 4G, the other
> > > is above 4G.
> > >
> > > Currently, there is only one crash kernel region on arm64, and pass
> > > "linux,usable-memory-range = <BASE SIZE>" property to crash dump
> > > kernel. Now, we pass
> > > "linux,usable-memory-range = <BASE1 SIZE1 BASE2 SIZE2>" to crash
> > > dump kernel to support two crash kernel regions and load crash
> > > kernel high.
> > >
> > > This patch paves the way for the use of arm64 reserving crashkernel
> > > above 4G. The details are as below:
> > > Link: https://lore.kernel.org/linux-arm-kernel/20190403030546.23718-1-chenzhou10@huawei.com/T/#t
> > >
> > > Signed-off-by: Chen Zhou <chenzhou10@huawei.com>
> >
> > Thanks, applied.
> 
> Sorry, but I think the kernel patch which adds this functionality is
> still under discussion and review (see [1]).
> May be we can wait for the kernel change to be first discussed and
> absorbed and then integrate this patch in kexec-tools.
> 
> What do you think?
> 
> [1]. https://lkml.org/lkml/2019/4/2/1173

Sure, sorry for being a bit too hasty.
I will drop this patch for now.

_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2019-04-10  9:15 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-04-08  9:22 [RESEND PATCH] arm64: support more than one crash kernel regions Chen Zhou
2019-04-08  9:36 ` Simon Horman
2019-04-09  3:59   ` Bhupesh Sharma
2019-04-10  9:15     ` Simon Horman

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.