| #include <linux/ioport.h> |
| #include <linux/swap.h> |
| |
| #include <asm/cacheflush.h> |
| #include <asm/page.h> |
| #include <asm/page_types.h> |
| #include <asm/sections.h> |
| #include <asm/system.h> |
| |
| /* |
| * devmem_is_allowed() checks to see if /dev/mem access to a certain address |
| * is valid. The argument is a physical page number. |
| * |
| * |
| * On x86, access has to be given to the first megabyte of ram because that area |
| * contains bios code and data regions used by X and dosemu and similar apps. |
| * Access has to be given to non-kernel-ram areas as well, these contain the PCI |
| * mmio resources as well as potential bios/acpi data regions. |
| */ |
| int devmem_is_allowed(unsigned long pagenr) |
| { |
| if (pagenr <= 256) |
| return 1; |
| if (iomem_is_exclusive(pagenr << PAGE_SHIFT)) |
| return 0; |
| if (!page_is_ram(pagenr)) |
| return 1; |
| return 0; |
| } |
| |
| void free_init_pages(char *what, unsigned long begin, unsigned long end) |
| { |
| unsigned long addr = begin; |
| |
| if (addr >= end) |
| return; |
| |
| /* |
| * If debugging page accesses then do not free this memory but |
| * mark them not present - any buggy init-section access will |
| * create a kernel page fault: |
| */ |
| #ifdef CONFIG_DEBUG_PAGEALLOC |
| printk(KERN_INFO "debug: unmapping init memory %08lx..%08lx\n", |
| begin, PAGE_ALIGN(end)); |
| set_memory_np(begin, (end - begin) >> PAGE_SHIFT); |
| #else |
| /* |
| * We just marked the kernel text read only above, now that |
| * we are going to free part of that, we need to make that |
| * writeable first. |
| */ |
| set_memory_rw(begin, (end - begin) >> PAGE_SHIFT); |
| |
| printk(KERN_INFO "Freeing %s: %luk freed\n", what, (end - begin) >> 10); |
| |
| for (; addr < end; addr += PAGE_SIZE) { |
| ClearPageReserved(virt_to_page(addr)); |
| init_page_count(virt_to_page(addr)); |
| memset((void *)(addr & ~(PAGE_SIZE-1)), |
| POISON_FREE_INITMEM, PAGE_SIZE); |
| free_page(addr); |
| totalram_pages++; |
| } |
| #endif |
| } |
| |
| void free_initmem(void) |
| { |
| free_init_pages("unused kernel memory", |
| (unsigned long)(&__init_begin), |
| (unsigned long)(&__init_end)); |
| } |