Fwd: [PATCH] arm64: Read reg property based on address-cells value.
Anurup M
anurup.m at huawei.com
Thu Jan 22 02:40:46 PST 2015
Hi Geoff,
I have faced an issue during dtb file matching for CPU reg property. The dtb file which
I use has 32 bit value in the reg property as the #address-cells is 1. The kexec-tools code
reads the reg as a 64bit values and reads a invalid value and hence the below comparison in
the function fixup_cpu_nodes fails.
449 result = read_cpu_info(&info_2, dtb_2);
-----------------------
463
464 if (cp_1->hwid != cp_2->hwid)
465 continue;
466
467 to_process--;
-----------------------
476 if (to_process) {
477 fprintf(stderr, "kexec: %s:%d: Warning: Failed to process %u CPUs.\n",
478 __func__, __LINE__, to_process);
479 result = -EINVAL;
480 goto on_exit;
I have written a patch to read the value based on the #address-cells. Please find the patch
below. Please share your comments.
Regards,
Anurup
Signed-off-by: Anurup M <anurup.m at huawei.com>
---
kexec/arch/arm64/kexec-arm64.c | 29 ++++++++++++++++++++++++++---
1 file changed, 26 insertions(+), 3 deletions(-)
diff --git a/kexec/arch/arm64/kexec-arm64.c b/kexec/arch/arm64/kexec-arm64.c
index c1577be..e9c92ba 100644
--- a/kexec/arch/arm64/kexec-arm64.c
+++ b/kexec/arch/arm64/kexec-arm64.c
@@ -141,7 +141,7 @@ struct cpu_properties {
*/
static int read_cpu_properties(struct cpu_properties *cp,
- const struct dtb *dtb, int node_offset)
+ const struct dtb *dtb, int node_offset, int address_cells)
{
int result;
const void *data;
@@ -158,7 +158,18 @@ static int read_cpu_properties(struct cpu_properties *cp,
return result;
}
- cp->hwid = fdt64_to_cpu(*(uint64_t *)data);
+ /* Read the value based on the #address-cells */
+ if (1 == address_cells) {
+ cp->hwid = fdt32_to_cpu(*(uint32_t *)data);
+ }
+ else if (2 == address_cells) {
+ cp->hwid = fdt64_to_cpu(*(uint64_t *)data);
+ }
+ else {
+ fprintf(stderr, "kexec: %s:%d: Invalid #address-cells value: %d\n",
+ __func__, __LINE__, address_cells);
+ return -1;
+ }
result = fdt_get_path(dtb->buf, node_offset, cp->node_path,
sizeof(cp->node_path));
@@ -361,6 +372,8 @@ static int read_cpu_info(struct cpu_info *info, const struct dtb *dtb)
int offset;
int result;
int depth;
+ const void *data;
+ int address_cells = -1;
offset = fdt_subnode_offset(dtb->buf, 0, "cpus");
@@ -370,6 +383,16 @@ static int read_cpu_info(struct cpu_info *info, const struct dtb *dtb)
return offset;
}
+ /* Read the #address-cells to read the CPU address from the reg property */
+ data = fdt_getprop(dtb->buf, offset, "#address-cells", &result);
+
+ if (!data) {
+ fprintf(stderr, "kexec: %s:%d: read #address-cells failed: %s\n",
+ __func__, __LINE__, fdt_strerror(result));
+ return result;
+ }
+ address_cells = fdt32_to_cpu(*(uint32_t *)data);
+
for (i = 0, depth = 0; ; i++) {
offset = fdt_next_node(dtb->buf, offset, &depth);
@@ -395,7 +418,7 @@ static int read_cpu_info(struct cpu_info *info, const struct dtb *dtb)
goto on_error;
}
- result = read_cpu_properties(&info->cp[i], dtb, offset);
+ result = read_cpu_properties(&info->cp[i], dtb, offset, address_cells);
if (result)
goto on_error;
--
1.7.9.5
.
More information about the kexec
mailing list