summaryrefslogtreecommitdiff
path: root/kexec/arch/arm64/crashdump-arm64.c
diff options
context:
space:
mode:
Diffstat (limited to 'kexec/arch/arm64/crashdump-arm64.c')
-rw-r--r--kexec/arch/arm64/crashdump-arm64.c44
1 files changed, 26 insertions, 18 deletions
diff --git a/kexec/arch/arm64/crashdump-arm64.c b/kexec/arch/arm64/crashdump-arm64.c
index a02019a..d0f2253 100644
--- a/kexec/arch/arm64/crashdump-arm64.c
+++ b/kexec/arch/arm64/crashdump-arm64.c
@@ -27,11 +27,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;
@@ -119,7 +119,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;
}
/*
@@ -133,6 +133,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.
@@ -140,16 +142,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 regions 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_alloc_and_exclude(&system_memory_rgns,
- &crash_reserved_mem)) {
- fprintf(stderr, "Cannot allocate memory for ranges\n");
- return -ENOMEM;
+ for (i = 0; i < usablemem_rgns.size; i++) {
+ if (mem_regions_alloc_and_exclude(&system_memory_rgns,
+ &crash_reserved_mem[i])) {
+ fprintf(stderr, "Cannot allocate memory for ranges\n");
+ return -ENOMEM;
+ }
}
/*
@@ -210,7 +215,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;
@@ -228,21 +234,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);
}
}
@@ -251,11 +259,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;
}