aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/smpboot.c
diff options
context:
space:
mode:
authorEric W. Biederman <ebiederm@xmission.com>2008-08-09 18:09:02 -0400
committerIngo Molnar <mingo@elte.hu>2008-08-11 04:37:34 -0400
commitd388e5fdc461344d04307a3fa83862b9ed429647 (patch)
tree61a9a4311b165038423a0f3412e93b8811796c6b /arch/x86/kernel/smpboot.c
parent31343d8a5079cda57ffd539fcf4f00cea344fe98 (diff)
x86: Restore proper vector locking during cpu hotplug
Having cpu_online_map change during assign_irq_vector can result in some really nasty and weird things happening. The one that bit me last time was accessing non existent per cpu memory for non existent cpus. This locking was removed in a sloppy x86_64 and x86_32 merge patch. Guys can we please try and avoid subtly breaking x86 when we are merging files together? Signed-off-by: Eric W. Biederman <ebiederm@xmission.com> Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Diffstat (limited to 'arch/x86/kernel/smpboot.c')
-rw-r--r--arch/x86/kernel/smpboot.c12
1 files changed, 9 insertions, 3 deletions
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
index 332512767f4f..da10f07fc59c 100644
--- a/arch/x86/kernel/smpboot.c
+++ b/arch/x86/kernel/smpboot.c
@@ -326,12 +326,16 @@ static void __cpuinit start_secondary(void *unused)
326 * for which cpus receive the IPI. Holding this 326 * for which cpus receive the IPI. Holding this
327 * lock helps us to not include this cpu in a currently in progress 327 * lock helps us to not include this cpu in a currently in progress
328 * smp_call_function(). 328 * smp_call_function().
329 *
330 * We need to hold vector_lock so there the set of online cpus
331 * does not change while we are assigning vectors to cpus. Holding
332 * this lock ensures we don't half assign or remove an irq from a cpu.
329 */ 333 */
330 ipi_call_lock_irq(); 334 ipi_call_lock_irq();
331#ifdef CONFIG_X86_IO_APIC 335 lock_vector_lock();
332 setup_vector_irq(smp_processor_id()); 336 __setup_vector_irq(smp_processor_id());
333#endif
334 cpu_set(smp_processor_id(), cpu_online_map); 337 cpu_set(smp_processor_id(), cpu_online_map);
338 unlock_vector_lock();
335 ipi_call_unlock_irq(); 339 ipi_call_unlock_irq();
336 per_cpu(cpu_state, smp_processor_id()) = CPU_ONLINE; 340 per_cpu(cpu_state, smp_processor_id()) = CPU_ONLINE;
337 341
@@ -1336,7 +1340,9 @@ int __cpu_disable(void)
1336 remove_siblinginfo(cpu); 1340 remove_siblinginfo(cpu);
1337 1341
1338 /* It's now safe to remove this processor from the online map */ 1342 /* It's now safe to remove this processor from the online map */
1343 lock_vector_lock();
1339 remove_cpu_from_maps(cpu); 1344 remove_cpu_from_maps(cpu);
1345 unlock_vector_lock();
1340 fixup_irqs(cpu_online_map); 1346 fixup_irqs(cpu_online_map);
1341 return 0; 1347 return 0;
1342} 1348}