diff options
Diffstat (limited to 'kexec/arch/arm64/crashdump-arm64.c')
-rw-r--r-- | kexec/arch/arm64/crashdump-arm64.c | 44 |
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; } |