vserver 1.9.5.x5
[linux-2.6.git] / arch / x86_64 / kernel / setup64.c
index b83680a..b5305b0 100644 (file)
 #include <linux/sched.h>
 #include <linux/string.h>
 #include <linux/bootmem.h>
+#include <linux/bitops.h>
 #include <asm/pda.h>
 #include <asm/pgtable.h>
 #include <asm/processor.h>
 #include <asm/desc.h>
-#include <asm/bitops.h>
 #include <asm/atomic.h>
 #include <asm/mmu_context.h>
 #include <asm/smp.h>
@@ -28,7 +28,7 @@
 
 char x86_boot_params[2048] __initdata = {0,};
 
-unsigned long cpu_initialized __initdata = 0;
+cpumask_t cpu_initialized __initdata = CPU_MASK_NONE;
 
 struct x8664_pda cpu_pda[NR_CPUS] __cacheline_aligned; 
 
@@ -43,83 +43,48 @@ char boot_cpu_stack[IRQSTACKSIZE] __attribute__((section(".bss.page_aligned")));
 
 unsigned long __supported_pte_mask = ~0UL;
 static int do_not_nx __initdata = 0;
-unsigned long vm_stack_flags = __VM_STACK_FLAGS; 
-unsigned long vm_stack_flags32 = __VM_STACK_FLAGS; 
-unsigned long vm_data_default_flags = __VM_DATA_DEFAULT_FLAGS; 
-unsigned long vm_data_default_flags32 = __VM_DATA_DEFAULT_FLAGS; 
-unsigned long vm_force_exec32 = PROT_EXEC; 
 
 /* noexec=on|off
 Control non executable mappings for 64bit processes.
 
-on     Enable
+on     Enable(default)
 off    Disable
-noforce (default) Don't enable by default for heap/stack/data, 
-       but allow PROT_EXEC to be effective
-
 */ 
-static int __init nonx_setup(char *str)
+int __init nonx_setup(char *str)
 {
-       if (!strcmp(str, "on")) {
+       if (!strncmp(str, "on", 2)) {
                 __supported_pte_mask |= _PAGE_NX; 
                do_not_nx = 0; 
-               vm_data_default_flags &= ~VM_EXEC; 
-               vm_stack_flags &= ~VM_EXEC;  
-       } else if (!strcmp(str, "noforce") || !strcmp(str, "off")) {
-               do_not_nx = (str[0] == 'o');
-               if (do_not_nx)
-                       __supported_pte_mask &= ~_PAGE_NX; 
-               vm_data_default_flags |= VM_EXEC; 
-               vm_stack_flags |= VM_EXEC;
-        } 
-        return 1;
+       } else if (!strncmp(str, "off", 3)) {
+               do_not_nx = 1;
+               __supported_pte_mask &= ~_PAGE_NX;
+        }
+       return 0;
 } 
+__setup("noexec=", nonx_setup);        /* parsed early actually */
 
-__setup("noexec=", nonx_setup); 
-
-/* noexec32=opt{,opt} 
-
-Control the no exec default for 32bit processes. Can be also overwritten
-per executable using ELF header flags (e.g. needed for the X server)
-Requires noexec=on or noexec=noforce to be effective.
+int force_personality32 = READ_IMPLIES_EXEC;
 
-Valid options: 
-   all,on    Heap,stack,data is non executable.        
-   off       (default) Heap,stack,data is executable
-   stack     Stack is non executable, heap/data is.
-   force     Don't imply PROT_EXEC for PROT_READ 
-   compat    (default) Imply PROT_EXEC for PROT_READ
+/* noexec32=on|off
+Control non executable heap for 32bit processes.
+To control the stack too use noexec=off
 
+on     PROT_READ does not imply PROT_EXEC for 32bit processes
+off    PROT_READ implies PROT_EXEC (default)
 */
- static int __init nonx32_setup(char *s)
- {
-        while (*s) {
-               if (!strncmp(s, "all", 3) || !strncmp(s,"on",2)) {
-                       vm_data_default_flags32 &= ~VM_EXEC; 
-                       vm_stack_flags32 &= ~VM_EXEC;  
-               } else if (!strncmp(s, "off",3)) {
-                       vm_data_default_flags32 |= VM_EXEC; 
-                       vm_stack_flags32 |= VM_EXEC;  
-               } else if (!strncmp(s, "stack", 5)) {
-                       vm_data_default_flags32 |= VM_EXEC; 
-                       vm_stack_flags32 &= ~VM_EXEC;           
-               } else if (!strncmp(s, "force",5)) {
-                       vm_force_exec32 = 0; 
-               } else if (!strncmp(s, "compat",5)) {
-                       vm_force_exec32 = PROT_EXEC;
-               } 
-               s += strcspn(s, ",");
-               if (*s == ',')
-                       ++s;
-        }
-        return 1;
-} 
-
-__setup("noexec32=", nonx32_setup); 
+static int __init nonx32_setup(char *str)
+{
+       if (!strcmp(str, "on"))
+               force_personality32 &= ~READ_IMPLIES_EXEC;
+       else if (!strcmp(str, "off"))
+               force_personality32 |= READ_IMPLIES_EXEC;
+       return 0;
+}
+__setup("noexec32=", nonx32_setup);
 
 /*
  * Great future plan:
- * Declare PDA itself and support (irqstack,tss,pml4) as per cpu data.
+ * Declare PDA itself and support (irqstack,tss,pgd) as per cpu data.
  * Always point %gs to its beginning
  */
 void __init setup_per_cpu_areas(void)
