代码拉取完成,页面将自动刷新
同步操作将从 src-openEuler/kexec-tools 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
From 6633170a04b1fc55eb72adc0150ffcd1b85be8ce Mon Sep 17 00:00:00 2001
From: Chen Zhou <chenzhou10@huawei.com>
Date: Fri, 29 Mar 2019 21:01:29 +0800
Subject: [PATCH] kexec-tools: support more than one crash kernel regions
reason: 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.
*/
@@ -428,7 +456,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);
@@ -459,18 +487,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
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。