Merge branch 'akpm' (patches from Andrew Morton)
[sfrench/cifs-2.6.git] / arch / x86 / kernel / cpu / common.c
index c649f236e288849f94f8b2bf4501117cd2f1a698..3eff36f719fb62dbb78ef64f37421b73a90c95ac 100644 (file)
@@ -964,6 +964,7 @@ static void vgetcpu_set_mode(void)
                vgetcpu_mode = VGETCPU_LSL;
 }
 
+#ifdef CONFIG_IA32_EMULATION
 /* May not be __init: called during resume */
 static void syscall32_cpu_init(void)
 {
@@ -975,7 +976,8 @@ static void syscall32_cpu_init(void)
 
        wrmsrl(MSR_CSTAR, ia32_cstar_target);
 }
-#endif
+#endif         /* CONFIG_IA32_EMULATION */
+#endif         /* CONFIG_X86_64 */
 
 #ifdef CONFIG_X86_32
 void enable_sep_cpu(void)
@@ -1184,7 +1186,7 @@ void syscall_init(void)
        /* Flags to clear on syscall */
        wrmsrl(MSR_SYSCALL_MASK,
               X86_EFLAGS_TF|X86_EFLAGS_DF|X86_EFLAGS_IF|
-              X86_EFLAGS_IOPL|X86_EFLAGS_AC);
+              X86_EFLAGS_IOPL|X86_EFLAGS_AC|X86_EFLAGS_NT);
 }
 
 /*
@@ -1266,6 +1268,19 @@ static void dbg_restore_debug_regs(void)
 #define dbg_restore_debug_regs()
 #endif /* ! CONFIG_KGDB */
 
+static void wait_for_master_cpu(int cpu)
+{
+#ifdef CONFIG_SMP
+       /*
+        * wait for ACK from master CPU before continuing
+        * with AP initialization
+        */
+       WARN_ON(cpumask_test_and_set_cpu(cpu, cpu_initialized_mask));
+       while (!cpumask_test_cpu(cpu, cpu_callout_mask))
+               cpu_relax();
+#endif
+}
+
 /*
  * cpu_init() initializes state that is per-CPU. Some data is already
  * initialized (naturally) in the bootstrap process, such as the GDT
@@ -1281,16 +1296,17 @@ void cpu_init(void)
        struct task_struct *me;
        struct tss_struct *t;
        unsigned long v;
-       int cpu;
+       int cpu = stack_smp_processor_id();
        int i;
 
+       wait_for_master_cpu(cpu);
+
        /*
         * Load microcode on this cpu if a valid microcode is available.
         * This is early microcode loading procedure.
         */
        load_ucode_ap();
 
-       cpu = stack_smp_processor_id();
        t = &per_cpu(init_tss, cpu);
        oist = &per_cpu(orig_ist, cpu);
 
@@ -1302,9 +1318,6 @@ void cpu_init(void)
 
        me = current;
 
-       if (cpumask_test_and_set_cpu(cpu, cpu_initialized_mask))
-               panic("CPU#%d already initialized!\n", cpu);
-
        pr_debug("Initializing CPU#%d\n", cpu);
 
        clear_in_cr4(X86_CR4_VME|X86_CR4_PVI|X86_CR4_TSD|X86_CR4_DE);
@@ -1381,17 +1394,13 @@ void cpu_init(void)
        struct tss_struct *t = &per_cpu(init_tss, cpu);
        struct thread_struct *thread = &curr->thread;
 
-       show_ucode_info_early();
+       wait_for_master_cpu(cpu);
 
-       if (cpumask_test_and_set_cpu(cpu, cpu_initialized_mask)) {
-               printk(KERN_WARNING "CPU#%d already initialized!\n", cpu);
-               for (;;)
-                       local_irq_enable();
-       }
+       show_ucode_info_early();
 
        printk(KERN_INFO "Initializing CPU#%d\n", cpu);
 
-       if (cpu_has_vme || cpu_has_tsc || cpu_has_de)
+       if (cpu_feature_enabled(X86_FEATURE_VME) || cpu_has_tsc || cpu_has_de)
                clear_in_cr4(X86_CR4_VME|X86_CR4_PVI|X86_CR4_TSD|X86_CR4_DE);
 
        load_current_idt();