All the attributes exposed in the device tree are in Big Endian format.
This patch add the byte swap operation for some entries which were not yet
processed, including those fixed by the following kernel's patch :
https://lists.ozlabs.org/pipermail/linuxppc-dev/2014-January/114720.html
To work on PPC64 Little Endian mode, kexec now requires that the kernel's
patch mentioned above is applied on the kexecing kernel.
Tested on ppc64 LPAR (kexec/dump) and ppc64le in a Qemu/KVM guest (kexec)
Changes from v1 :
* add processing of the following entries :
- ibm,dynamic-reconfiguration-memory
- chosen/linux,kernel-end
- chosen/linux,crashkernel-base & size
- chosen/linux,memory-limit
- chosen/linux,htab-base & size
- linux,tce-base & size
- memory@/reg
Signed-off-by: Laurent Dufour
---
kexec/arch/ppc64/crashdump-ppc64.c |9 ---
kexec/arch/ppc64/kexec-ppc64.c | 44 +++-
kexec/fs2dt.c | 19
3 files changed, 48 insertions(+), 24 deletions(-)
diff --git a/kexec/arch/ppc64/crashdump-ppc64.c
b/kexec/arch/ppc64/crashdump-ppc64.c
index e31dd6d..c0d575d 100644
--- a/kexec/arch/ppc64/crashdump-ppc64.c
+++ b/kexec/arch/ppc64/crashdump-ppc64.c
@@ -146,12 +146,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 +252,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;
diff --git a/kexec/arch/ppc64/kexec-ppc64.c b/kexec/arch/ppc64/kexec-ppc64.c
index af9112b..49b291d 100644
--- a/kexec/arch/ppc64/kexec-ppc64.c
+++ b/kexec/arch/ppc64/kexec-ppc64.c
@@ -167,7 +167,7 @@ static int get_dyn_reconf_base_ranges(void)
* lmb_size, num_of_lmbs(global variables) are
* initialized once here.
*/
- lmb_size = ((uint64_t *)buf)[0];
+ lmb_size = be64_to_cpu(((uint64_t *)buf)[0]);
fclose(file);
strcpy(fname, "/proc/device-tree/");
@@ -183,7 +183,7 @@ static int get_dyn_reconf_base_ranges(void)
fclose(file);
return -1;
}
- num_of_lmbs = ((unsigned int *)buf)[0];
+ num_of_lmbs = be32_to_cpu(((unsigned int *)buf)[0]);
for (i = 0; i < num_of_lmbs; i++) {
if ((n = fread(buf, 1, 24, file)) < 0) {
@@ -194,7 +194,7 @@ static int get_dyn_reconf_base_ranges(void)
if (nr_memory_ranges >= max_memory_ranges)
return -1;
- start = ((uint64_t *)buf)[0];
+ start = be64_to_cpu(((uint64_t *)buf)[0]);
end = start + lmb_size;
add_base_memory_range(start, end);
}
@@ -278,8 +278,8 @@ static int get_base_ranges(void)
if (realloc_memory_ranges() < 0)
break;
}
- start = ((uint64_t *)buf)[0];
- end = start + ((uint64_t *)buf)[1];
+ start = be64_to_cpu(((uint64_t *)buf)[0]);
+ end = start + be64_to_cpu(((uint64_t *)buf)[1]);
add_base_memory_range(start, end);
fclose(file);
}
@@ -363,6 +363,7 @@ static int get_devtree_details(unsigned long kexec_flags)
goto error_openfile;
}
fclose(file);
+ kernel_end = be64_to_cpu(kernel_end);
/* Add kernel memory to exclude_range */
exclude_range[i].start = 0x0UL;
@@ -386,6 +387,7 @@ static int get_devtree_details(unsigned long kexec_flags)
goto error_openfile;
}