Skip to content

Commit

Permalink
bootmem: avoid freeing to bootmem after bootmem is done
Browse files Browse the repository at this point in the history
Bootmem isn't popular any more, but some architectures still use it, and
freeing to bootmem after calling free_all_bootmem_core() can end up
scribbling over random memory.  Instead, make sure the kernel generates
a warning in this case by ensuring the node_bootmem_map field is
non-NULL when are freeing or marking bootmem.

An instance of this bug was just fixed in the tile architecture ("tile:
use free_bootmem_late() for initrd") and catching this case more widely
seems like a good thing.

Signed-off-by: Chris Metcalf <cmetcalf@ezchip.com>
Acked-by: Mel Gorman <mgorman@suse.de>
Cc: Yasuaki Ishimatsu <isimatu.yasuaki@jp.fujitsu.com>
Cc: Pekka Enberg <penberg@kernel.org>
Cc: Paul McQuade <paulmcquad@gmail.com>
Cc: Tang Chen <tangchen@cn.fujitsu.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
  • Loading branch information
Chris Metcalf authored and Linus Torvalds committed Sep 8, 2015
1 parent c5b4e1b commit 1b4ace4
Showing 1 changed file with 7 additions and 0 deletions.
7 changes: 7 additions & 0 deletions mm/bootmem.c
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,7 @@ static unsigned long __init free_all_bootmem_core(bootmem_data_t *bdata)
count += pages;
while (pages--)
__free_pages_bootmem(page++, cur++, 0);
bdata->node_bootmem_map = NULL;

bdebug("nid=%td released=%lx\n", bdata - bootmem_node_data, count);

Expand Down Expand Up @@ -294,6 +295,9 @@ static void __init __free(bootmem_data_t *bdata,
sidx + bdata->node_min_pfn,
eidx + bdata->node_min_pfn);

if (WARN_ON(bdata->node_bootmem_map == NULL))
return;

if (bdata->hint_idx > sidx)
bdata->hint_idx = sidx;

Expand All @@ -314,6 +318,9 @@ static int __init __reserve(bootmem_data_t *bdata, unsigned long sidx,
eidx + bdata->node_min_pfn,
flags);

if (WARN_ON(bdata->node_bootmem_map == NULL))
return 0;

for (idx = sidx; idx < eidx; idx++)
if (test_and_set_bit(idx, bdata->node_bootmem_map)) {
if (exclusive) {
Expand Down

0 comments on commit 1b4ace4

Please sign in to comment.