diff options
Diffstat (limited to 'arch/x86/kernel/cpu/common.c')
-rw-r--r-- | arch/x86/kernel/cpu/common.c | 27 |
1 files changed, 11 insertions, 16 deletions
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index a4bcbacdbe0b..a135239badb7 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c | |||
@@ -1221,17 +1221,6 @@ static void dbg_restore_debug_regs(void) | |||
1221 | #define dbg_restore_debug_regs() | 1221 | #define dbg_restore_debug_regs() |
1222 | #endif /* ! CONFIG_KGDB */ | 1222 | #endif /* ! CONFIG_KGDB */ |
1223 | 1223 | ||
1224 | static void wait_for_master_cpu(int cpu) | ||
1225 | { | ||
1226 | /* | ||
1227 | * wait for ACK from master CPU before continuing | ||
1228 | * with AP initialization | ||
1229 | */ | ||
1230 | WARN_ON(cpumask_test_and_set_cpu(cpu, cpu_initialized_mask)); | ||
1231 | while (!cpumask_test_cpu(cpu, cpu_callout_mask)) | ||
1232 | cpu_relax(); | ||
1233 | } | ||
1234 | |||
1235 | /* | 1224 | /* |
1236 | * cpu_init() initializes state that is per-CPU. Some data is already | 1225 | * cpu_init() initializes state that is per-CPU. Some data is already |
1237 | * initialized (naturally) in the bootstrap process, such as the GDT | 1226 | * initialized (naturally) in the bootstrap process, such as the GDT |
@@ -1247,17 +1236,16 @@ void cpu_init(void) | |||
1247 | struct task_struct *me; | 1236 | struct task_struct *me; |
1248 | struct tss_struct *t; | 1237 | struct tss_struct *t; |
1249 | unsigned long v; | 1238 | unsigned long v; |
1250 | int cpu = stack_smp_processor_id(); | 1239 | int cpu; |
1251 | int i; | 1240 | int i; |
1252 | 1241 | ||
1253 | wait_for_master_cpu(cpu); | ||
1254 | |||
1255 | /* | 1242 | /* |
1256 | * Load microcode on this cpu if a valid microcode is available. | 1243 | * Load microcode on this cpu if a valid microcode is available. |
1257 | * This is early microcode loading procedure. | 1244 | * This is early microcode loading procedure. |
1258 | */ | 1245 | */ |
1259 | load_ucode_ap(); | 1246 | load_ucode_ap(); |
1260 | 1247 | ||
1248 | cpu = stack_smp_processor_id(); | ||
1261 | t = &per_cpu(init_tss, cpu); | 1249 | t = &per_cpu(init_tss, cpu); |
1262 | oist = &per_cpu(orig_ist, cpu); | 1250 | oist = &per_cpu(orig_ist, cpu); |
1263 | 1251 | ||
@@ -1269,6 +1257,9 @@ void cpu_init(void) | |||
1269 | 1257 | ||
1270 | me = current; | 1258 | me = current; |
1271 | 1259 | ||
1260 | if (cpumask_test_and_set_cpu(cpu, cpu_initialized_mask)) | ||
1261 | panic("CPU#%d already initialized!\n", cpu); | ||
1262 | |||
1272 | pr_debug("Initializing CPU#%d\n", cpu); | 1263 | pr_debug("Initializing CPU#%d\n", cpu); |
1273 | 1264 | ||
1274 | clear_in_cr4(X86_CR4_VME|X86_CR4_PVI|X86_CR4_TSD|X86_CR4_DE); | 1265 | clear_in_cr4(X86_CR4_VME|X86_CR4_PVI|X86_CR4_TSD|X86_CR4_DE); |
@@ -1345,10 +1336,14 @@ void cpu_init(void) | |||
1345 | struct tss_struct *t = &per_cpu(init_tss, cpu); | 1336 | struct tss_struct *t = &per_cpu(init_tss, cpu); |
1346 | struct thread_struct *thread = &curr->thread; | 1337 | struct thread_struct *thread = &curr->thread; |
1347 | 1338 | ||
1348 | wait_for_master_cpu(cpu); | ||
1349 | |||
1350 | show_ucode_info_early(); | 1339 | show_ucode_info_early(); |
1351 | 1340 | ||
1341 | if (cpumask_test_and_set_cpu(cpu, cpu_initialized_mask)) { | ||
1342 | printk(KERN_WARNING "CPU#%d already initialized!\n", cpu); | ||
1343 | for (;;) | ||
1344 | local_irq_enable(); | ||
1345 | } | ||
1346 | |||
1352 | printk(KERN_INFO "Initializing CPU#%d\n", cpu); | 1347 | printk(KERN_INFO "Initializing CPU#%d\n", cpu); |
1353 | 1348 | ||
1354 | if (cpu_has_vme || cpu_has_tsc || cpu_has_de) | 1349 | if (cpu_has_vme || cpu_has_tsc || cpu_has_de) |