diff options
Diffstat (limited to 'arch/x86/kernel/smpboot.c')
| -rw-r--r-- | arch/x86/kernel/smpboot.c | 38 |
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 | ||
