Thread (129 messages) read the whole thread 129 messages, 11 authors, 2007-07-19
STALE6954d

[PATCH 08/61] bootwrapper: dt_xlate_range() bugfixes

From: Scott Wood <hidden>
Date: 2007-07-18 01:33:12
Subsystem: linux for powerpc (32-bit and 64-bit), the rest · Maintainers: Madhavan Srinivasan, Linus Torvalds

1. The check whether ranges fits in the buffer was using elements rather
than bytes.
2. Empty ranges were not properly treated as transparent, and missing
ranges were treated as transparent.
3. The loop terminated when translating from the root rather than to.  Once
bug #2 was fixed, it failed due to a missing ranges in the root node.
4. In decoding the ranges property, the #size-cells used was that of
the parent, not the child.

Signed-off-by: Scott Wood <redacted>
---
 arch/powerpc/boot/devtree.c |   20 +++++++++++++-------
 1 files changed, 13 insertions(+), 7 deletions(-)
diff --git a/arch/powerpc/boot/devtree.c b/arch/powerpc/boot/devtree.c
index 3465d3f..f33c00b 100644
--- a/arch/powerpc/boot/devtree.c
+++ b/arch/powerpc/boot/devtree.c
@@ -219,7 +219,7 @@ static int dt_xlate(void *node, int res, int reglen, unsigned long *addr,
 	u32 this_addr[MAX_ADDR_CELLS];
 	void *parent;
 	u64 ret_addr, ret_size;
-	u32 naddr, nsize, prev_naddr;
+	u32 naddr, nsize, prev_naddr, prev_nsize;
 	int buflen, offset;
 
 	parent = get_parent(node);
@@ -234,7 +234,7 @@ static int dt_xlate(void *node, int res, int reglen, unsigned long *addr,
 	offset = (naddr + nsize) * res;
 
 	if (reglen < offset + naddr + nsize ||
-	    sizeof(dt_xlate_buf) < offset + naddr + nsize)
+	    sizeof(dt_xlate_buf) < (offset + naddr + nsize) * 4)
 		return 0;
 
 	copy_val(last_addr, dt_xlate_buf + offset, naddr);
@@ -245,20 +245,26 @@ static int dt_xlate(void *node, int res, int reglen, unsigned long *addr,
 		ret_size |= dt_xlate_buf[offset + naddr + 1];
 	}
 
-	while ((node = get_parent(node))) {
+	for (;;) {
 		prev_naddr = naddr;
+		prev_nsize = nsize;
+		node = parent;
 
-		get_reg_format(node, &naddr, &nsize);
+		parent = get_parent(node);
+		if (!parent)
+			break;
+
+		get_reg_format(parent, &naddr, &nsize);
 
 		buflen = getprop(node, "ranges", dt_xlate_buf,
 				sizeof(dt_xlate_buf));
-		if (buflen < 0)
+		if (buflen == 0)
 			continue;
-		if (buflen > sizeof(dt_xlate_buf))
+		if (buflen < 0 || buflen > sizeof(dt_xlate_buf))
 			return 0;
 
 		offset = find_range(last_addr, dt_xlate_buf, prev_naddr,
-		                    naddr, nsize, buflen / 4);
+		                    naddr, prev_nsize, buflen / 4);
 
 		if (offset < 0)
 			return 0;
-- 
1.5.0.3
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help