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