diff options
Diffstat (limited to 'arch/powerpc/boot/devtree.c')
-rw-r--r-- | 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 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; |