include cleanup: Update gfp.h and slab.h includes to prepare for breaking implicit...
[safe/jmp/linux-2.6] / arch / x86 / mm / init_64.c
index 66d6be8..ee41bba 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/module.h>
 #include <linux/memory_hotplug.h>
 #include <linux/nmi.h>
+#include <linux/gfp.h>
 
 #include <asm/processor.h>
 #include <asm/bios_ebda.h>
 #include <asm/numa.h>
 #include <asm/cacheflush.h>
 #include <asm/init.h>
-
-/*
- * end_pfn only includes RAM, while max_pfn_mapped includes all e820 entries.
- * The direct mapping extends to max_pfn_mapped, so that we can directly access
- * apertures, ACPI and other tables without having to play with fixmaps.
- */
-unsigned long max_low_pfn_mapped;
-unsigned long max_pfn_mapped;
+#include <linux/bootmem.h>
 
 static unsigned long dma_reserve __initdata;
 
-DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
-
 static int __init parse_direct_gbpages_off(char *arg)
 {
        direct_gbpages = 0;
@@ -85,39 +77,6 @@ early_param("gbpages", parse_direct_gbpages_on);
 pteval_t __supported_pte_mask __read_mostly = ~_PAGE_IOMAP;
 EXPORT_SYMBOL_GPL(__supported_pte_mask);
 
-static int do_not_nx __cpuinitdata;
-
-/*
- * noexec=on|off
- * Control non-executable mappings for 64-bit processes.
- *
- * on  Enable (default)
- * off Disable
- */
-static int __init nonx_setup(char *str)
-{
-       if (!str)
-               return -EINVAL;
-       if (!strncmp(str, "on", 2)) {
-               __supported_pte_mask |= _PAGE_NX;
-               do_not_nx = 0;
-       } else if (!strncmp(str, "off", 3)) {
-               do_not_nx = 1;
-               __supported_pte_mask &= ~_PAGE_NX;
-       }
-       return 0;
-}
-early_param("noexec", nonx_setup);
-
-void __cpuinit check_efer(void)
-{
-       unsigned long efer;
-
-       rdmsrl(MSR_EFER, efer);
-       if (!(efer & EFER_NX) || do_not_nx)
-               __supported_pte_mask &= ~_PAGE_NX;
-}
-
 int force_personality32;
 
 /*
@@ -147,7 +106,7 @@ static __ref void *spp_getpage(void)
        void *ptr;
 
        if (after_bootmem)
-               ptr = (void *) get_zeroed_page(GFP_ATOMIC);
+               ptr = (void *) get_zeroed_page(GFP_ATOMIC | __GFP_NOTRACK);
        else
                ptr = alloc_bootmem_pages(PAGE_SIZE);
 
@@ -324,7 +283,7 @@ static __ref void *alloc_low_page(unsigned long *phys)
        void *adr;
 
        if (after_bootmem) {
-               adr = (void *)get_zeroed_page(GFP_ATOMIC);
+               adr = (void *)get_zeroed_page(GFP_ATOMIC | __GFP_NOTRACK);
                *phys = __pa(adr);
 
                return adr;
@@ -570,7 +529,7 @@ phys_pud_update(pgd_t *pgd, unsigned long addr, unsigned long end,
        return phys_pud_init(pud, addr, end, page_size_mask);
 }
 
-unsigned long __init
+unsigned long __meminit
 kernel_physical_mapping_init(unsigned long start,
                             unsigned long end,
                             unsigned long page_size_mask)
@@ -611,8 +570,10 @@ kernel_physical_mapping_init(unsigned long start,
 }
 
 #ifndef CONFIG_NUMA
-void __init initmem_init(unsigned long start_pfn, unsigned long end_pfn)
+void __init initmem_init(unsigned long start_pfn, unsigned long end_pfn,
+                               int acpi, int k8)
 {
+#ifndef CONFIG_NO_BOOTMEM
        unsigned long bootmap_size, bootmap;
 
        bootmap_size = bootmem_bootmap_pages(end_pfn)<<PAGE_SHIFT;
@@ -620,14 +581,17 @@ void __init initmem_init(unsigned long start_pfn, unsigned long end_pfn)
                                 PAGE_SIZE);
        if (bootmap == -1L)
                panic("Cannot find bootmem map of size %ld\n", bootmap_size);
+       reserve_early(bootmap, bootmap + bootmap_size, "BOOTMAP");
        /* don't touch min_low_pfn */
        bootmap_size = init_bootmem_node(NODE_DATA(0), bootmap >> PAGE_SHIFT,
                                         0, end_pfn);
        e820_register_active_regions(0, start_pfn, end_pfn);
        free_bootmem_with_active_regions(0, end_pfn);
-       early_res_to_bootmem(0, end_pfn<<PAGE_SHIFT);
-       reserve_bootmem(bootmap, bootmap_size, BOOTMEM_DEFAULT);
+#else
+       e820_register_active_regions(0, start_pfn, end_pfn);
+#endif
 }
