diff mbox

drivers/of: Fix depth when unflattening devicetree

Message ID 1462988217-29314-1-git-send-email-rklein@nvidia.com
State Accepted, archived
Delegated to: Jon Hunter
Headers show

Commit Message

Rhyland Klein May 11, 2016, 5:36 p.m. UTC
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.

Cc: stable@vger.kernel.org
Fixes: 9ffa9eb41763 ("drivers/of: Avoid recursively calling unflatten_dt_node()")
Signed-off-by: Rhyland Klein <rklein@nvidia.com>
---
 drivers/of/fdt.c | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

Comments

Rob Herring (Arm) May 16, 2016, 2:10 p.m. UTC | #1
On Wed, May 11, 2016 at 01:36:57PM -0400, Rhyland Klein wrote:
> 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.
> 
> Cc: stable@vger.kernel.org
> Fixes: 9ffa9eb41763 ("drivers/of: Avoid recursively calling unflatten_dt_node()")
> Signed-off-by: Rhyland Klein <rklein@nvidia.com>
> ---
>  drivers/of/fdt.c | 16 ++++++++--------
>  1 file changed, 8 insertions(+), 8 deletions(-)

Applied, thanks.

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

Patch

diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
index df9f4e8dfa00..becb025702d7 100644
--- a/drivers/of/fdt.c
+++ b/drivers/of/fdt.c
@@ -407,24 +407,24 @@  static int unflatten_dt_nodes(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) {