Merge branch 'x86-mm-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
Linus Torvalds [Wed, 10 Jun 2009 23:13:20 +0000 (16:13 -0700)]
* 'x86-mm-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: (22 commits)
  x86: fix system without memory on node0
  x86, mm: Fix node_possible_map logic
  mm, x86: remove MEMORY_HOTPLUG_RESERVE related code
  x86: make sparse mem work in non-NUMA mode
  x86: process.c, remove useless headers
  x86: merge process.c a bit
  x86: use sparse_memory_present_with_active_regions() on UMA
  x86: unify 64-bit UMA and NUMA paging_init()
  x86: Allow 1MB of slack between the e820 map and SRAT, not 4GB
  x86: Sanity check the e820 against the SRAT table using e820 map only
  x86: clean up and and print out initial max_pfn_mapped
  x86/pci: remove rounding quirk from e820_setup_gap()
  x86, e820, pci: reserve extra free space near end of RAM
  x86: fix typo in address space documentation
  x86: 46 bit physical address support on 64 bits
  x86, mm: fault.c, use printk_once() in is_errata93()
  x86: move per-cpu mmu_gathers to mm/init.c
  x86: move max_pfn_mapped and max_low_pfn_mapped to setup.c
  x86: unify noexec handling
  x86: remove (null) in /sys kernel_page_tables
  ...

1  2 
arch/x86/include/asm/page_64_types.h
arch/x86/include/asm/traps.h
arch/x86/kernel/process.c
arch/x86/kernel/setup.c
arch/x86/kernel/setup_percpu.c
arch/x86/mm/init.c

   */
  #define __PAGE_OFFSET           _AC(0xffff880000000000, UL)
  
 -#define __PHYSICAL_START      CONFIG_PHYSICAL_START
 -#define __KERNEL_ALIGN                0x200000
 -
 -/*
 - * Make sure kernel is aligned to 2MB address. Catching it at compile
 - * time is better. Change your config file and compile the kernel
 - * for a 2MB aligned address (CONFIG_PHYSICAL_START)
 - */
 -#if (CONFIG_PHYSICAL_START % __KERNEL_ALIGN) != 0
 -#error "CONFIG_PHYSICAL_START must be a multiple of 2MB"
 -#endif
 +#define __PHYSICAL_START      ((CONFIG_PHYSICAL_START +               \
 +                                (CONFIG_PHYSICAL_ALIGN - 1)) &        \
 +                               ~(CONFIG_PHYSICAL_ALIGN - 1))
  
  #define __START_KERNEL                (__START_KERNEL_map + __PHYSICAL_START)
  #define __START_KERNEL_map    _AC(0xffffffff80000000, UL)
  
- /* See Documentation/x86_64/mm.txt for a description of the memory map. */
+ /* See Documentation/x86/x86_64/mm.txt for a description of the memory map. */
  #define __PHYSICAL_MASK_SHIFT 46
  #define __VIRTUAL_MASK_SHIFT  48
  