+#endif
 
 void __init paging_init(void)
 {
@@ -638,17 +602,40 @@ void __init paging_init(void)
        max_zone_pfns[ZONE_DMA32] = MAX_DMA32_PFN;
        max_zone_pfns[ZONE_NORMAL] = max_pfn;
 
-       memory_present(0, 0, max_pfn);
+       sparse_memory_present_with_active_regions(MAX_NUMNODES);
        sparse_init();
+
+       /*
+        * clear the default setting with node 0
+        * note: don't use nodes_clear here, that is really clearing when
+        *       numa support is not compiled in, and later node_set_state
+        *       will not set it back.
+        */
+       node_clear_state(0, N_NORMAL_MEMORY);
+
        free_area_init_nodes(max_zone_pfns);
 }
-#endif
 
 /*
  * Memory hotplug specific functions
  */
 #ifdef CONFIG_MEMORY_HOTPLUG
 /*
+ * After memory hotplug the variables max_pfn, max_low_pfn and high_memory need
+ * updating.
+ */
+static void  update_end_of_memory_vars(u64 start, u64 size)
+{
+       unsigned long end_pfn = PFN_UP(start + size);
+
+       if (end_pfn > max_pfn) {
+               max_pfn = end_pfn;
+               max_low_pfn = end_pfn;
+               high_memory = (void *)__va(max_pfn * PAGE_SIZE - 1) + 1;
+       }
+}
+
+/*
  * Memory is added always to NORMAL zone. This means you will never get
  * additional DMA/DMA32 memory.
  */
@@ -667,6 +654,9 @@ int arch_add_memory(int nid, u64 start, u64 size)
        ret = __add_pages(nid, zone, start_pfn, nr_pages);
        WARN_ON_ONCE(ret);
 
+       /* update max_pfn, max_low_pfn and high_memory */
+       update_end_of_memory_vars(start, size);
+
        return ret;
 }
 EXPORT_SYMBOL_GPL(arch_add_memory);
@@ -681,8 +671,7 @@ EXPORT_SYMBOL_GPL(memory_add_physaddr_to_nid);
 
 #endif /* CONFIG_MEMORY_HOTPLUG */
 
