diff options
Diffstat (limited to 'kexec/arch/ppc64/crashdump-ppc64.c')
-rw-r--r-- | kexec/arch/ppc64/crashdump-ppc64.c | 41 |
1 files changed, 37 insertions, 4 deletions
diff --git a/kexec/arch/ppc64/crashdump-ppc64.c b/kexec/arch/ppc64/crashdump-ppc64.c index e31dd6d..6214b83 100644 --- a/kexec/arch/ppc64/crashdump-ppc64.c +++ b/kexec/arch/ppc64/crashdump-ppc64.c @@ -38,7 +38,11 @@ static struct crash_elf_info elf_info64 = { class: ELFCLASS64, +#if BYTE_ORDER == LITTLE_ENDIAN + data: ELFDATA2LSB, +#else data: ELFDATA2MSB, +#endif machine: EM_PPC64, page_offset: PAGE_OFFSET, lowmem_limit: MAXMEM, @@ -146,12 +150,12 @@ static int get_dyn_reconf_crash_memory_ranges(void) return -1; } - start = ((uint64_t *)buf)[DRCONF_ADDR]; + start = be64_to_cpu(((uint64_t *)buf)[DRCONF_ADDR]); end = start + lmb_size; if (start == 0 && end >= (BACKUP_SRC_END + 1)) start = BACKUP_SRC_END + 1; - flags = (*((uint32_t *)&buf[DRCONF_FLAGS])); + flags = be32_to_cpu((*((uint32_t *)&buf[DRCONF_FLAGS]))); /* skip this block if the reserved bit is set in flags (0x80) or if the block is not assigned to this partition (0x8) */ if ((flags & 0x80) || !(flags & 0x8)) @@ -252,8 +256,9 @@ static int get_crash_memory_ranges(struct memory_range **range, int *ranges) goto err; } - start = ((unsigned long long *)buf)[0]; - end = start + ((unsigned long long *)buf)[1]; + start = be64_to_cpu(((unsigned long long *)buf)[0]); + end = start + + be64_to_cpu(((unsigned long long *)buf)[1]); if (start == 0 && end >= (BACKUP_SRC_END + 1)) start = BACKUP_SRC_END + 1; @@ -293,6 +298,34 @@ static int get_crash_memory_ranges(struct memory_range **range, int *ranges) crash_memory_range[memory_ranges++].end = cend; } + /* + * If OPAL region is overlapped with crashkernel, need to create ELF + * Program header for the overlapped memory. + */ + if (crash_base < opal_base + opal_size && + opal_base < crash_base + crash_size) { + page_size = getpagesize(); + cstart = opal_base; + cend = opal_base + opal_size; + if (cstart < crash_base) + cstart = crash_base; + if (cend > crash_base + crash_size) + cend = crash_base + crash_size; + /* + * The opal section created here is formed by reading opal-base + * and opal-size from /proc/device-tree/ibm,opal. Unfortunately + * opal-size is not required to be a multiple of PAGE_SIZE + * The remainder of the page it ends on is just garbage, and is + * safe to read, its just not accounted in opal-size. Since + * we're creating an elf section here though, lets round it up + * to the next page size boundary though, so makedumpfile can + * read it safely without going south on us. + */ + cend = _ALIGN(cend, page_size); + + crash_memory_range[memory_ranges].start = cstart; + crash_memory_range[memory_ranges++].end = cend; + } *range = crash_memory_range; *ranges = memory_ranges; |