Skip to contentSkip to conversation

arm64: Read reg property based on address-cells value.

PATCH In review Anurup M 2 participants 2 messages Jan 22, 2015 1 message not in the archive

Subsystems (2)
lore
Share & tools
lore

A message that is not in the archive (sent off-list or not yet received): [email protected]

Anurup M

author
#1 lore raw

PATCH 1/1 arm64: Read reg property based on address-cells value.

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

---
 kexec/arch/arm64/kexec-arm64.c |   29 ++++++++++++++++++++++++++---
 1 file changed, 26 insertions(+), 3 deletions(-)
kexec/arch/arm64/kexec-arm64.c +26 -3
index c1577be..e9c92ba 100644
@@ -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;
Signature · 13 lines
1.7.9.5


.





_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec
#2 lore raw

Hi Anurup,

Quoted 4 lines · Anurup M

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.

Thanks for reporting. I pushed out a fix very similar to yours. I only tested on a dtb with address-cells=2 though. Let me know if it doesn't work for you.

git://git.kernel.org/pub/scm/linux/kernel/git/geoff/kexec-tools.git

-Geoff

_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec