[RFC PATCH] drivers/of: Fix depth when unflattening devicetree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 




When the implementation for unflatten_dt_node() changed from being
recursive to being non-recursive, it had a side effect of increasing the
depth passed to fdt_next_node() by 1. This is fine most of the time, but
it seems that when the end of the dtb is being parsed, it will cause the
FDT_END condition in fdt_next_node() to return a different value
(returning nextoffset instead of -FDT_ERR_NOTFOUND). This ends up passing
an FDT_ERR_TRUNCATED error back to the unflatten_dt_node() which then
sees that and complains "Error -8 processing FDT" causing boot to fail.

This patch simply avoids incrementing depth and uses modified accesses
for local array indices so that the depth is the same as it was before
the change as far as fdt_next_node() is concerned.

This problem was discovered trying to boot Tegra210-Smaug platforms.

Signed-off-by: Rhyland Klein <rklein@xxxxxxxxxx>
---
 drivers/of/fdt.c | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
index f3da1878eea2..8855ba4f7470 100644
--- a/drivers/of/fdt.c
+++ b/drivers/of/fdt.c
@@ -407,24 +407,24 @@ static int unflatten_dt_node(const void *blob,
 
 	root = dad;
 	fpsizes[depth] = dad ? strlen(of_node_full_name(dad)) : 0;
-	nps[depth++] = dad;
+	nps[depth+1] = dad;
 	for (offset = 0;
 	     offset >= 0;
 	     offset = fdt_next_node(blob, offset, &depth)) {
 		if (WARN_ON_ONCE(depth >= FDT_MAX_DEPTH))
 			continue;
 
-		fpsizes[depth] = populate_node(blob, offset, &mem,
-					       nps[depth - 1],
-					       fpsizes[depth - 1],
-					       &nps[depth], dryrun);
-		if (!fpsizes[depth])
+		fpsizes[depth+1] = populate_node(blob, offset, &mem,
+					       nps[depth],
+					       fpsizes[depth],
+					       &nps[depth+1], dryrun);
+		if (!fpsizes[depth+1])
 			return mem - base;
 
 		if (!dryrun && nodepp && !*nodepp)
-			*nodepp = nps[depth];
+			*nodepp = nps[depth+1];
 		if (!dryrun && !root)
-			root = nps[depth];
+			root = nps[depth+1];
 	}
 
 	if (offset < 0 && offset != -FDT_ERR_NOTFOUND) {
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Device Tree Compilter]     [Device Tree Spec]     [Linux Driver Backports]     [Video for Linux]     [Linux USB Devel]     [Linux PCI Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [XFree86]     [Yosemite Backpacking]
  Powered by Linux