@@@ -63,12 -71,6 +63,6 @@@ extern unsigned long __phys_addr(unsign
  
  #define vmemmap ((struct page *)VMEMMAP_START)
  
- extern unsigned long init_memory_mapping(unsigned long start,
-                                        unsigned long end);
- extern void initmem_init(unsigned long start_pfn, unsigned long end_pfn);
- extern void free_initmem(void);
  extern void init_extra_mapping_uc(unsigned long phys, unsigned long size);
  extern void init_extra_mapping_wb(unsigned long phys, unsigned long size);
  
@@@ -2,6 -2,7 +2,7 @@@
  #define _ASM_X86_TRAPS_H
  
  #include <asm/debugreg.h>
+ #include <asm/siginfo.h>                      /* TRAP_TRACE, ... */
  
  #ifdef CONFIG_X86_32
  #define dotraplinkage
@@@ -74,6 -75,7 +75,6 @@@ static inline int get_si_code(unsigned 
  }
  
  extern int panic_on_unrecovered_nmi;
 -extern int kstack_depth_to_print;
  
  void math_error(void __user *);
  void math_emulate(struct math_emu_info *);
@@@ -8,10 -8,10 +8,11 @@@
  #include <linux/module.h>
  #include <linux/pm.h>
  #include <linux/clockchips.h>
+ #include <linux/random.h>
  #include <trace/power.h>
  #include <asm/system.h>
  #include <asm/apic.h>
 +#include <asm/syscalls.h>
  #include <asm/idle.h>
  #include <asm/uaccess.h>
  #include <asm/i387.h>
@@@ -614,3 -614,16 +615,16 @@@ static int __init idle_setup(char *str
  }
  early_param("idle", idle_setup);
  
+ unsigned long arch_align_stack(unsigned long sp)
+ {
+       if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
+               sp -= get_random_int() % 8192;
+       return sp & ~0xf;
+ }
+ unsigned long arch_randomize_brk(struct mm_struct *mm)
+ {
+       unsigned long range_end = mm->brk + 0x02000000;
+       return randomize_range(mm->brk, range_end, 0) ? : mm->brk;
+ }
diff --combined arch/x86/kernel/setup.c
  #define ARCH_SETUP
  #endif
  
+ /*
+  * 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;
  RESERVE_BRK(dmi_alloc, 65536);
  
  unsigned int boot_cpu_id __read_mostly;
@@@ -214,8 -222,8 +222,8 @@@ unsigned long mmu_cr4_features
  unsigned long mmu_cr4_features = X86_CR4_PAE;
  #endif
  
 -/* Boot loader ID as an integer, for the benefit of proc_dointvec */
 -int bootloader_type;
 +/* Boot loader ID and version as integers, for the benefit of proc_dointvec */
 +int bootloader_type, bootloader_version;
  
  /*
   * Setup options
@@@ -706,12 -714,6 +714,12 @@@ void __init setup_arch(char **cmdline_p
  #endif
        saved_video_mode = boot_params.hdr.vid_mode;
        bootloader_type = boot_params.hdr.type_of_loader;
 +      if ((bootloader_type >> 4) == 0xe) {
 +              bootloader_type &= 0xf;
 +              bootloader_type |= (boot_params.hdr.ext_loader_type+0x10) << 4;
 +      }
 +      bootloader_version  = bootloader_type & 0xf;
 +      bootloader_version |= boot_params.hdr.ext_loader_ver << 4;
  
  #ifdef CONFIG_BLK_DEV_RAM
        rd_image_start = boot_params.hdr.ram_size & RAMDISK_IMAGE_START_MASK;
                max_low_pfn = max_pfn;
  
        high_memory = (void *)__va(max_pfn * PAGE_SIZE - 1) + 1;
+       max_pfn_mapped = KERNEL_IMAGE_SIZE >> PAGE_SHIFT;
  #endif
  
  #ifdef CONFIG_X86_CHECK_BIOS_CORRUPTION
        setup_bios_corruption_check();
  #endif
  
+       printk(KERN_DEBUG "initial memory mapped : 0 - %08lx\n",
+                       max_pfn_mapped<<PAGE_SHIFT);
        reserve_brk();
  
        /* max_pfn_mapped is updated here */
  #ifdef CONFIG_X86_32
  
  /**
 - * x86_quirk_pre_intr_init - initialisation prior to setting up interrupt vectors
 - *
 - * Description:
 - *    Perform any necessary interrupt initialisation prior to setting up
 - *    the "ordinary" interrupt call gates.  For legacy reasons, the ISA
 - *    interrupts should be initialised here if the machine emulates a PC
 - *    in any way.
 - **/
 -void __init x86_quirk_pre_intr_init(void)
 -{
 -      if (x86_quirks->arch_pre_intr_init) {
 -              if (x86_quirks->arch_pre_intr_init())
 -                      return;
 -      }
 -      init_ISA_irqs();
 -}
 -
 -/**
   * x86_quirk_intr_init - post gate setup interrupt initialisation
   *
   * Description:
@@@ -160,10 -160,8 +160,10 @@@ static ssize_t __init setup_pcpu_remap(
        /*
         * If large page isn't supported, there's no benefit in doing
         * this.  Also, on non-NUMA, embedding is better.
 +       *
 +       * NOTE: disabled for now.
         */
 -      if (!cpu_has_pse || !pcpu_need_numa())
 +      if (true || !cpu_has_pse || !pcpu_need_numa())
                return -EINVAL;
  
        /*
@@@ -425,6 -423,14 +425,14 @@@ void __init setup_per_cpu_areas(void
        early_per_cpu_ptr(x86_cpu_to_node_map) = NULL;
  #endif
  
+ #if defined(CONFIG_X86_64) && defined(CONFIG_NUMA)
+       /*
+        * make sure boot cpu node_number is right, when boot cpu is on the
+        * node that doesn't have mem installed
+        */
+       per_cpu(node_number, boot_cpu_id) = cpu_to_node(boot_cpu_id);
+ #endif
        /* Setup node to cpumask map */
        setup_node_to_cpumask_map();
  
diff --combined arch/x86/mm/init.c
@@@ -1,4 -1,3 +1,4 @@@
 +#include <linux/initrd.h>
  #include <linux/ioport.h>
  #include <linux/swap.h>
  
@@@ -11,6 -10,9 +11,9 @@@
  #include <asm/setup.h>
  #include <asm/system.h>
  #include <asm/tlbflush.h>
+ #include <asm/tlb.h>
+ DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
  
  unsigned long __initdata e820_table_start;
  unsigned long __meminitdata e820_table_end;
@@@ -24,6 -26,69 +27,69 @@@ int direct_gbpage
  #endif
  ;
  
+ int nx_enabled;
+ #if defined(CONFIG_X86_64) || defined(CONFIG_X86_PAE)
+ static int disable_nx __cpuinitdata;
+ /*
+  * noexec = on|off
+  *
+  * Control non-executable mappings for processes.
+  *
+  * on      Enable
+  * off     Disable
+  */
+ static int __init noexec_setup(char *str)
+ {
+       if (!str)
+               return -EINVAL;
+       if (!strncmp(str, "on", 2)) {
+               __supported_pte_mask |= _PAGE_NX;
+               disable_nx = 0;
+       } else if (!strncmp(str, "off", 3)) {
+               disable_nx = 1;
+               __supported_pte_mask &= ~_PAGE_NX;
+       }
+       return 0;
+ }
+ early_param("noexec", noexec_setup);
+ #endif
+ #ifdef CONFIG_X86_PAE
+ static void __init set_nx(void)
+ {
+       unsigned int v[4], l, h;
+       if (cpu_has_pae && (cpuid_eax(0x80000000) > 0x80000001)) {
+               cpuid(0x80000001, &v[0], &v[1], &v[2], &v[3]);
+               if ((v[3] & (1 << 20)) && !disable_nx) {
+                       rdmsr(MSR_EFER, l, h);
+                       l |= EFER_NX;
+                       wrmsr(MSR_EFER, l, h);
+                       nx_enabled = 1;
+                       __supported_pte_mask |= _PAGE_NX;
+               }
+       }
+ }
+ #else
+ static inline void set_nx(void)
+ {
+ }
+ #endif
+ #ifdef CONFIG_X86_64
+ void __cpuinit check_efer(void)
+ {
+       unsigned long efer;
+       rdmsrl(MSR_EFER, efer);
+       if (!(efer & EFER_NX) || disable_nx)
+               __supported_pte_mask &= ~_PAGE_NX;
+ }
+ #endif
  static void __init find_early_table_space(unsigned long end, int use_pse,
                                          int use_gbpages)
  {
         */
  #ifdef CONFIG_X86_32
        start = 0x7000;
-       e820_table_start = find_e820_area(start, max_pfn_mapped<<PAGE_SHIFT,
-                                       tables, PAGE_SIZE);
- #else /* CONFIG_X86_64 */
+ #else
        start = 0x8000;
-       e820_table_start = find_e820_area(start, end, tables, PAGE_SIZE);
  #endif
+       e820_table_start = find_e820_area(start, max_pfn_mapped<<PAGE_SHIFT,
+                                       tables, PAGE_SIZE);
        if (e820_table_start == -1UL)
                panic("Cannot find space for the kernel page tables");
  
@@@ -160,12 -224,9 +225,9 @@@ unsigned long __init_refok init_memory_
        use_gbpages = direct_gbpages;
  #endif
  
        set_nx();
        if (nx_enabled)
                printk(KERN_INFO "NX (Execute Disable) protection: active\n");
- #endif
  
        /* Enable PSE if available */
        if (cpu_has_pse)
                set_in_cr4(X86_CR4_PGE);
                __supported_pte_mask |= _PAGE_GLOBAL;
        }
- #endif
  
        if (use_gbpages)
                page_size_mask |= 1 << PG_LEVEL_1G;