#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>
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;
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)
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);
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 */
/* 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;
}
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);
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);
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);
set_debug(0UL, 7);
fpu_init();
-
-#ifdef CONFIG_NUMA
- numa_add_cpu(cpu);
-#endif
}