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