summaryrefslogtreecommitdiff
path: root/kexec/arch/ppc64/crashdump-ppc64.c
diff options
context:
space:
mode:
Diffstat (limited to 'kexec/arch/ppc64/crashdump-ppc64.c')
-rw-r--r--kexec/arch/ppc64/crashdump-ppc64.c41
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;