aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/smpboot.c
diff options
context:
space:
mode:
authorDavid Woodhouse <David.Woodhouse@intel.com>2008-07-11 09:36:25 -0400
committerDavid Woodhouse <David.Woodhouse@intel.com>2008-07-11 09:36:25 -0400
commita8931ef380c92d121ae74ecfb03b2d63f72eea6f (patch)
tree980fb6b019e11e6cb1ece55b7faff184721a8053 /arch/x86/kernel/smpboot.c
parent90574d0a4d4b73308ae54a2a57a4f3f1fa98e984 (diff)
parente5a5816f7875207cb0a0a7032e39a4686c5e10a4 (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
Diffstat (limited to 'arch/x86/kernel/smpboot.c')
-rw-r--r--arch/x86/kernel/smpboot.c34
1 files changed, 23 insertions, 11 deletions
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
index 84241a256dc8..3e1cecedde42 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 */
@@ -299,7 +300,7 @@ static void __cpuinit smp_callin(void)
299/* 300/*
300 * Activate a secondary processor. 301 * Activate a secondary processor.
301 */ 302 */
302void __cpuinit start_secondary(void *unused) 303static void __cpuinit start_secondary(void *unused)
303{ 304{
304 /* 305 /*
305 * Don't put *anything* before cpu_init(), SMP booting is too 306 * Don't put *anything* before cpu_init(), SMP booting is too
@@ -326,6 +327,12 @@ 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();
@@ -989,7 +996,6 @@ do_rest:
989#endif 996#endif
990 cpu_clear(cpu, cpu_callout_map); /* was set by do_boot_cpu() */ 997 cpu_clear(cpu, cpu_callout_map); /* was set by do_boot_cpu() */
991 cpu_clear(cpu, cpu_initialized); /* was set by cpu_init() */ 998 cpu_clear(cpu, cpu_initialized); /* was set by cpu_init() */
992 cpu_clear(cpu, cpu_possible_map);
993 cpu_clear(cpu, cpu_present_map); 999 cpu_clear(cpu, cpu_present_map);
994 per_cpu(x86_cpu_to_apicid, cpu) = BAD_APICID; 1000 per_cpu(x86_cpu_to_apicid, cpu) = BAD_APICID;
995 } 1001 }
@@ -1040,14 +1046,20 @@ int __cpuinit native_cpu_up(unsigned int cpu)
1040#ifdef CONFIG_X86_32 1046#ifdef CONFIG_X86_32
1041 /* init low mem mapping */ 1047 /* init low mem mapping */
1042 clone_pgd_range(swapper_pg_dir, swapper_pg_dir + KERNEL_PGD_BOUNDARY, 1048 clone_pgd_range(swapper_pg_dir, swapper_pg_dir + KERNEL_PGD_BOUNDARY,
1043 min_t(unsigned long, KERNEL_PGD_PTRS, KERNEL_PGD_BOUNDARY)); 1049 min_t(unsigned long, KERNEL_PGD_PTRS, KERNEL_PGD_BOUNDARY));
1044 flush_tlb_all(); 1050 flush_tlb_all();
1045#endif 1051 low_mappings = 1;
1052
1053 err = do_boot_cpu(apicid, cpu);
1046 1054
1055 zap_low_mappings();
1056 low_mappings = 0;
1057#else
1047 err = do_boot_cpu(apicid, cpu); 1058 err = do_boot_cpu(apicid, cpu);
1048 if (err < 0) { 1059#endif
1060 if (err) {
1049 Dprintk("do_boot_cpu failed %d\n", err); 1061 Dprintk("do_boot_cpu failed %d\n", err);
1050 return err; 1062 return -EIO;
1051 } 1063 }
1052 1064
1053 /* 1065 /*
@@ -1177,6 +1189,7 @@ static void __init smp_cpu_index_default(void)
1177 */ 1189 */
1178void __init native_smp_prepare_cpus(unsigned int max_cpus) 1190void __init native_smp_prepare_cpus(unsigned int max_cpus)
1179{ 1191{
1192 preempt_disable();
1180 nmi_watchdog_default(); 1193 nmi_watchdog_default();
1181 smp_cpu_index_default(); 1194 smp_cpu_index_default();
1182 current_cpu_data = boot_cpu_data; 1195 current_cpu_data = boot_cpu_data;
@@ -1193,7 +1206,7 @@ void __init native_smp_prepare_cpus(unsigned int max_cpus)
1193 if (smp_sanity_check(max_cpus) < 0) { 1206 if (smp_sanity_check(max_cpus) < 0) {
1194 printk(KERN_INFO "SMP disabled\n"); 1207 printk(KERN_INFO "SMP disabled\n");
1195 disable_smp(); 1208 disable_smp();
1196 return; 1209 goto out;
1197 } 1210 }
1198 1211
1199 preempt_disable(); 1212 preempt_disable();
@@ -1233,6 +1246,8 @@ void __init native_smp_prepare_cpus(unsigned int max_cpus)
1233 printk(KERN_INFO "CPU%d: ", 0); 1246 printk(KERN_INFO "CPU%d: ", 0);
1234 print_cpu_info(&cpu_data(0)); 1247 print_cpu_info(&cpu_data(0));
1235 setup_boot_clock(); 1248 setup_boot_clock();
1249out:
1250 preempt_enable();
1236} 1251}
1237/* 1252/*
1238 * Early setup to make printk work. 1253 * Early setup to make printk work.
@@ -1259,9 +1274,6 @@ void __init native_smp_cpus_done(unsigned int max_cpus)
1259 setup_ioapic_dest(); 1274 setup_ioapic_dest();
1260#endif 1275#endif
1261 check_nmi_watchdog(); 1276 check_nmi_watchdog();
1262#ifdef CONFIG_X86_32
1263 zap_low_mappings();
1264#endif
1265} 1277}
1266 1278
1267#ifdef CONFIG_HOTPLUG_CPU 1279#ifdef CONFIG_HOTPLUG_CPU
@@ -1306,7 +1318,7 @@ static void remove_siblinginfo(int cpu)
1306 cpu_clear(cpu, cpu_sibling_setup_map); 1318 cpu_clear(cpu, cpu_sibling_setup_map);
1307} 1319}
1308 1320
1309int additional_cpus __initdata = -1; 1321static int additional_cpus __initdata = -1;
1310 1322
1311static __init int setup_additional_cpus(char *s) 1323static __init int setup_additional_cpus(char *s)
1312{ 1324{