init.c revision e5b2bb552706ca0e30795ee84caacbb37cec5705
1e5b2bb552706ca0e30795ee84caacbb37cec5705Pekka Enberg#include <linux/swap.h>
2e5b2bb552706ca0e30795ee84caacbb37cec5705Pekka Enberg#include <asm/cacheflush.h>
3e5b2bb552706ca0e30795ee84caacbb37cec5705Pekka Enberg#include <asm/page.h>
4e5b2bb552706ca0e30795ee84caacbb37cec5705Pekka Enberg#include <asm/sections.h>
5e5b2bb552706ca0e30795ee84caacbb37cec5705Pekka Enberg#include <asm/system.h>
6e5b2bb552706ca0e30795ee84caacbb37cec5705Pekka Enberg
7e5b2bb552706ca0e30795ee84caacbb37cec5705Pekka Enbergvoid free_init_pages(char *what, unsigned long begin, unsigned long end)
8e5b2bb552706ca0e30795ee84caacbb37cec5705Pekka Enberg{
9e5b2bb552706ca0e30795ee84caacbb37cec5705Pekka Enberg	unsigned long addr = begin;
10e5b2bb552706ca0e30795ee84caacbb37cec5705Pekka Enberg
11e5b2bb552706ca0e30795ee84caacbb37cec5705Pekka Enberg	if (addr >= end)
12e5b2bb552706ca0e30795ee84caacbb37cec5705Pekka Enberg		return;
13e5b2bb552706ca0e30795ee84caacbb37cec5705Pekka Enberg
14e5b2bb552706ca0e30795ee84caacbb37cec5705Pekka Enberg	/*
15e5b2bb552706ca0e30795ee84caacbb37cec5705Pekka Enberg	 * If debugging page accesses then do not free this memory but
16e5b2bb552706ca0e30795ee84caacbb37cec5705Pekka Enberg	 * mark them not present - any buggy init-section access will
17e5b2bb552706ca0e30795ee84caacbb37cec5705Pekka Enberg	 * create a kernel page fault:
18e5b2bb552706ca0e30795ee84caacbb37cec5705Pekka Enberg	 */
19e5b2bb552706ca0e30795ee84caacbb37cec5705Pekka Enberg#ifdef CONFIG_DEBUG_PAGEALLOC
20e5b2bb552706ca0e30795ee84caacbb37cec5705Pekka Enberg	printk(KERN_INFO "debug: unmapping init memory %08lx..%08lx\n",
21e5b2bb552706ca0e30795ee84caacbb37cec5705Pekka Enberg		begin, PAGE_ALIGN(end));
22e5b2bb552706ca0e30795ee84caacbb37cec5705Pekka Enberg	set_memory_np(begin, (end - begin) >> PAGE_SHIFT);
23e5b2bb552706ca0e30795ee84caacbb37cec5705Pekka Enberg#else
24e5b2bb552706ca0e30795ee84caacbb37cec5705Pekka Enberg	/*
25e5b2bb552706ca0e30795ee84caacbb37cec5705Pekka Enberg	 * We just marked the kernel text read only above, now that
26e5b2bb552706ca0e30795ee84caacbb37cec5705Pekka Enberg	 * we are going to free part of that, we need to make that
27e5b2bb552706ca0e30795ee84caacbb37cec5705Pekka Enberg	 * writeable first.
28e5b2bb552706ca0e30795ee84caacbb37cec5705Pekka Enberg	 */
29e5b2bb552706ca0e30795ee84caacbb37cec5705Pekka Enberg	set_memory_rw(begin, (end - begin) >> PAGE_SHIFT);
30e5b2bb552706ca0e30795ee84caacbb37cec5705Pekka Enberg
31e5b2bb552706ca0e30795ee84caacbb37cec5705Pekka Enberg	printk(KERN_INFO "Freeing %s: %luk freed\n", what, (end - begin) >> 10);
32e5b2bb552706ca0e30795ee84caacbb37cec5705Pekka Enberg
33e5b2bb552706ca0e30795ee84caacbb37cec5705Pekka Enberg	for (; addr < end; addr += PAGE_SIZE) {
34e5b2bb552706ca0e30795ee84caacbb37cec5705Pekka Enberg		ClearPageReserved(virt_to_page(addr));
35e5b2bb552706ca0e30795ee84caacbb37cec5705Pekka Enberg		init_page_count(virt_to_page(addr));
36e5b2bb552706ca0e30795ee84caacbb37cec5705Pekka Enberg		memset((void *)(addr & ~(PAGE_SIZE-1)),
37e5b2bb552706ca0e30795ee84caacbb37cec5705Pekka Enberg			POISON_FREE_INITMEM, PAGE_SIZE);
38e5b2bb552706ca0e30795ee84caacbb37cec5705Pekka Enberg		free_page(addr);
39e5b2bb552706ca0e30795ee84caacbb37cec5705Pekka Enberg		totalram_pages++;
40e5b2bb552706ca0e30795ee84caacbb37cec5705Pekka Enberg	}
41e5b2bb552706ca0e30795ee84caacbb37cec5705Pekka Enberg#endif
42e5b2bb552706ca0e30795ee84caacbb37cec5705Pekka Enberg}
43e5b2bb552706ca0e30795ee84caacbb37cec5705Pekka Enberg
44e5b2bb552706ca0e30795ee84caacbb37cec5705Pekka Enbergvoid free_initmem(void)
45e5b2bb552706ca0e30795ee84caacbb37cec5705Pekka Enberg{
46e5b2bb552706ca0e30795ee84caacbb37cec5705Pekka Enberg	free_init_pages("unused kernel memory",
47e5b2bb552706ca0e30795ee84caacbb37cec5705Pekka Enberg			(unsigned long)(&__init_begin),
48e5b2bb552706ca0e30795ee84caacbb37cec5705Pekka Enberg			(unsigned long)(&__init_end));
49e5b2bb552706ca0e30795ee84caacbb37cec5705Pekka Enberg}
50