init.c revision 540aca06b737cc38965b52eeceefba3d24376461
1540aca06b737cc38965b52eeceefba3d24376461Pekka Enberg#include <linux/ioport.h> 2e5b2bb552706ca0e30795ee84caacbb37cec5705Pekka Enberg#include <linux/swap.h> 3540aca06b737cc38965b52eeceefba3d24376461Pekka Enberg 4e5b2bb552706ca0e30795ee84caacbb37cec5705Pekka Enberg#include <asm/cacheflush.h> 5e5b2bb552706ca0e30795ee84caacbb37cec5705Pekka Enberg#include <asm/page.h> 6540aca06b737cc38965b52eeceefba3d24376461Pekka Enberg#include <asm/page_types.h> 7e5b2bb552706ca0e30795ee84caacbb37cec5705Pekka Enberg#include <asm/sections.h> 8e5b2bb552706ca0e30795ee84caacbb37cec5705Pekka Enberg#include <asm/system.h> 9e5b2bb552706ca0e30795ee84caacbb37cec5705Pekka Enberg 10540aca06b737cc38965b52eeceefba3d24376461Pekka Enberg/* 11540aca06b737cc38965b52eeceefba3d24376461Pekka Enberg * devmem_is_allowed() checks to see if /dev/mem access to a certain address 12540aca06b737cc38965b52eeceefba3d24376461Pekka Enberg * is valid. The argument is a physical page number. 13540aca06b737cc38965b52eeceefba3d24376461Pekka Enberg * 14540aca06b737cc38965b52eeceefba3d24376461Pekka Enberg * 15540aca06b737cc38965b52eeceefba3d24376461Pekka Enberg * On x86, access has to be given to the first megabyte of ram because that area 16540aca06b737cc38965b52eeceefba3d24376461Pekka Enberg * contains bios code and data regions used by X and dosemu and similar apps. 17540aca06b737cc38965b52eeceefba3d24376461Pekka Enberg * Access has to be given to non-kernel-ram areas as well, these contain the PCI 18540aca06b737cc38965b52eeceefba3d24376461Pekka Enberg * mmio resources as well as potential bios/acpi data regions. 19540aca06b737cc38965b52eeceefba3d24376461Pekka Enberg */ 20540aca06b737cc38965b52eeceefba3d24376461Pekka Enbergint devmem_is_allowed(unsigned long pagenr) 21540aca06b737cc38965b52eeceefba3d24376461Pekka Enberg{ 22540aca06b737cc38965b52eeceefba3d24376461Pekka Enberg if (pagenr <= 256) 23540aca06b737cc38965b52eeceefba3d24376461Pekka Enberg return 1; 24540aca06b737cc38965b52eeceefba3d24376461Pekka Enberg if (iomem_is_exclusive(pagenr << PAGE_SHIFT)) 25540aca06b737cc38965b52eeceefba3d24376461Pekka Enberg return 0; 26540aca06b737cc38965b52eeceefba3d24376461Pekka Enberg if (!page_is_ram(pagenr)) 27540aca06b737cc38965b52eeceefba3d24376461Pekka Enberg return 1; 28540aca06b737cc38965b52eeceefba3d24376461Pekka Enberg return 0; 29540aca06b737cc38965b52eeceefba3d24376461Pekka Enberg} 30540aca06b737cc38965b52eeceefba3d24376461Pekka Enberg 31e5b2bb552706ca0e30795ee84caacbb37cec5705Pekka Enbergvoid free_init_pages(char *what, unsigned long begin, unsigned long end) 32e5b2bb552706ca0e30795ee84caacbb37cec5705Pekka Enberg{ 33e5b2bb552706ca0e30795ee84caacbb37cec5705Pekka Enberg unsigned long addr = begin; 34e5b2bb552706ca0e30795ee84caacbb37cec5705Pekka Enberg 35e5b2bb552706ca0e30795ee84caacbb37cec5705Pekka Enberg if (addr >= end) 36e5b2bb552706ca0e30795ee84caacbb37cec5705Pekka Enberg return; 37e5b2bb552706ca0e30795ee84caacbb37cec5705Pekka Enberg 38e5b2bb552706ca0e30795ee84caacbb37cec5705Pekka Enberg /* 39e5b2bb552706ca0e30795ee84caacbb37cec5705Pekka Enberg * If debugging page accesses then do not free this memory but 40e5b2bb552706ca0e30795ee84caacbb37cec5705Pekka Enberg * mark them not present - any buggy init-section access will 41e5b2bb552706ca0e30795ee84caacbb37cec5705Pekka Enberg * create a kernel page fault: 42e5b2bb552706ca0e30795ee84caacbb37cec5705Pekka Enberg */ 43e5b2bb552706ca0e30795ee84caacbb37cec5705Pekka Enberg#ifdef CONFIG_DEBUG_PAGEALLOC 44e5b2bb552706ca0e30795ee84caacbb37cec5705Pekka Enberg printk(KERN_INFO "debug: unmapping init memory %08lx..%08lx\n", 45e5b2bb552706ca0e30795ee84caacbb37cec5705Pekka Enberg begin, PAGE_ALIGN(end)); 46e5b2bb552706ca0e30795ee84caacbb37cec5705Pekka Enberg set_memory_np(begin, (end - begin) >> PAGE_SHIFT); 47e5b2bb552706ca0e30795ee84caacbb37cec5705Pekka Enberg#else 48e5b2bb552706ca0e30795ee84caacbb37cec5705Pekka Enberg /* 49e5b2bb552706ca0e30795ee84caacbb37cec5705Pekka Enberg * We just marked the kernel text read only above, now that 50e5b2bb552706ca0e30795ee84caacbb37cec5705Pekka Enberg * we are going to free part of that, we need to make that 51e5b2bb552706ca0e30795ee84caacbb37cec5705Pekka Enberg * writeable first. 52e5b2bb552706ca0e30795ee84caacbb37cec5705Pekka Enberg */ 53e5b2bb552706ca0e30795ee84caacbb37cec5705Pekka Enberg set_memory_rw(begin, (end - begin) >> PAGE_SHIFT); 54e5b2bb552706ca0e30795ee84caacbb37cec5705Pekka Enberg 55e5b2bb552706ca0e30795ee84caacbb37cec5705Pekka Enberg printk(KERN_INFO "Freeing %s: %luk freed\n", what, (end - begin) >> 10); 56e5b2bb552706ca0e30795ee84caacbb37cec5705Pekka Enberg 57e5b2bb552706ca0e30795ee84caacbb37cec5705Pekka Enberg for (; addr < end; addr += PAGE_SIZE) { 58e5b2bb552706ca0e30795ee84caacbb37cec5705Pekka Enberg ClearPageReserved(virt_to_page(addr)); 59e5b2bb552706ca0e30795ee84caacbb37cec5705Pekka Enberg init_page_count(virt_to_page(addr)); 60e5b2bb552706ca0e30795ee84caacbb37cec5705Pekka Enberg memset((void *)(addr & ~(PAGE_SIZE-1)), 61e5b2bb552706ca0e30795ee84caacbb37cec5705Pekka Enberg POISON_FREE_INITMEM, PAGE_SIZE); 62e5b2bb552706ca0e30795ee84caacbb37cec5705Pekka Enberg free_page(addr); 63e5b2bb552706ca0e30795ee84caacbb37cec5705Pekka Enberg totalram_pages++; 64e5b2bb552706ca0e30795ee84caacbb37cec5705Pekka Enberg } 65e5b2bb552706ca0e30795ee84caacbb37cec5705Pekka Enberg#endif 66e5b2bb552706ca0e30795ee84caacbb37cec5705Pekka Enberg} 67e5b2bb552706ca0e30795ee84caacbb37cec5705Pekka Enberg 68e5b2bb552706ca0e30795ee84caacbb37cec5705Pekka Enbergvoid free_initmem(void) 69e5b2bb552706ca0e30795ee84caacbb37cec5705Pekka Enberg{ 70e5b2bb552706ca0e30795ee84caacbb37cec5705Pekka Enberg free_init_pages("unused kernel memory", 71e5b2bb552706ca0e30795ee84caacbb37cec5705Pekka Enberg (unsigned long)(&__init_begin), 72e5b2bb552706ca0e30795ee84caacbb37cec5705Pekka Enberg (unsigned long)(&__init_end)); 73e5b2bb552706ca0e30795ee84caacbb37cec5705Pekka Enberg} 74