mirror of
https://github.com/Fishwaldo/u-boot.git
synced 2025-06-23 15:11:42 +00:00
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>
This commit is contained in:
parent
63796c4e61
commit
7570a9941f
1 changed files with 19 additions and 15 deletions
|
@ -285,11 +285,14 @@ phys_addr_t __lmb_alloc_base(struct lmb *lmb, phys_size_t size, ulong align, phy
|
||||||
{
|
{
|
||||||
long i, j;
|
long i, j;
|
||||||
phys_addr_t base = 0;
|
phys_addr_t base = 0;
|
||||||
|
phys_addr_t res_base;
|
||||||
|
|
||||||
for (i = lmb->memory.cnt-1; i >= 0; i--) {
|
for (i = lmb->memory.cnt-1; i >= 0; i--) {
|
||||||
phys_addr_t lmbbase = lmb->memory.region[i].base;
|
phys_addr_t lmbbase = lmb->memory.region[i].base;
|
||||||
phys_size_t lmbsize = lmb->memory.region[i].size;
|
phys_size_t lmbsize = lmb->memory.region[i].size;
|
||||||
|
|
||||||
|
if (lmbsize < size)
|
||||||
|
continue;
|
||||||
if (max_addr == LMB_ALLOC_ANYWHERE)
|
if (max_addr == LMB_ALLOC_ANYWHERE)
|
||||||
base = lmb_align_down(lmbbase + lmbsize - size, align);
|
base = lmb_align_down(lmbbase + lmbsize - size, align);
|
||||||
else if (lmbbase < max_addr) {
|
else if (lmbbase < max_addr) {
|
||||||
|
@ -298,22 +301,23 @@ phys_addr_t __lmb_alloc_base(struct lmb *lmb, phys_size_t size, ulong align, phy
|
||||||
} else
|
} else
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
while ((lmbbase <= base) &&
|
while (base && lmbbase <= base) {
|
||||||
((j = lmb_overlaps_region(&(lmb->reserved), base, size)) >= 0) )
|
j = lmb_overlaps_region(&lmb->reserved, base, size);
|
||||||
base = lmb_align_down(lmb->reserved.region[j].base - size,
|
if (j < 0) {
|
||||||
align);
|
/* This area isn't reserved, take it */
|
||||||
|
if (lmb_add_region(&lmb->reserved, base,
|
||||||
if ((base != 0) && (lmbbase <= base))
|
lmb_align_up(size,
|
||||||
break;
|
align)) < 0)
|
||||||
|
return 0;
|
||||||
|
return base;
|
||||||
|
}
|
||||||
|
res_base = lmb->reserved.region[j].base;
|
||||||
|
if (res_base < size)
|
||||||
|
break;
|
||||||
|
base = lmb_align_down(res_base - size, align);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
return 0;
|
||||||
if (i < 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (lmb_add_region(&(lmb->reserved), base, lmb_align_up(size, align)) < 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
return base;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int lmb_is_reserved(struct lmb *lmb, phys_addr_t addr)
|
int lmb_is_reserved(struct lmb *lmb, phys_addr_t addr)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue