aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/boot/devtree.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/boot/devtree.c')
-rw-r--r--arch/powerpc/boot/devtree.c20
1 files changed, 13 insertions, 7 deletions
diff --git a/arch/powerpc/boot/devtree.c b/arch/powerpc/boot/devtree.c
index ae8b886f5a1d..129e6d9b8d43 100644
--- a/arch/powerpc/boot/devtree.c
+++ b/arch/powerpc/boot/devtree.c
@@ -218,7 +218,7 @@ static int dt_xlate(void *node, int res, int reglen, unsigned long *addr,
218 u32 this_addr[MAX_ADDR_CELLS]; 218 u32 this_addr[MAX_ADDR_CELLS];
219 void *parent; 219 void *parent;
220 u64 ret_addr, ret_size; 220 u64 ret_addr, ret_size;
221 u32 naddr, nsize, prev_naddr; 221 u32 naddr, nsize, prev_naddr, prev_nsize;
222 int buflen, offset; 222 int buflen, offset;
223 223
224 parent = get_parent(node); 224 parent = get_parent(node);
@@ -233,7 +233,7 @@ static int dt_xlate(void *node, int res, int reglen, unsigned long *addr,
233 offset = (naddr + nsize) * res; 233 offset = (naddr + nsize) * res;
234 234
235 if (reglen < offset + naddr + nsize || 235 if (reglen < offset + naddr + nsize ||
236 sizeof(dt_xlate_buf) < offset + naddr + nsize) 236 sizeof(dt_xlate_buf) < (offset + naddr + nsize) * 4)
237 return 0; 237 return 0;
238 238
239 copy_val(last_addr, dt_xlate_buf + offset, naddr); 239 copy_val(last_addr, dt_xlate_buf + offset, naddr);
@@ -244,20 +244,26 @@ static int dt_xlate(void *node, int res, int reglen, unsigned long *addr,
244 ret_size |= dt_xlate_buf[offset + naddr + 1]; 244 ret_size |= dt_xlate_buf[offset + naddr + 1];
245 } 245 }
246 246
247 while ((node = get_parent(node))) { 247 for (;;) {
248 prev_naddr = naddr; 248 prev_naddr = naddr;
249 prev_nsize = nsize;
250 node = parent;
249 251
250 get_reg_format(node, &naddr, &nsize); 252 parent = get_parent(node);
253 if (!parent)
254 break;
255
256 get_reg_format(parent, &naddr, &nsize);
251 257
252 buflen = getprop(node, "ranges", dt_xlate_buf, 258 buflen = getprop(node, "ranges", dt_xlate_buf,
253 sizeof(dt_xlate_buf)); 259 sizeof(dt_xlate_buf));
254 if (buflen < 0) 260 if (buflen == 0)
255 continue; 261 continue;
256 if (buflen > sizeof(dt_xlate_buf)) 262 if (buflen < 0 || buflen > sizeof(dt_xlate_buf))
257 return 0; 263 return 0;
258 264
259 offset = find_range(last_addr, dt_xlate_buf, prev_naddr, 265 offset = find_range(last_addr, dt_xlate_buf, prev_naddr,
260 naddr, nsize, buflen / 4); 266 naddr, prev_nsize, buflen / 4);
261 267
262 if (offset < 0) 268 if (offset < 0)
263 return 0; 269 return 0;