Commit 7570a9941fc565922078679a72d246fe208d696d
Committed by
Wolfgang Denk
1 parent
63796c4e61
Exists in
master
and in
54 other branches
Fix an underflow bug in __lmb_alloc_base
__lmb_alloc_base can underflow if it fails to find free space. This was fixed in linux with commit d9024df02ffe74d723d97d552f86de3b34beb8cc. This patch merely updates __lmb_alloc_base to resemble the current version in Linux. Signed-off-by: Andy Fleming <afleming@freescale.com>
Showing 1 changed file with 19 additions and 15 deletions Side-by-side Diff
lib_generic/lmb.c
... | ... | @@ -285,11 +285,14 @@ |
285 | 285 | { |
286 | 286 | long i, j; |
287 | 287 | phys_addr_t base = 0; |
288 | + phys_addr_t res_base; | |
288 | 289 | |
289 | 290 | for (i = lmb->memory.cnt-1; i >= 0; i--) { |
290 | 291 | phys_addr_t lmbbase = lmb->memory.region[i].base; |
291 | 292 | phys_size_t lmbsize = lmb->memory.region[i].size; |
292 | 293 | |
294 | + if (lmbsize < size) | |
295 | + continue; | |
293 | 296 | if (max_addr == LMB_ALLOC_ANYWHERE) |
294 | 297 | base = lmb_align_down(lmbbase + lmbsize - size, align); |
295 | 298 | else if (lmbbase < max_addr) { |
296 | 299 | |
... | ... | @@ -298,22 +301,23 @@ |
298 | 301 | } else |
299 | 302 | continue; |
300 | 303 | |
301 | - while ((lmbbase <= base) && | |
302 | - ((j = lmb_overlaps_region(&(lmb->reserved), base, size)) >= 0) ) | |
303 | - base = lmb_align_down(lmb->reserved.region[j].base - size, | |
304 | - align); | |
305 | - | |
306 | - if ((base != 0) && (lmbbase <= base)) | |
307 | - break; | |
304 | + while (base && lmbbase <= base) { | |
305 | + j = lmb_overlaps_region(&lmb->reserved, base, size); | |
306 | + if (j < 0) { | |
307 | + /* This area isn't reserved, take it */ | |
308 | + if (lmb_add_region(&lmb->reserved, base, | |
309 | + lmb_align_up(size, | |
310 | + align)) < 0) | |
311 | + return 0; | |
312 | + return base; | |
313 | + } | |
314 | + res_base = lmb->reserved.region[j].base; | |
315 | + if (res_base < size) | |
316 | + break; | |
317 | + base = lmb_align_down(res_base - size, align); | |
318 | + } | |
308 | 319 | } |
309 | - | |
310 | - if (i < 0) | |
311 | - return 0; | |
312 | - | |
313 | - if (lmb_add_region(&(lmb->reserved), base, lmb_align_up(size, align)) < 0) | |
314 | - return 0; | |
315 | - | |
316 | - return base; | |
320 | + return 0; | |
317 | 321 | } |
318 | 322 | |
319 | 323 | int lmb_is_reserved(struct lmb *lmb, phys_addr_t addr) |