* 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 same 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 --- diff -Naurp gittree/kexec/arch/ppc64/crashdump-ppc64.c gittree-new/kexec/arch/ppc64/crashdump-ppc64.c --- gittree/kexec/arch/ppc64/crashdump-ppc64.c 2006-12-26 14:56:01.000000000 +0530 +++ gittree-new/kexec/arch/ppc64/crashdump-ppc64.c 2007-01-23 19:38:31.000000000 +0530 @@ -120,7 +120,7 @@ static int get_crash_memory_ranges(struc /* 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(struc 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 { 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 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 -Naurp gittree/kexec/arch/ppc64/crashdump-ppc64.h gittree-new/kexec/arch/ppc64/crashdump-ppc64.h --- gittree/kexec/arch/ppc64/crashdump-ppc64.h 2006-12-26 14:56:01.000000000 +0530 +++ gittree-new/kexec/arch/ppc64/crashdump-ppc64.h 2007-01-23 19:09:54.000000000 +0530 @@ -16,10 +16,10 @@ void add_usable_mem_rgns(unsigned long l #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)))