Commit 7570a9941fc565922078679a72d246fe208d696d

Authored by Andy Fleming
Committed by Wolfgang Denk
1 parent 63796c4e61

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

... ... @@ -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)