-static struct kcore_list kcore_mem, kcore_vmalloc, kcore_kernel,
-                        kcore_modules, kcore_vsyscall;
+static struct kcore_list kcore_vsyscall;
 
 void __init mem_init(void)
 {
@@ -711,17 +700,12 @@ void __init mem_init(void)
        initsize =  (unsigned long) &__init_end - (unsigned long) &__init_begin;
 
        /* Register memory areas for /proc/kcore */
-       kclist_add(&kcore_mem, __va(0), max_low_pfn << PAGE_SHIFT);
-       kclist_add(&kcore_vmalloc, (void *)VMALLOC_START,
-                  VMALLOC_END-VMALLOC_START);
-       kclist_add(&kcore_kernel, &_stext, _end - _stext);
-       kclist_add(&kcore_modules, (void *)MODULES_VADDR, MODULES_LEN);
        kclist_add(&kcore_vsyscall, (void *)VSYSCALL_START,
-                                VSYSCALL_END - VSYSCALL_START);
+                        VSYSCALL_END - VSYSCALL_START, KCORE_OTHER);
 
        printk(KERN_INFO "Memory: %luk/%luk available (%ldk kernel code, "
                         "%ldk absent, %ldk reserved, %ldk data, %ldk init)\n",
-               (unsigned long) nr_free_pages() << (PAGE_SHIFT-10),
+               nr_free_pages() << (PAGE_SHIFT-10),
                max_pfn << (PAGE_SHIFT-10),
                codesize >> 10,
                absent_pages << (PAGE_SHIFT-10),
@@ -734,12 +718,12 @@ void __init mem_init(void)
 const int rodata_test_data = 0xC3;
 EXPORT_SYMBOL_GPL(rodata_test_data);
 
-static int kernel_set_to_readonly;
+int kernel_set_to_readonly;
 
 void set_kernel_text_rw(void)
 {
-       unsigned long start = PFN_ALIGN(_stext);
-       unsigned long end = PFN_ALIGN(__start_rodata);
+       unsigned long start = PFN_ALIGN(_text);
+       unsigned long end = PFN_ALIGN(__stop___ex_table);
 
        if (!kernel_set_to_readonly)
                return;
@@ -747,13 +731,18 @@ void set_kernel_text_rw(void)
        pr_debug("Set kernel text: %lx - %lx for read write\n",
                 start, end);
 
+       /*
+        * Make the kernel identity mapping for text RW. Kernel text
+        * mapping will always be RO. Refer to the comment in
+        * static_protections() in pageattr.c
+        */
        set_memory_rw(start, (end - start) >> PAGE_SHIFT);
 }
 
 void set_kernel_text_ro(void)
 {
-       unsigned long start = PFN_ALIGN(_stext);
-       unsigned long end = PFN_ALIGN(__start_rodata);
+       unsigned long start = PFN_ALIGN(_text);
+       unsigned long end = PFN_ALIGN(__stop___ex_table);
 
        if (!kernel_set_to_readonly)
                return;
@@ -761,14 +750,21 @@ void set_kernel_text_ro(void)
        pr_debug("Set kernel text: %lx - %lx for read only\n",
                 start, end);
 
+       /*
+        * Set the kernel identity mapping for text RO.
+        */
        set_memory_ro(start, (end - start) >> PAGE_SHIFT);
 }
 
 void mark_rodata_ro(void)
 {
-       unsigned long start = PFN_ALIGN(_stext), end = PFN_ALIGN(__end_rodata);
+       unsigned long start = PFN_ALIGN(_text);
        unsigned long rodata_start =
                ((unsigned long)__start_rodata + PAGE_SIZE - 1) & PAGE_MASK;
+       unsigned long end = (unsigned long) &__end_rodata_hpage_align;
+       unsigned long text_end = PAGE_ALIGN((unsigned long) &__stop___ex_table);
+       unsigned long rodata_end = PAGE_ALIGN((unsigned long) &__end_rodata);
+       unsigned long data_start = (unsigned long) &_sdata;
 
        printk(KERN_INFO "Write protecting the kernel read-only data: %luk\n",
               (end - start) >> 10);
@@ -791,6 +787,14 @@ void mark_rodata_ro(void)
        printk(KERN_INFO "Testing CPA: again\n");
        set_memory_ro(start, (end-start) >> PAGE_SHIFT);
 #endif
+
+       free_init_pages("unused kernel memory",
+                       (unsigned long) page_address(virt_to_page(text_end)),
+                       (unsigned long)
+                                page_address(virt_to_page(rodata_start)));
+       free_init_pages("unused kernel memory",
+                       (unsigned long) page_address(virt_to_page(rodata_end)),
+                       (unsigned long) page_address(virt_to_page(data_start)));
 }
 
 #endif
@@ -830,7 +834,7 @@ int __init reserve_bootmem_generic(unsigned long phys, unsigned long len,
                return ret;
 
 #else
-       reserve_bootmem(phys, len, BOOTMEM_DEFAULT);
+       reserve_bootmem(phys, len, flags);
 #endif
 
        if (phys+len <= MAX_DMA_PFN*PAGE_SIZE) {
@@ -974,7 +978,7 @@ vmemmap_populate(struct page *start_page, unsigned long size, int node)
                        if (pmd_none(*pmd)) {
                                pte_t entry;
 
-                               p = vmemmap_alloc_block(PMD_SIZE, node);
+                               p = vmemmap_alloc_block_buf(PMD_SIZE, node);
                                if (!p)
                                        return -ENOMEM;