diff options
Diffstat (limited to 'arch/x86/kernel/cpu/common.c')
-rw-r--r-- | arch/x86/kernel/cpu/common.c | 29 |
1 files changed, 18 insertions, 11 deletions
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index e4ab2b42bd6f..426cfedefd04 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c | |||
@@ -1266,6 +1266,19 @@ static void dbg_restore_debug_regs(void) | |||
1266 | #define dbg_restore_debug_regs() | 1266 | #define dbg_restore_debug_regs() |
1267 | #endif /* ! CONFIG_KGDB */ | 1267 | #endif /* ! CONFIG_KGDB */ |
1268 | 1268 | ||
1269 | static void wait_for_master_cpu(int cpu) | ||
1270 | { | ||
1271 | #ifdef CONFIG_SMP | ||
1272 | /* | ||
1273 | * wait for ACK from master CPU before continuing | ||
1274 | * with AP initialization | ||
1275 | */ | ||
1276 | WARN_ON(cpumask_test_and_set_cpu(cpu, cpu_initialized_mask)); | ||
1277 | while (!cpumask_test_cpu(cpu, cpu_callout_mask)) | ||
1278 | cpu_relax(); | ||
1279 | #endif | ||
1280 | } | ||
1281 | |||
1269 | /* | 1282 | /* |
1270 | * cpu_init() initializes state that is per-CPU. Some data is already | 1283 | * cpu_init() initializes state that is per-CPU. Some data is already |
1271 | * initialized (naturally) in the bootstrap process, such as the GDT | 1284 | * initialized (naturally) in the bootstrap process, such as the GDT |
@@ -1281,16 +1294,17 @@ void cpu_init(void) | |||
1281 | struct task_struct *me; | 1294 | struct task_struct *me; |
1282 | struct tss_struct *t; | 1295 | struct tss_struct *t; |
1283 | unsigned long v; | 1296 | unsigned long v; |
1284 | int cpu; | 1297 | int cpu = stack_smp_processor_id(); |
1285 | int i; | 1298 | int i; |
1286 | 1299 | ||
1300 | wait_for_master_cpu(cpu); | ||
1301 | |||
1287 | /* | 1302 | /* |
1288 | * Load microcode on this cpu if a valid microcode is available. | 1303 | * Load microcode on this cpu if a valid microcode is available. |
1289 | * This is early microcode loading procedure. | 1304 | * This is early microcode loading procedure. |
1290 | */ | 1305 | */ |
1291 | load_ucode_ap(); | 1306 | load_ucode_ap(); |
1292 | 1307 | ||
1293 | cpu = stack_smp_processor_id(); | ||
1294 | t = &per_cpu(init_tss, cpu); | 1308 | t = &per_cpu(init_tss, cpu); |
1295 | oist = &per_cpu(orig_ist, cpu); | 1309 | oist = &per_cpu(orig_ist, cpu); |
1296 | 1310 | ||
@@ -1302,9 +1316,6 @@ void cpu_init(void) | |||
1302 | 1316 | ||
1303 | me = current; | 1317 | me = current; |
1304 | 1318 | ||
1305 | if (cpumask_test_and_set_cpu(cpu, cpu_initialized_mask)) | ||
1306 | panic("CPU#%d already initialized!\n", cpu); | ||
1307 | |||
1308 | pr_debug("Initializing CPU#%d\n", cpu); | 1319 | pr_debug("Initializing CPU#%d\n", cpu); |
1309 | 1320 | ||
1310 | clear_in_cr4(X86_CR4_VME|X86_CR4_PVI|X86_CR4_TSD|X86_CR4_DE); | 1321 | clear_in_cr4(X86_CR4_VME|X86_CR4_PVI|X86_CR4_TSD|X86_CR4_DE); |
@@ -1381,13 +1392,9 @@ void cpu_init(void) | |||
1381 | struct tss_struct *t = &per_cpu(init_tss, cpu); | 1392 | struct tss_struct *t = &per_cpu(init_tss, cpu); |
1382 | struct thread_struct *thread = &curr->thread; | 1393 | struct thread_struct *thread = &curr->thread; |
1383 | 1394 | ||
1384 | show_ucode_info_early(); | 1395 | wait_for_master_cpu(cpu); |
1385 | 1396 | ||
1386 | if (cpumask_test_and_set_cpu(cpu, cpu_initialized_mask)) { | 1397 | show_ucode_info_early(); |
1387 | printk(KERN_WARNING "CPU#%d already initialized!\n", cpu); | ||
1388 | for (;;) | ||
1389 | local_irq_enable(); | ||
1390 | } | ||
1391 | 1398 | ||
1392 | printk(KERN_INFO "Initializing CPU#%d\n", cpu); | 1399 | printk(KERN_INFO "Initializing CPU#%d\n", cpu); |
1393 | 1400 | ||