@@ -136,13 +101,13 @@ void __init setup_per_cpu_areas(void)
 
        for (i = 0; i < NR_CPUS; i++) { 
                unsigned char *ptr;
-               /* If possible allocate on the node of the CPU.
-                  In case it doesn't exist round-robin nodes. */
-               if (!NODE_DATA(i % numnodes)) { 
-                       printk("cpu with no node %d, numnodes %d\n", i, numnodes);
+
+               if (!NODE_DATA(cpu_to_node(i))) {
+                       printk("cpu with no node %d, num_online_nodes %d\n",
+                              i, num_online_nodes());
                        ptr = alloc_bootmem(size);
                } else { 
-                       ptr = alloc_bootmem_node(NODE_DATA(i % numnodes), size);
+                       ptr = alloc_bootmem_node(NODE_DATA(cpu_to_node(i)), size);
                }
                if (!ptr)
                        panic("Cannot allocate cpu data for CPU %d\n", i);
@@ -153,7 +118,6 @@ void __init setup_per_cpu_areas(void)
 
 void pda_init(int cpu)
 { 
-        pml4_t *level4;
        struct x8664_pda *pda = &cpu_pda[cpu];
 
        /* Setup up data that may be needed in __get_free_pages early */
@@ -172,22 +136,14 @@ void pda_init(int cpu)
                /* others are initialized in smpboot.c */
                pda->pcurrent = &init_task;
                pda->irqstackptr = boot_cpu_stack; 
-               level4 = init_level4_pgt; 
        } else {
-               level4 = (pml4_t *)__get_free_pages(GFP_ATOMIC, 0); 
-               if (!level4) 
-                       panic("Cannot allocate top level page for cpu %d", cpu); 
                pda->irqstackptr = (char *)
                        __get_free_pages(GFP_ATOMIC, IRQSTACK_ORDER);
                if (!pda->irqstackptr)
                        panic("cannot allocate irqstack for cpu %d", cpu); 
        }
 
-       pda->level4_pgt = (unsigned long *)level4; 
-       if (level4 != init_level4_pgt)
-               memcpy(level4, &init_level4_pgt, PAGE_SIZE); 
-       set_pml4(level4 + 510, mk_kernel_pml4(__pa_symbol(boot_vmalloc_pgt)));
-       asm volatile("movq %0,%%cr3" :: "r" (__pa(level4))); 
+       asm volatile("movq %0,%%cr3" :: "r" (__pa_symbol(&init_level4_pgt)));
 
        pda->irqstackptr += IRQSTACKSIZE-64;
 } 
@@ -252,7 +208,7 @@ void __init cpu_init (void)
 
        me = current;
 
-       if (test_and_set_bit(cpu, &cpu_initialized))
+       if (cpu_test_and_set(cpu, cpu_initialized))
                panic("CPU#%d already initialized!\n", cpu);
 
        printk("Initializing CPU#%d\n", cpu);
@@ -269,8 +225,8 @@ void __init cpu_init (void)
 
        cpu_gdt_descr[cpu].size = GDT_SIZE;
        cpu_gdt_descr[cpu].address = (unsigned long)cpu_gdt_table[cpu];
-       __asm__ __volatile__("lgdt %0": "=m" (cpu_gdt_descr[cpu]));
-       __asm__ __volatile__("lidt %0": "=m" (idt_descr));
+       asm volatile("lgdt %0" :: "m" (cpu_gdt_descr[cpu]));
+       asm volatile("lidt %0" :: "m" (idt_descr));
 
        memcpy(me->thread.tls_array, cpu_gdt_table[cpu], GDT_ENTRY_TLS_ENTRIES * 8);
 
@@ -280,9 +236,6 @@ void __init cpu_init (void)
 
        asm volatile("pushfq ; popq %%rax ; btr $14,%%rax ; pushq %%rax ; popfq" ::: "eax");
 
-       if (cpu == 0) 
-               early_identify_cpu(&boot_cpu_data);
-
        syscall_init();
 
        wrmsrl(MSR_FS_BASE, 0);
@@ -336,8 +289,4 @@ void __init cpu_init (void)
        set_debug(0UL, 7);
 
        fpu_init(); 
-
-#ifdef CONFIG_NUMA
-       numa_add_cpu(cpu);
-#endif
 }