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.c38
1 files changed, 23 insertions, 15 deletions
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
index 8add66b22f33..b1f3ed9c7a9e 100644
--- a/arch/x86/kernel/smpboot.c
+++ b/arch/x86/kernel/smpboot.c
@@ -171,11 +171,6 @@ static void smp_callin(void)
171 apic_ap_setup(); 171 apic_ap_setup();
172 172
173 /* 173 /*
174 * Need to setup vector mappings before we enable interrupts.
175 */
176 setup_vector_irq(smp_processor_id());
177
178 /*
179 * Save our processor parameters. Note: this information 174 * Save our processor parameters. Note: this information
180 * is needed for clock calibration. 175 * is needed for clock calibration.
181 */ 176 */
@@ -239,18 +234,13 @@ static void notrace start_secondary(void *unused)
239 check_tsc_sync_target(); 234 check_tsc_sync_target();
240 235
241 /* 236 /*
242 * Enable the espfix hack for this CPU 237 * Lock vector_lock and initialize the vectors on this cpu
243 */ 238 * before setting the cpu online. We must set it online with
244#ifdef CONFIG_X86_ESPFIX64 239 * vector_lock held to prevent a concurrent setup/teardown
245 init_espfix_ap(); 240 * from seeing a half valid vector space.
246#endif
247
248 /*
249 * We need to hold vector_lock so there the set of online cpus
250 * does not change while we are assigning vectors to cpus. Holding
251 * this lock ensures we don't half assign or remove an irq from a cpu.
252 */ 241 */
253 lock_vector_lock(); 242 lock_vector_lock();
243 setup_vector_irq(smp_processor_id());
254 set_cpu_online(smp_processor_id(), true); 244 set_cpu_online(smp_processor_id(), true);
255 unlock_vector_lock(); 245 unlock_vector_lock();
256 cpu_set_state_online(smp_processor_id()); 246 cpu_set_state_online(smp_processor_id());
@@ -854,6 +844,13 @@ static int do_boot_cpu(int apicid, int cpu, struct task_struct *idle)
854 initial_code = (unsigned long)start_secondary; 844 initial_code = (unsigned long)start_secondary;
855 stack_start = idle->thread.sp; 845 stack_start = idle->thread.sp;
856 846
847 /*
848 * Enable the espfix hack for this CPU
849 */
850#ifdef CONFIG_X86_ESPFIX64
851 init_espfix_ap(cpu);
852#endif
853
857 /* So we see what's up */ 854 /* So we see what's up */
858 announce_cpu(cpu, apicid); 855 announce_cpu(cpu, apicid);
859 856
@@ -995,8 +992,17 @@ int native_cpu_up(unsigned int cpu, struct task_struct *tidle)
995 992
996 common_cpu_up(cpu, tidle); 993 common_cpu_up(cpu, tidle);
997 994
995 /*
996 * We have to walk the irq descriptors to setup the vector
997 * space for the cpu which comes online. Prevent irq
998 * alloc/free across the bringup.
999 */
1000 irq_lock_sparse();
1001
998 err = do_boot_cpu(apicid, cpu, tidle); 1002 err = do_boot_cpu(apicid, cpu, tidle);
1003
999 if (err) { 1004 if (err) {
1005 irq_unlock_sparse();
1000 pr_err("do_boot_cpu failed(%d) to wakeup CPU#%u\n", err, cpu); 1006 pr_err("do_boot_cpu failed(%d) to wakeup CPU#%u\n", err, cpu);
1001 return -EIO; 1007 return -EIO;
1002 } 1008 }
@@ -1014,6 +1020,8 @@ int native_cpu_up(unsigned int cpu, struct task_struct *tidle)
1014 touch_nmi_watchdog(); 1020 touch_nmi_watchdog();
1015 } 1021 }
1016 1022
1023 irq_unlock_sparse();
1024
1017 return 0; 1025 return 0;
1018} 1026}
1019 1027