From f8afe9befb4918853b3002725e53ddbbd43cf719 Mon Sep 17 00:00:00 2001 From: "Sachin P. Sant" Date: Tue, 23 Jan 2007 20:12:33 +0530 Subject: cp /proc/vmcore fails on core generated using latest kexec tools. * On ppc64 memory ranges in device-tree is denoted as start and size. * While in case of other architectures like i386 it is represented as start and * end. Because of this when loading the memory ranges in crashdump-elf.c the * filesz calculation using start and end values of memory range goes for a toss. * * phdr->p_filesz = phdr->p_memsz = mend - mstart + 1; * * Because of the +1 in above statement the generated vmcore is not a valid * dump file. * * There are different ways in which this problem can be fixed. * A. Add a ifdef in crashdump-elf.c for elf machine type. * if EM_PPC64 then * filesz = end - start; * else * filesz = end - start + 1; * fi * B. Change the ppc64 specific code so as to follow the i386 convention when * it comes to representing memory ranges. * C. Create a PPC64 specific function to populate crash ranges and not use * the generic function from crashdump-elf.c * * Of all these solutions B is the smallest and works well. Here is a patch * to implement the same. * Signed-off-by : Sachin Sant Removed trailing whitespace Signed-off-by : Simon Horman --- kexec/arch/ppc64/crashdump-ppc64.c | 25 +++++++++++++++++++++---- kexec/arch/ppc64/crashdump-ppc64.h | 4 ++-- 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/kexec/arch/ppc64/crashdump-ppc64.c b/kexec/arch/ppc64/crashdump-ppc64.c index 33d4b18..d3231b6 100644 --- a/kexec/arch/ppc64/crashdump-ppc64.c +++ b/kexec/arch/ppc64/crashdump-ppc64.c @@ -120,7 +120,7 @@ static int get_crash_memory_ranges(struct memory_range **range, int *ranges) /* create a separate program header for the backup region */ crash_memory_range[0].start = BACKUP_SRC_START; - crash_memory_range[0].end = BACKUP_SRC_END; + crash_memory_range[0].end = BACKUP_SRC_END + 1; crash_memory_range[0].type = RANGE_RAM; memory_ranges++; @@ -165,8 +165,8 @@ static int get_crash_memory_ranges(struct memory_range **range, int *ranges) start = ((unsigned long long *)buf)[0]; end = start + ((unsigned long long *)buf)[1]; - if (start == 0 && end >= BACKUP_SRC_END) - start = BACKUP_SRC_END; + if (start == 0 && end >= (BACKUP_SRC_END + 1)) + start = BACKUP_SRC_END + 1; cstart = crash_base; cend = crash_base + crash_size; @@ -309,7 +309,8 @@ int load_crashdump_segments(struct kexec_info *info, char* mod_cmdline, { void *tmp; unsigned long sz, elfcorehdr; - int nr_ranges, align = 1024; + int nr_ranges, align = 1024, i; + unsigned long long end; struct memory_range *mem_range; if (get_crash_memory_ranges(&mem_range, &nr_ranges) < 0) @@ -323,6 +324,22 @@ int load_crashdump_segments(struct kexec_info *info, char* mod_cmdline, 0, max_addr, 1); reserve(info->backup_start, sz); + /* On ppc64 memory ranges in device-tree is denoted as start + * and size rather than start and end, as is the case with + * other architectures like i386 . Because of this when loading + * the memory ranges in crashdump-elf.c the filesz calculation + * [ end - start + 1 ] goes for a toss. + * + * To be in sync with other archs adjust the end value for + * every crash memory range before calling the generic function + */ + + for (i = 0; i < nr_ranges; i++) { + end = crash_memory_range[i].end - 1; + crash_memory_range[i].end = end; + } + + /* Create elf header segment and store crash image data. */ if (arch_options.core_header_type == CORE_TYPE_ELF64) { if (crash_create_elf64_headers(info, &elf_info64, diff --git a/kexec/arch/ppc64/crashdump-ppc64.h b/kexec/arch/ppc64/crashdump-ppc64.h index db44df2..583338a 100644 --- a/kexec/arch/ppc64/crashdump-ppc64.h +++ b/kexec/arch/ppc64/crashdump-ppc64.h @@ -16,10 +16,10 @@ void add_usable_mem_rgns(unsigned long long base, unsigned long long size); #define COMMAND_LINE_SIZE 512 /* from kernel */ /* Backup Region, First 64K of System RAM. */ #define BACKUP_SRC_START 0x0000 -#define BACKUP_SRC_END 0x10000 +#define BACKUP_SRC_END 0xffff #define BACKUP_SRC_SIZE (BACKUP_SRC_END - BACKUP_SRC_START + 1) -#define KDUMP_BACKUP_LIMIT BACKUP_SRC_END +#define KDUMP_BACKUP_LIMIT BACKUP_SRC_SIZE #define _ALIGN_UP(addr,size) (((addr)+((size)-1))&(~((size)-1))) #define _ALIGN_DOWN(addr,size) ((addr)&(~((size)-1))) -- cgit