]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - arch/x86/kernel/smpboot.c
Merge branches 'x86/numa-fixes', 'x86/apic', 'x86/apm', 'x86/bitops', 'x86/build...
[linux-2.6-omap-h63xx.git] / arch / x86 / kernel / smpboot.c
index 6b087ab6cd8f3e3ea6c35c4bbe73ae85ae0d0686..f2b666756299cffa0b6bebd64968209ea41433c3 100644 (file)
@@ -59,7 +59,6 @@
 #include <asm/pgtable.h>
 #include <asm/tlbflush.h>
 #include <asm/mtrr.h>
-#include <asm/nmi.h>
 #include <asm/vmi.h>
 #include <asm/genapic.h>
 #include <linux/mc146818rtc.h>
@@ -86,6 +85,7 @@ void *x86_bios_cpu_apicid_early_ptr;
 
 #ifdef CONFIG_X86_32
 u8 apicid_2_node[MAX_APICID];
+static int low_mappings;
 #endif
 
 /* State of each CPU */
@@ -326,6 +326,12 @@ static void __cpuinit start_secondary(void *unused)
                enable_8259A_irq(0);
        }
 
+#ifdef CONFIG_X86_32
+       while (low_mappings)
+               cpu_relax();
+       __flush_tlb_all();
+#endif
+
        /* This must be done before setting cpu_online_map */
        set_cpu_sibling_map(raw_smp_processor_id());
        wmb();
@@ -989,7 +995,6 @@ do_rest:
 #endif
                cpu_clear(cpu, cpu_callout_map); /* was set by do_boot_cpu() */
                cpu_clear(cpu, cpu_initialized); /* was set by cpu_init() */
-               cpu_clear(cpu, cpu_possible_map);
                cpu_clear(cpu, cpu_present_map);
                per_cpu(x86_cpu_to_apicid, cpu) = BAD_APICID;
        }
@@ -1040,14 +1045,20 @@ int __cpuinit native_cpu_up(unsigned int cpu)
 #ifdef CONFIG_X86_32
        /* init low mem mapping */
        clone_pgd_range(swapper_pg_dir, swapper_pg_dir + KERNEL_PGD_BOUNDARY,
-                       min_t(unsigned long, KERNEL_PGD_PTRS, KERNEL_PGD_BOUNDARY));
+               min_t(unsigned long, KERNEL_PGD_PTRS, KERNEL_PGD_BOUNDARY));
        flush_tlb_all();
-#endif
+       low_mappings = 1;
+
+       err = do_boot_cpu(apicid, cpu);
 
+       zap_low_mappings();
+       low_mappings = 0;
+#else
        err = do_boot_cpu(apicid, cpu);
-       if (err < 0) {
+#endif
+       if (err) {
                Dprintk("do_boot_cpu failed %d\n", err);
-               return err;
+               return -EIO;
        }
 
        /*
@@ -1145,9 +1156,11 @@ static int __init smp_sanity_check(unsigned max_cpus)
         * If SMP should be disabled, then really disable it!
         */
        if (!max_cpus) {
-               printk(KERN_INFO "SMP mode deactivated,"
-                                "forcing use of dummy APIC emulation.\n");
+               printk(KERN_INFO "SMP mode deactivated.\n");
                smpboot_clear_io_apic();
+
+               localise_nmi_watchdog();
+
 #ifdef CONFIG_X86_32
                connect_bsp_APIC();
 #endif
@@ -1177,6 +1190,7 @@ static void __init smp_cpu_index_default(void)
  */
 void __init native_smp_prepare_cpus(unsigned int max_cpus)
 {
+       preempt_disable();
        nmi_watchdog_default();
        smp_cpu_index_default();
        current_cpu_data = boot_cpu_data;
@@ -1193,7 +1207,7 @@ void __init native_smp_prepare_cpus(unsigned int max_cpus)
        if (smp_sanity_check(max_cpus) < 0) {
                printk(KERN_INFO "SMP disabled\n");
                disable_smp();
-               return;
+               goto out;
        }
 
        preempt_disable();
@@ -1233,6 +1247,8 @@ void __init native_smp_prepare_cpus(unsigned int max_cpus)
        printk(KERN_INFO "CPU%d: ", 0);
        print_cpu_info(&cpu_data(0));
        setup_boot_clock();
+out:
+       preempt_enable();
 }
 /*
  * Early setup to make printk work.
@@ -1259,9 +1275,6 @@ void __init native_smp_cpus_done(unsigned int max_cpus)
        setup_ioapic_dest();
 #endif
        check_nmi_watchdog();
-#ifdef CONFIG_X86_32
-       zap_low_mappings();
-#endif
 }
 
 #ifdef CONFIG_HOTPLUG_CPU