lkml.org 
[lkml]   [2008]   [Mar]   [21]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
/
Date
From
SubjectRe: [PATCH] mm: fix boundary checking in free_bootmem_core

* Andrew Morton <akpm@linux-foundation.org> wrote:

> diff -puN mm/bootmem.c~mm-fix-boundary-checking-in-free_bootmem_core mm/bootmem.c
> --- a/mm/bootmem.c~mm-fix-boundary-checking-in-free_bootmem_core
> +++ a/mm/bootmem.c
> @@ -125,6 +125,7 @@ static int __init reserve_bootmem_core(b
> BUG_ON(!size);
> BUG_ON(PFN_DOWN(addr) >= bdata->node_low_pfn);
> BUG_ON(PFN_UP(addr + size) > bdata->node_low_pfn);
> + BUG_ON(addr < bdata->node_boot_start);
>
> sidx = PFN_DOWN(addr - bdata->node_boot_start);
> eidx = PFN_UP(addr + size - bdata->node_boot_start);
> @@ -156,21 +157,31 @@ static void __init free_bootmem_core(boo
> unsigned long sidx, eidx;
> unsigned long i;
>
> + BUG_ON(!size);
> +
> + /* out range */
> + if (addr + size < bdata->node_boot_start ||
> + PFN_DOWN(addr) > bdata->node_low_pfn)
> + return;
> /*
> * round down end of usable mem, partially free pages are
> * considered reserved.
> */
> - BUG_ON(!size);
> - BUG_ON(PFN_DOWN(addr + size) > bdata->node_low_pfn);
>
> - if (addr < bdata->last_success)
> + if (addr >= bdata->node_boot_start && addr < bdata->last_success)
> bdata->last_success = addr;
>
> /*
> - * Round up the beginning of the address.
> + * Round up to index to the range.
> */
> - sidx = PFN_UP(addr) - PFN_DOWN(bdata->node_boot_start);
> + if (PFN_UP(addr) > PFN_DOWN(bdata->node_boot_start))
> + sidx = PFN_UP(addr) - PFN_DOWN(bdata->node_boot_start);
> + else
> + sidx = 0;
> +
> eidx = PFN_DOWN(addr + size - bdata->node_boot_start);
> + if (eidx > bdata->node_low_pfn - PFN_DOWN(bdata->node_boot_start))
> + eidx = bdata->node_low_pfn - PFN_DOWN(bdata->node_boot_start);
>
> for (i = sidx; i < eidx; i++) {
> if (unlikely(!test_and_clear_bit(i, bdata->node_bootmem_map)))
> @@ -421,7 +432,9 @@ int __init reserve_bootmem(unsigned long
>
> void __init free_bootmem(unsigned long addr, unsigned long size)
> {
> - free_bootmem_core(NODE_DATA(0)->bdata, addr, size);
> + bootmem_data_t *bdata;
> + list_for_each_entry(bdata, &bdata_list, list)
> + free_bootmem_core(bdata, addr, size);
> }
>
> unsigned long __init free_all_bootmem(void)

note, this combination is quite well tested now, on various x86 systems,
small and large alike, and about a 100 randconfigs booted up.

Acked-by: Ingo Molnar <mingo@elte.hu>
Tested-by: Ingo Molnar <mingo@elte.hu>

Ingo


\
 
 \ /
  Last update: 2008-03-21 21:03    [W:0.048 / U:0.076 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site