diff options
Diffstat (limited to 'arch/x86/kernel/smpboot.c')
-rw-r--r-- | arch/x86/kernel/smpboot.c | 34 |
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 |
88 | u8 apicid_2_node[MAX_APICID]; | 88 | u8 apicid_2_node[MAX_APICID]; |
89 | static 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 | */ |
302 | void __cpuinit start_secondary(void *unused) | 303 | static 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 | */ |
1178 | void __init native_smp_prepare_cpus(unsigned int max_cpus) | 1190 | void __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(); |
1249 | out: | ||
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 | ||
1309 | int additional_cpus __initdata = -1; | 1321 | static int additional_cpus __initdata = -1; |
1310 | 1322 | ||
1311 | static __init int setup_additional_cpus(char *s) | 1323 | static __init int setup_additional_cpus(char *s) |
1312 | { | 1324 | { |