support more than one crash kernel regions
Signed-off-by: yang_zhuang_zhuang <1162011203@qq.com>
This commit is contained in:
parent
6e4f815d34
commit
7de03dd07f
@ -26,251 +26,283 @@ Signed-off-by: Chen Zhou <chenzhou10@huawei.com>
|
|||||||
kexec/arch/arm64/kexec-arm64.c | 57 +++++++++++++++++++++++++++++---------
|
kexec/arch/arm64/kexec-arm64.c | 57 +++++++++++++++++++++++++++++---------
|
||||||
3 files changed, 72 insertions(+), 32 deletions(-)
|
3 files changed, 72 insertions(+), 32 deletions(-)
|
||||||
|
|
||||||
diff --git a/kexec/arch/arm64/crashdump-arm64.c b/kexec/arch/arm64/crashdump-arm64.c
|
diff --git a/kexec/arch/arm64/crashdump-arm64.c b/kexec/arch/arm64/crashdump-arm64.c
|
||||||
index 4fd7aa8..158e778 100644
|
index 38d1a0f..d8338eb 100644
|
||||||
--- a/kexec/arch/arm64/crashdump-arm64.c
|
--- a/kexec/arch/arm64/crashdump-arm64.c
|
||||||
+++ b/kexec/arch/arm64/crashdump-arm64.c
|
+++ b/kexec/arch/arm64/crashdump-arm64.c
|
||||||
@@ -27,11 +27,11 @@
|
@@ -27,11 +27,11 @@
|
||||||
static struct memory_ranges system_memory_rgns;
|
static struct memory_ranges system_memory_rgns;
|
||||||
|
|
||||||
/* memory range reserved for crashkernel */
|
/* memory range reserved for crashkernel */
|
||||||
-struct memory_range crash_reserved_mem;
|
-struct memory_range crash_reserved_mem;
|
||||||
+struct memory_range crash_reserved_mem[CRASH_MAX_RESERVED_RANGES];
|
+struct memory_range crash_reserved_mem[CRASH_MAX_RESERVED_RANGES];
|
||||||
struct memory_ranges usablemem_rgns = {
|
struct memory_ranges usablemem_rgns = {
|
||||||
.size = 0,
|
.size = 0,
|
||||||
- .max_size = 1,
|
- .max_size = 1,
|
||||||
- .ranges = &crash_reserved_mem,
|
- .ranges = &crash_reserved_mem,
|
||||||
+ .max_size = CRASH_MAX_RESERVED_RANGES,
|
+ .max_size = CRASH_MAX_RESERVED_RANGES,
|
||||||
+ .ranges = crash_reserved_mem,
|
+ .ranges = crash_reserved_mem,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct memory_range elfcorehdr_mem;
|
struct memory_range elfcorehdr_mem;
|
||||||
@@ -108,7 +108,7 @@ int is_crashkernel_mem_reserved(void)
|
@@ -84,7 +84,10 @@ static int iomem_range_callback(void *UNUSED(data), int UNUSED(nr),
|
||||||
if (!usablemem_rgns.size)
|
char *str, unsigned long long base,
|
||||||
kexec_iomem_for_each_line(NULL, iomem_range_callback, NULL);
|
unsigned long long length)
|
||||||
|
{
|
||||||
- return crash_reserved_mem.start != crash_reserved_mem.end;
|
- if (strncmp(str, CRASH_KERNEL, strlen(CRASH_KERNEL)) == 0)
|
||||||
+ return usablemem_rgns.size;
|
+ if (strncmp(str, CRASH_KERNEL_LOW, strlen(CRASH_KERNEL_LOW)) == 0)
|
||||||
}
|
+ return mem_regions_alloc_and_add(&usablemem_rgns,
|
||||||
|
+ base, length, RANGE_RAM);
|
||||||
/*
|
+ else if (strncmp(str, CRASH_KERNEL, strlen(CRASH_KERNEL)) == 0)
|
||||||
@@ -122,6 +122,8 @@ int is_crashkernel_mem_reserved(void)
|
return mem_regions_alloc_and_add(&usablemem_rgns,
|
||||||
*/
|
base, length, RANGE_RAM);
|
||||||
static int crash_get_memory_ranges(void)
|
else if (strncmp(str, SYSTEM_RAM, strlen(SYSTEM_RAM)) == 0)
|
||||||
{
|
@@ -103,7 +106,7 @@ int is_crashkernel_mem_reserved(void)
|
||||||
+ int i;
|
if (!usablemem_rgns.size)
|
||||||
+
|
kexec_iomem_for_each_line(NULL, iomem_range_callback, NULL);
|
||||||
/*
|
|
||||||
* First read all memory regions that can be considered as
|
- return crash_reserved_mem.start != crash_reserved_mem.end;
|
||||||
* system memory including the crash area.
|
+ return usablemem_rgns.size;
|
||||||
@@ -124,16 +126,19 @@ static int crash_get_memory_ranges(void)
|
}
|
||||||
if (!usablemem_rgns.size)
|
|
||||||
kexec_iomem_for_each_line(NULL, iomem_range_callback, NULL);
|
/*
|
||||||
|
@@ -117,6 +120,8 @@ int is_crashkernel_mem_reserved(void)
|
||||||
- /* allow only a single region for crash dump kernel */
|
*/
|
||||||
- if (usablemem_rgns.size != 1)
|
static int crash_get_memory_ranges(void)
|
||||||
+ /* allow one or two region for crash dump kernel */
|
{
|
||||||
+ if (!usablemem_rgns.size)
|
+ int i;
|
||||||
return -EINVAL;
|
+
|
||||||
|
/*
|
||||||
- dbgprint_mem_range("Reserved memory range", &crash_reserved_mem, 1);
|
* First read all memory regions that can be considered as
|
||||||
+ dbgprint_mem_range("Reserved memory range",
|
* system memory including the crash area.
|
||||||
+ usablemem_rgns.ranges, usablemem_rgns.size);
|
@@ -124,16 +129,19 @@ static int crash_get_memory_ranges(void)
|
||||||
|
if (!usablemem_rgns.size)
|
||||||
- if (mem_regions_alloc_and_exclude(&system_memory_rgns,
|
kexec_iomem_for_each_line(NULL, iomem_range_callback, NULL);
|
||||||
- &crash_reserved_mem)) {
|
|
||||||
- fprintf(stderr, "Cannot allocate memory for ranges\n");
|
- /* allow only a single region for crash dump kernel */
|
||||||
- return -ENOMEM;
|
- if (usablemem_rgns.size != 1)
|
||||||
+ for (i = 0; i < usablemem_rgns.size; i++) {
|
+ /* allow one or two region for crash dump kernel */
|
||||||
+ if (mem_regions_exclude(&system_memory_rgns, &crash_reserved_mem[i])) {
|
+ if (!usablemem_rgns.size)
|
||||||
+ fprintf(stderr,
|
return -EINVAL;
|
||||||
+ "Error: Number of crash memory ranges excedeed the max limit\n");
|
|
||||||
+ return -ENOMEM;
|
- 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_alloc_and_exclude(&system_memory_rgns,
|
||||||
@@ -199,7 +204,8 @@ int load_crashdump_segments(struct kexec_info *info)
|
- &crash_reserved_mem)) {
|
||||||
return EFAILED;
|
- fprintf(stderr, "Cannot allocate memory for ranges\n");
|
||||||
|
- return -ENOMEM;
|
||||||
elfcorehdr = add_buffer_phys_virt(info, buf, bufsz, bufsz, 0,
|
+ for (i = 0; i < usablemem_rgns.size; i++) {
|
||||||
- crash_reserved_mem.start, crash_reserved_mem.end,
|
+ if (mem_regions_alloc_and_exclude(&system_memory_rgns,
|
||||||
+ crash_reserved_mem[usablemem_rgns.size - 1].start,
|
+ &crash_reserved_mem[i])) {
|
||||||
+ crash_reserved_mem[usablemem_rgns.size - 1].end,
|
+ fprintf(stderr, "Cannot allocate memory for ranges\n");
|
||||||
-1, 0);
|
+ return -ENOMEM;
|
||||||
|
+ }
|
||||||
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
|
@@ -194,7 +202,8 @@ int load_crashdump_segments(struct kexec_info *info)
|
||||||
* (arm64_mm.phys_offset) will be correctly replaced with
|
return EFAILED;
|
||||||
- * crash_reserved_mem.start.
|
|
||||||
+ * crash_reserved_mem[usablemem_rgns.size - 1].start.
|
elfcorehdr = add_buffer_phys_virt(info, buf, bufsz, bufsz, 0,
|
||||||
*/
|
- crash_reserved_mem.start, crash_reserved_mem.end,
|
||||||
void fixup_elf_addrs(struct mem_ehdr *ehdr)
|
+ crash_reserved_mem[usablemem_rgns.size - 1].start,
|
||||||
{
|
+ crash_reserved_mem[usablemem_rgns.size - 1].end,
|
||||||
struct mem_phdr *phdr;
|
-1, 0);
|
||||||
int i;
|
|
||||||
|
elfcorehdr_mem.start = elfcorehdr;
|
||||||
- ehdr->e_entry += - arm64_mem.phys_offset + crash_reserved_mem.start;
|
@@ -212,21 +221,23 @@ int load_crashdump_segments(struct kexec_info *info)
|
||||||
+ ehdr->e_entry += -arm64_mem.phys_offset +
|
* virt_to_phys() in add_segment().
|
||||||
+ crash_reserved_mem[usablemem_rgns.size - 1].start;
|
* So let's fix up those values for later use so the memory base
|
||||||
|
* (arm64_mm.phys_offset) will be correctly replaced with
|
||||||
for (i = 0; i < ehdr->e_phnum; i++) {
|
- * crash_reserved_mem.start.
|
||||||
phdr = &ehdr->e_phdr[i];
|
+ * crash_reserved_mem[usablemem_rgns.size - 1].start.
|
||||||
if (phdr->p_type != PT_LOAD)
|
*/
|
||||||
continue;
|
void fixup_elf_addrs(struct mem_ehdr *ehdr)
|
||||||
phdr->p_paddr +=
|
{
|
||||||
- (-arm64_mem.phys_offset + crash_reserved_mem.start);
|
struct mem_phdr *phdr;
|
||||||
+ (-arm64_mem.phys_offset +
|
int i;
|
||||||
+ crash_reserved_mem[usablemem_rgns.size - 1].start);
|
|
||||||
}
|
- 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;
|
||||||
@@ -240,11 +248,11 @@ int get_crash_kernel_load_range(uint64_t *start, uint64_t *end)
|
|
||||||
if (!usablemem_rgns.size)
|
for (i = 0; i < ehdr->e_phnum; i++) {
|
||||||
kexec_iomem_for_each_line(NULL, iomem_range_callback, NULL);
|
phdr = &ehdr->e_phdr[i];
|
||||||
|
if (phdr->p_type != PT_LOAD)
|
||||||
- if (!crash_reserved_mem.end)
|
continue;
|
||||||
+ if (!usablemem_rgns.size)
|
phdr->p_paddr +=
|
||||||
return -1;
|
- (-arm64_mem.phys_offset + crash_reserved_mem.start);
|
||||||
|
+ (-arm64_mem.phys_offset +
|
||||||
- *start = crash_reserved_mem.start;
|
+ crash_reserved_mem[usablemem_rgns.size - 1].start);
|
||||||
- *end = crash_reserved_mem.end;
|
}
|
||||||
+ *start = crash_reserved_mem[usablemem_rgns.size - 1].start;
|
}
|
||||||
+ *end = crash_reserved_mem[usablemem_rgns.size - 1].end;
|
|
||||||
|
@@ -235,11 +246,11 @@ int get_crash_kernel_load_range(uint64_t *start, uint64_t *end)
|
||||||
return 0;
|
if (!usablemem_rgns.size)
|
||||||
}
|
kexec_iomem_for_each_line(NULL, iomem_range_callback, NULL);
|
||||||
diff --git a/kexec/arch/arm64/crashdump-arm64.h b/kexec/arch/arm64/crashdump-arm64.h
|
|
||||||
index 880b83a..c07233f 100644
|
- if (!crash_reserved_mem.end)
|
||||||
--- a/kexec/arch/arm64/crashdump-arm64.h
|
+ if (!usablemem_rgns.size)
|
||||||
+++ b/kexec/arch/arm64/crashdump-arm64.h
|
return -1;
|
||||||
@@ -15,9 +15,10 @@
|
|
||||||
#include "kexec.h"
|
- *start = crash_reserved_mem.start;
|
||||||
|
- *end = crash_reserved_mem.end;
|
||||||
#define CRASH_MAX_MEMORY_RANGES 32
|
+ *start = crash_reserved_mem[usablemem_rgns.size - 1].start;
|
||||||
+#define CRASH_MAX_RESERVED_RANGES 8
|
+ *end = crash_reserved_mem[usablemem_rgns.size - 1].end;
|
||||||
|
|
||||||
extern struct memory_ranges usablemem_rgns;
|
return 0;
|
||||||
-extern struct memory_range crash_reserved_mem;
|
}
|
||||||
+extern struct memory_range crash_reserved_mem[];
|
diff --git a/kexec/arch/arm64/crashdump-arm64.h b/kexec/arch/arm64/crashdump-arm64.h
|
||||||
extern struct memory_range elfcorehdr_mem;
|
index 880b83a..12f4308 100644
|
||||||
|
--- a/kexec/arch/arm64/crashdump-arm64.h
|
||||||
extern int load_crashdump_segments(struct kexec_info *info);
|
+++ b/kexec/arch/arm64/crashdump-arm64.h
|
||||||
diff --git a/kexec/arch/arm64/kexec-arm64.c b/kexec/arch/arm64/kexec-arm64.c
|
@@ -16,8 +16,11 @@
|
||||||
index 2992bce..2bf8b66 100644
|
|
||||||
--- a/kexec/arch/arm64/kexec-arm64.c
|
#define CRASH_MAX_MEMORY_RANGES 32
|
||||||
+++ b/kexec/arch/arm64/kexec-arm64.c
|
|
||||||
@@ -414,6 +414,34 @@ static int fdt_setprop_range(void *fdt, int nodeoffset,
|
+/* crash dump kernel support at most two regions, low_region and high region. */
|
||||||
return result;
|
+#define CRASH_MAX_RESERVED_RANGES 2
|
||||||
}
|
+
|
||||||
|
extern struct memory_ranges usablemem_rgns;
|
||||||
+static int fdt_setprop_ranges(void *fdt, int nodeoffset,
|
-extern struct memory_range crash_reserved_mem;
|
||||||
+ const char *name, struct memory_ranges *ranges,
|
+extern struct memory_range crash_reserved_mem[];
|
||||||
+ uint32_t address_cells, uint32_t size_cells)
|
extern struct memory_range elfcorehdr_mem;
|
||||||
+{
|
|
||||||
+ void *buf, *prop;
|
extern int load_crashdump_segments(struct kexec_info *info);
|
||||||
+ size_t buf_size;
|
diff --git a/kexec/arch/arm64/iomem.h b/kexec/arch/arm64/iomem.h
|
||||||
+ int i, result;
|
index d4864bb..45d7953 100644
|
||||||
+
|
--- a/kexec/arch/arm64/iomem.h
|
||||||
+ buf_size = (address_cells + size_cells) * sizeof(uint32_t) *
|
+++ b/kexec/arch/arm64/iomem.h
|
||||||
+ ranges->size;
|
@@ -4,6 +4,7 @@
|
||||||
+ prop = buf = xmalloc(buf_size);
|
#define SYSTEM_RAM "System RAM\n"
|
||||||
+
|
#define KERNEL_CODE "Kernel code\n"
|
||||||
+ for (i = 0; i < ranges->size; i++) {
|
#define KERNEL_DATA "Kernel data\n"
|
||||||
+ fill_property(prop, ranges->ranges[i].start, address_cells);
|
+#define CRASH_KERNEL_LOW "Crash kernel (low)\n"
|
||||||
+ prop += address_cells * sizeof(uint32_t);
|
#define CRASH_KERNEL "Crash kernel\n"
|
||||||
+
|
#define IOMEM_RESERVED "reserved\n"
|
||||||
+ fill_property(prop, ranges->ranges[i].end -
|
|
||||||
+ ranges->ranges[i].start + 1, size_cells);
|
diff --git a/kexec/arch/arm64/kexec-arm64.c b/kexec/arch/arm64/kexec-arm64.c
|
||||||
+ prop += size_cells * sizeof(uint32_t);
|
index 45ebc54..6346f83 100644
|
||||||
+ }
|
--- a/kexec/arch/arm64/kexec-arm64.c
|
||||||
+
|
+++ b/kexec/arch/arm64/kexec-arm64.c
|
||||||
+ result = fdt_setprop(fdt, nodeoffset, name, buf, buf_size);
|
@@ -418,6 +418,42 @@ static int fdt_setprop_range(void *fdt, int nodeoffset,
|
||||||
+
|
return result;
|
||||||
+ free(buf);
|
}
|
||||||
+
|
|
||||||
+ return result;
|
+/*
|
||||||
+}
|
+ * fdt_setprop_ranges - Used for linux,usable-memory-range
|
||||||
+
|
+ */
|
||||||
/**
|
+static int fdt_setprop_ranges(void *fdt, int nodeoffset,
|
||||||
* setup_2nd_dtb - Setup the 2nd stage kernel's dtb.
|
+ const char *name, struct memory_ranges *ranges,
|
||||||
*/
|
+ uint32_t address_cells, uint32_t size_cells)
|
||||||
@@ -428,7 +456,7 @@ static int setup_2nd_dtb(struct dtb *dtb, char *command_line, int on_crash)
|
+{
|
||||||
int len, range_len;
|
+ void *buf, *prop;
|
||||||
int nodeoffset;
|
+ size_t buf_size;
|
||||||
int new_size;
|
+ int i, result;
|
||||||
- int result, kaslr_seed;
|
+
|
||||||
+ int i, result, kaslr_seed;
|
+ buf_size = (address_cells + size_cells) * sizeof(uint32_t) *
|
||||||
|
+ ranges->size;
|
||||||
result = fdt_check_header(dtb->buf);
|
+ prop = buf = xmalloc(buf_size);
|
||||||
|
+
|
||||||
@@ -459,18 +487,21 @@ static int setup_2nd_dtb(struct dtb *dtb, char *command_line, int on_crash)
|
+ /*
|
||||||
goto on_error;
|
+ * crash dump kernel support at most two regions, low_region and high region.
|
||||||
}
|
+ * To make compatibility with existing user-space and older kdump, the low
|
||||||
|
+ * region is always the last range of linux,usable-memory-range if exist.
|
||||||
- if (!cells_size_fitted(address_cells, size_cells,
|
+ */
|
||||||
- &crash_reserved_mem)) {
|
+ for (i = ranges->size - 1; i >= 0; i--) {
|
||||||
- fprintf(stderr, "kexec: usable memory range doesn't fit cells-size.\n");
|
+ fill_property(prop, ranges->ranges[i].start, address_cells);
|
||||||
- result = -EINVAL;
|
+ prop += address_cells * sizeof(uint32_t);
|
||||||
- goto on_error;
|
+
|
||||||
+ for (i = 0; i < usablemem_rgns.size; i++) {
|
+ fill_property(prop, ranges->ranges[i].end -
|
||||||
+ if (!cells_size_fitted(address_cells, size_cells,
|
+ ranges->ranges[i].start + 1, size_cells);
|
||||||
+ &crash_reserved_mem[i])) {
|
+ prop += size_cells * sizeof(uint32_t);
|
||||||
+ fprintf(stderr,
|
+ }
|
||||||
+ "kexec: usable memory range doesn't fit cells-size.\n");
|
+
|
||||||
+ result = -EINVAL;
|
+ result = fdt_setprop(fdt, nodeoffset, name, buf, buf_size);
|
||||||
+ goto on_error;
|
+
|
||||||
+ }
|
+ free(buf);
|
||||||
}
|
+
|
||||||
|
+ return result;
|
||||||
/* 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)
|
* setup_2nd_dtb - Setup the 2nd stage kernel's dtb.
|
||||||
- + fdt_prop_len(PROP_USABLE_MEM_RANGE, range_len);
|
*/
|
||||||
+ + fdt_prop_len(PROP_USABLE_MEM_RANGE, range_len * usablemem_rgns.size);
|
@@ -431,7 +467,7 @@ static int setup_2nd_dtb(struct dtb *dtb, char *command_line, int on_crash)
|
||||||
|
int len, range_len;
|
||||||
new_buf = xmalloc(new_size);
|
int nodeoffset;
|
||||||
result = fdt_open_into(dtb->buf, new_buf, new_size);
|
int new_size;
|
||||||
@@ -565,8 +596,8 @@ static int setup_2nd_dtb(struct dtb *dtb, char *command_line, int on_crash)
|
- int result, kaslr_seed;
|
||||||
|
+ int i, result, kaslr_seed;
|
||||||
/* add linux,usable-memory-range */
|
|
||||||
nodeoffset = fdt_path_offset(new_buf, "/chosen");
|
result = fdt_check_header(dtb->buf);
|
||||||
- result = fdt_setprop_range(new_buf, nodeoffset,
|
|
||||||
- PROP_USABLE_MEM_RANGE, &crash_reserved_mem,
|
@@ -462,18 +498,21 @@ static int setup_2nd_dtb(struct dtb *dtb, char *command_line, int on_crash)
|
||||||
+ result = fdt_setprop_ranges(new_buf, nodeoffset,
|
goto on_error;
|
||||||
+ PROP_USABLE_MEM_RANGE, &usablemem_rgns,
|
}
|
||||||
address_cells, size_cells);
|
|
||||||
if (result) {
|
- if (!cells_size_fitted(address_cells, size_cells,
|
||||||
dbgprintf("%s: fdt_setprop failed: %s\n", __func__,
|
- &crash_reserved_mem)) {
|
||||||
@@ -599,13 +630,13 @@ unsigned long arm64_locate_kernel_segment(struct kexec_info *info)
|
- fprintf(stderr, "kexec: usable memory range doesn't fit cells-size.\n");
|
||||||
if (info->kexec_flags & KEXEC_ON_CRASH) {
|
- result = -EINVAL;
|
||||||
unsigned long hole_end;
|
- goto on_error;
|
||||||
|
+ for (i = 0; i < usablemem_rgns.size; i++) {
|
||||||
- hole = (crash_reserved_mem.start < mem_min ?
|
+ if (!cells_size_fitted(address_cells, size_cells,
|
||||||
- mem_min : crash_reserved_mem.start);
|
+ &crash_reserved_mem[i])) {
|
||||||
+ hole = (crash_reserved_mem[usablemem_rgns.size - 1].start < mem_min ?
|
+ fprintf(stderr,
|
||||||
+ mem_min : crash_reserved_mem[usablemem_rgns.size - 1].start);
|
+ "kexec: usable memory range doesn't fit cells-size.\n");
|
||||||
hole = _ALIGN_UP(hole, MiB(2));
|
+ result = -EINVAL;
|
||||||
hole_end = hole + arm64_mem.text_offset + arm64_mem.image_size;
|
+ goto on_error;
|
||||||
|
+ }
|
||||||
if ((hole_end > mem_max) ||
|
}
|
||||||
- (hole_end > crash_reserved_mem.end)) {
|
|
||||||
+ (hole_end > crash_reserved_mem[usablemem_rgns.size - 1].end)) {
|
/* duplicate dt blob */
|
||||||
dbgprintf("%s: Crash kernel out of range\n", __func__);
|
range_len = sizeof(uint32_t) * (address_cells + size_cells);
|
||||||
hole = ULONG_MAX;
|
new_size = fdt_totalsize(dtb->buf)
|
||||||
}
|
+ fdt_prop_len(PROP_ELFCOREHDR, range_len)
|
||||||
@@ -673,7 +704,7 @@ int arm64_load_other_segments(struct kexec_info *info,
|
- + fdt_prop_len(PROP_USABLE_MEM_RANGE, range_len);
|
||||||
|
+ + fdt_prop_len(PROP_USABLE_MEM_RANGE, range_len * usablemem_rgns.size);
|
||||||
hole_min = image_base + arm64_mem.image_size;
|
|
||||||
if (info->kexec_flags & KEXEC_ON_CRASH)
|
new_buf = xmalloc(new_size);
|
||||||
- hole_max = crash_reserved_mem.end;
|
result = fdt_open_into(dtb->buf, new_buf, new_size);
|
||||||
+ hole_max = crash_reserved_mem[usablemem_rgns.size - 1].end;
|
@@ -569,8 +608,8 @@ static int setup_2nd_dtb(struct dtb *dtb, char *command_line, int on_crash)
|
||||||
else
|
|
||||||
hole_max = ULONG_MAX;
|
/* add linux,usable-memory-range */
|
||||||
|
nodeoffset = fdt_path_offset(new_buf, "/chosen");
|
||||||
--
|
- result = fdt_setprop_range(new_buf, nodeoffset,
|
||||||
2.7.4
|
- 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__,
|
||||||
|
@@ -603,13 +642,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;
|
||||||
|
}
|
||||||
|
@@ -677,7 +716,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.20.1
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
From 7d404ff2549cb9d6d94ec38cee8712cf2feeb39e Mon Sep 17 00:00:00 2001
|
From 5a302cd06079a285cb24a74c0f60b26866ae4e4d Mon Sep 17 00:00:00 2001
|
||||||
From: snoweay <snoweay@163.com>
|
From: snoweay <snoweay@163.com>
|
||||||
Date: Wed, 12 Aug 2020 07:59:06 -0400
|
Date: Wed, 12 Aug 2020 07:59:06 -0400
|
||||||
Subject: [PATCH] kexec: Quick kexec implementation for arm64
|
Subject: [PATCH] kexec: Quick kexec implementation for arm64
|
||||||
@ -8,26 +8,26 @@ Implement quick kexec on arch/arm64.
|
|||||||
Locate kernel segments from reserved memory of range "Quick kexec".
|
Locate kernel segments from reserved memory of range "Quick kexec".
|
||||||
---
|
---
|
||||||
kexec/arch/arm64/iomem.h | 1 +
|
kexec/arch/arm64/iomem.h | 1 +
|
||||||
kexec/arch/arm64/kexec-arm64.c | 39 +++++++++++++++++++---------
|
kexec/arch/arm64/kexec-arm64.c | 42 +++++++++++++++++++++++++-----------
|
||||||
kexec/arch/arm64/kexec-image-arm64.c | 11 ++++++++
|
kexec/arch/arm64/kexec-image-arm64.c | 11 ++++++++++
|
||||||
3 files changed, 39 insertions(+), 12 deletions(-)
|
3 files changed, 41 insertions(+), 13 deletions(-)
|
||||||
|
|
||||||
diff --git a/kexec/arch/arm64/iomem.h b/kexec/arch/arm64/iomem.h
|
diff --git a/kexec/arch/arm64/iomem.h b/kexec/arch/arm64/iomem.h
|
||||||
index d4864bb..108871e 100644
|
index 45d7953..f283f50 100644
|
||||||
--- a/kexec/arch/arm64/iomem.h
|
--- a/kexec/arch/arm64/iomem.h
|
||||||
+++ b/kexec/arch/arm64/iomem.h
|
+++ b/kexec/arch/arm64/iomem.h
|
||||||
@@ -6,5 +6,6 @@
|
@@ -7,5 +7,6 @@
|
||||||
#define KERNEL_DATA "Kernel data\n"
|
#define CRASH_KERNEL_LOW "Crash kernel (low)\n"
|
||||||
#define CRASH_KERNEL "Crash kernel\n"
|
#define CRASH_KERNEL "Crash kernel\n"
|
||||||
#define IOMEM_RESERVED "reserved\n"
|
#define IOMEM_RESERVED "reserved\n"
|
||||||
+#define QUICK_KEXEC "Quick kexec\n"
|
+#define QUICK_KEXEC "Quick kexec\n"
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
diff --git a/kexec/arch/arm64/kexec-arm64.c b/kexec/arch/arm64/kexec-arm64.c
|
diff --git a/kexec/arch/arm64/kexec-arm64.c b/kexec/arch/arm64/kexec-arm64.c
|
||||||
index a3803e3..d12e426 100644
|
index 219ec49..8a3bb69 100644
|
||||||
--- a/kexec/arch/arm64/kexec-arm64.c
|
--- a/kexec/arch/arm64/kexec-arm64.c
|
||||||
+++ b/kexec/arch/arm64/kexec-arm64.c
|
+++ b/kexec/arch/arm64/kexec-arm64.c
|
||||||
@@ -96,6 +96,9 @@ uint64_t get_vp_offset(void)
|
@@ -99,6 +99,9 @@ uint64_t get_vp_offset(void)
|
||||||
return arm64_mem.vp_offset;
|
return arm64_mem.vp_offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -37,7 +37,7 @@ index a3803e3..d12e426 100644
|
|||||||
/**
|
/**
|
||||||
* arm64_process_image_header - Process the arm64 image header.
|
* arm64_process_image_header - Process the arm64 image header.
|
||||||
*
|
*
|
||||||
@@ -624,23 +627,33 @@ on_error:
|
@@ -627,23 +630,33 @@ on_error:
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -83,7 +83,7 @@ index a3803e3..d12e426 100644
|
|||||||
} else {
|
} else {
|
||||||
hole = locate_hole(info,
|
hole = locate_hole(info,
|
||||||
arm64_mem.text_offset + arm64_mem.image_size,
|
arm64_mem.text_offset + arm64_mem.image_size,
|
||||||
@@ -706,6 +719,8 @@ int arm64_load_other_segments(struct kexec_info *info,
|
@@ -709,6 +722,8 @@ int arm64_load_other_segments(struct kexec_info *info,
|
||||||
hole_min = image_base + arm64_mem.image_size;
|
hole_min = image_base + arm64_mem.image_size;
|
||||||
if (info->kexec_flags & KEXEC_ON_CRASH)
|
if (info->kexec_flags & KEXEC_ON_CRASH)
|
||||||
hole_max = crash_reserved_mem[usablemem_rgns.size - 1].end;
|
hole_max = crash_reserved_mem[usablemem_rgns.size - 1].end;
|
||||||
@ -92,6 +92,16 @@ index a3803e3..d12e426 100644
|
|||||||
else
|
else
|
||||||
hole_max = ULONG_MAX;
|
hole_max = ULONG_MAX;
|
||||||
|
|
||||||
|
@@ -944,7 +959,8 @@ static bool to_be_excluded(char *str)
|
||||||
|
if (!strncmp(str, SYSTEM_RAM, strlen(SYSTEM_RAM)) ||
|
||||||
|
!strncmp(str, KERNEL_CODE, strlen(KERNEL_CODE)) ||
|
||||||
|
!strncmp(str, KERNEL_DATA, strlen(KERNEL_DATA)) ||
|
||||||
|
- !strncmp(str, CRASH_KERNEL, strlen(CRASH_KERNEL)))
|
||||||
|
+ !strncmp(str, CRASH_KERNEL, strlen(CRASH_KERNEL)) ||
|
||||||
|
+ !strncmp(str, QUICK_KEXEC, strlen(QUICK_KEXEC)))
|
||||||
|
return false;
|
||||||
|
else
|
||||||
|
return true;
|
||||||
diff --git a/kexec/arch/arm64/kexec-image-arm64.c b/kexec/arch/arm64/kexec-image-arm64.c
|
diff --git a/kexec/arch/arm64/kexec-image-arm64.c b/kexec/arch/arm64/kexec-image-arm64.c
|
||||||
index aa8f2e2..f22db62 100644
|
index aa8f2e2..f22db62 100644
|
||||||
--- a/kexec/arch/arm64/kexec-image-arm64.c
|
--- a/kexec/arch/arm64/kexec-image-arm64.c
|
||||||
@ -129,5 +139,5 @@ index aa8f2e2..f22db62 100644
|
|||||||
|
|
||||||
if (arm64_process_image_header(header))
|
if (arm64_process_image_header(header))
|
||||||
--
|
--
|
||||||
2.19.1
|
2.9.5
|
||||||
|
|
||||||
|
|||||||
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
Name: kexec-tools
|
Name: kexec-tools
|
||||||
Version: 2.0.20
|
Version: 2.0.20
|
||||||
Release: 4
|
Release: 5
|
||||||
License: GPLv2
|
License: GPLv2
|
||||||
Summary: The kexec/kdump userspace component
|
Summary: The kexec/kdump userspace component
|
||||||
URL: https://www.kernel.org/
|
URL: https://www.kernel.org/
|
||||||
@ -339,6 +339,14 @@ done
|
|||||||
%endif
|
%endif
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Mon Mar 22 2021 yangzhuangzhuang <yangzhuangzhuang1@huawei.com> - 2.0.20-5
|
||||||
|
- Type:bugfix
|
||||||
|
- ID:NA
|
||||||
|
- SUG:NA
|
||||||
|
- DESC:support more than one crash kernel regions.
|
||||||
|
Fix bugs of unuseable quick kexec on arm64, becaues of arm64-kexec-allocate-memory-space-avoiding-reserved-regions
|
||||||
|
excluding QUICK_KEXEC memory region.
|
||||||
|
|
||||||
* Mon Sep 14 2020 zhangruifang2020 <zhangruifang1@huawei.com> - 2.0.20-4
|
* Mon Sep 14 2020 zhangruifang2020 <zhangruifang1@huawei.com> - 2.0.20-4
|
||||||
- Type:enhancement
|
- Type:enhancement
|
||||||
- ID:NA
|
- ID:NA
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user