aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/smpboot.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/kernel/smpboot.c')
-rw-r--r--arch/x86/kernel/smpboot.c29
1 files changed, 21 insertions, 8 deletions
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
index 6b087ab6cd8f..56078d61c793 100644
--- a/arch/x86/kernel/smpboot.c
+++ b/arch/x86/kernel/smpboot.c
@@ -86,6 +86,7 @@ void *x86_bios_cpu_apicid_early_ptr;
86 86
87#ifdef CONFIG_X86_32 87#ifdef CONFIG_X86_32
88u8 apicid_2_node[MAX_APICID]; 88u8 apicid_2_node[MAX_APICID];
89static int low_mappings;
89#endif 90#endif
90 91
91/* State of each CPU */ 92/* State of each CPU */
@@ -326,6 +327,12 @@ static void __cpuinit start_secondary(void *unused)
326 enable_8259A_irq(0); 327 enable_8259A_irq(0);
327 } 328 }
328 329
330#ifdef CONFIG_X86_32
331 while (low_mappings)
332 cpu_relax();
333 __flush_tlb_all();
334#endif
335
329 /* This must be done before setting cpu_online_map */ 336 /* This must be done before setting cpu_online_map */
330 set_cpu_sibling_map(raw_smp_processor_id()); 337 set_cpu_sibling_map(raw_smp_processor_id());
331 wmb(); 338 wmb();
@@ -1040,14 +1047,20 @@ int __cpuinit native_cpu_up(unsigned int cpu)
1040#ifdef CONFIG_X86_32 1047#ifdef CONFIG_X86_32
1041 /* init low mem mapping */ 1048 /* init low mem mapping */
1042 clone_pgd_range(swapper_pg_dir, swapper_pg_dir + KERNEL_PGD_BOUNDARY, 1049 clone_pgd_range(swapper_pg_dir, swapper_pg_dir + KERNEL_PGD_BOUNDARY,
1043 min_t(unsigned long, KERNEL_PGD_PTRS, KERNEL_PGD_BOUNDARY)); 1050 min_t(unsigned long, KERNEL_PGD_PTRS, KERNEL_PGD_BOUNDARY));
1044 flush_tlb_all(); 1051 flush_tlb_all();
1045#endif 1052 low_mappings = 1;
1053
1054 err = do_boot_cpu(apicid, cpu);
1046 1055
1056 zap_low_mappings();
1057 low_mappings = 0;
1058#else
1047 err = do_boot_cpu(apicid, cpu); 1059 err = do_boot_cpu(apicid, cpu);
1048 if (err < 0) { 1060#endif
1061 if (err) {
1049 Dprintk("do_boot_cpu failed %d\n", err); 1062 Dprintk("do_boot_cpu failed %d\n", err);
1050 return err; 1063 return -EIO;
1051 } 1064 }
1052 1065
1053 /* 1066 /*
@@ -1177,6 +1190,7 @@ static void __init smp_cpu_index_default(void)
1177 */ 1190 */
1178void __init native_smp_prepare_cpus(unsigned int max_cpus) 1191void __init native_smp_prepare_cpus(unsigned int max_cpus)
1179{ 1192{
1193 preempt_disable();
1180 nmi_watchdog_default(); 1194 nmi_watchdog_default();
1181 smp_cpu_index_default(); 1195 smp_cpu_index_default();
1182 current_cpu_data = boot_cpu_data; 1196 current_cpu_data = boot_cpu_data;
@@ -1193,7 +1207,7 @@ void __init native_smp_prepare_cpus(unsigned int max_cpus)
1193 if (smp_sanity_check(max_cpus) < 0) { 1207 if (smp_sanity_check(max_cpus) < 0) {
1194 printk(KERN_INFO "SMP disabled\n"); 1208 printk(KERN_INFO "SMP disabled\n");
1195 disable_smp(); 1209 disable_smp();
1196 return; 1210 goto out;
1197 } 1211 }
1198 1212
1199 preempt_disable(); 1213 preempt_disable();
@@ -1233,6 +1247,8 @@ void __init native_smp_prepare_cpus(unsigned int max_cpus)
1233 printk(KERN_INFO "CPU%d: ", 0); 1247 printk(KERN_INFO "CPU%d: ", 0);
1234 print_cpu_info(&cpu_data(0)); 1248 print_cpu_info(&cpu_data(0));
1235 setup_boot_clock(); 1249 setup_boot_clock();
1250out:
1251 preempt_enable();
1236} 1252}
1237/* 1253/*
1238 * Early setup to make printk work. 1254 * Early setup to make printk work.
@@ -1259,9 +1275,6 @@ void __init native_smp_cpus_done(unsigned int max_cpus)
1259 setup_ioapic_dest(); 1275 setup_ioapic_dest();
1260#endif 1276#endif
1261 check_nmi_watchdog(); 1277 check_nmi_watchdog();
1262#ifdef CONFIG_X86_32
1263 zap_low_mappings();
1264#endif
1265} 1278}
1266 1279
1267#ifdef CONFIG_HOTPLUG_CPU 1280#ifdef CONFIG_HOTPLUG_CPU