aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/smpboot.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2008-10-12 15:04:59 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-10-12 15:05:14 -0400
commit807f4f8cdd5b65a8a5fcfda266c074f6a23818dd (patch)
tree395afdf45badd02d03871c827b8baa850cbe5841 /arch/x86/kernel/smpboot.c
parent1a2217a9516b134e0a0e54cb4629e1e075d97b17 (diff)
parent8daf14cf56816303d64d1a705fcbc389211ba36e (diff)
Merge branch 'x86-core-v2-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip
This merges in: x86/build, x86/microcode, x86/spinlocks, x86/memory-corruption-check, x86/early-printk, x86/xsave, x86/quirks, x86/setup, x86/signal, core/signal, x86/urgent, x86/xen * 'x86-core-v2-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: (142 commits) x86: make processor type select depend on CONFIG_EMBEDDED x86: extend processor type select help text x86, amd-iommu: propagate PCI device enabling error warnings: fix arch/x86/kernel/io_apic_64.c warnings: fix arch/x86/kernel/early_printk.c x86, fpu: check __clear_user() return value x86: memory corruption check - cleanup x86: ioperm user_regset xen: do not reserve 2 pages of padding between hypervisor and fixmap. xen: use spin_lock_nest_lock when pinning a pagetable x86: xsave: set FP, SSE bits in the xsave header in the user sigcontext x86: xsave: fix error condition in save_i387_xstate() x86: SB450: deprioritize DMI quirks x86: SB450: skip IRQ0 override if it is not routed to INT2 of IOAPIC x86: replace a magic number with a named constant in the VESA boot code x86 setup: remove IMAGE_OFFSET x86 setup: remove DEF_INITSEG and DEF_SETUPSEG Revert "x86: fix ghost EDD devices in /sys again" x86 setup: fix ghost entries under /sys/firmware/edd take 3 x86: signal: remove indent in restore_sigcontext() ...
Diffstat (limited to 'arch/x86/kernel/smpboot.c')
-rw-r--r--arch/x86/kernel/smpboot.c77
1 files changed, 57 insertions, 20 deletions
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
index 9056f7e272c0..76b6f50978f7 100644
--- a/arch/x86/kernel/smpboot.c
+++ b/arch/x86/kernel/smpboot.c
@@ -52,6 +52,7 @@
52#include <asm/desc.h> 52#include <asm/desc.h>
53#include <asm/nmi.h> 53#include <asm/nmi.h>
54#include <asm/irq.h> 54#include <asm/irq.h>
55#include <asm/idle.h>
55#include <asm/smp.h> 56#include <asm/smp.h>
56#include <asm/trampoline.h> 57#include <asm/trampoline.h>
57#include <asm/cpu.h> 58#include <asm/cpu.h>
@@ -1344,25 +1345,9 @@ static void __ref remove_cpu_from_maps(int cpu)
1344 numa_remove_cpu(cpu); 1345 numa_remove_cpu(cpu);
1345} 1346}
1346 1347
1347int __cpu_disable(void) 1348void cpu_disable_common(void)
1348{ 1349{
1349 int cpu = smp_processor_id(); 1350 int cpu = smp_processor_id();
1350
1351 /*
1352 * Perhaps use cpufreq to drop frequency, but that could go
1353 * into generic code.
1354 *
1355 * We won't take down the boot processor on i386 due to some
1356 * interrupts only being able to be serviced by the BSP.
1357 * Especially so if we're not using an IOAPIC -zwane
1358 */
1359 if (cpu == 0)
1360 return -EBUSY;
1361
1362 if (nmi_watchdog == NMI_LOCAL_APIC)
1363 stop_apic_nmi_watchdog(NULL);
1364 clear_local_APIC();
1365
1366 /* 1351 /*
1367 * HACK: 1352 * HACK:
1368 * Allow any queued timer interrupts to get serviced 1353 * Allow any queued timer interrupts to get serviced
@@ -1380,10 +1365,32 @@ int __cpu_disable(void)
1380 remove_cpu_from_maps(cpu); 1365 remove_cpu_from_maps(cpu);
1381 unlock_vector_lock(); 1366 unlock_vector_lock();
1382 fixup_irqs(cpu_online_map); 1367 fixup_irqs(cpu_online_map);
1368}
1369
1370int native_cpu_disable(void)
1371{
1372 int cpu = smp_processor_id();
1373
1374 /*
1375 * Perhaps use cpufreq to drop frequency, but that could go
1376 * into generic code.
1377 *
1378 * We won't take down the boot processor on i386 due to some
1379 * interrupts only being able to be serviced by the BSP.
1380 * Especially so if we're not using an IOAPIC -zwane
1381 */
1382 if (cpu == 0)
1383 return -EBUSY;
1384
1385 if (nmi_watchdog == NMI_LOCAL_APIC)
1386 stop_apic_nmi_watchdog(NULL);
1387 clear_local_APIC();
1388
1389 cpu_disable_common();
1383 return 0; 1390 return 0;
1384} 1391}
1385 1392
1386void __cpu_die(unsigned int cpu) 1393void native_cpu_die(unsigned int cpu)
1387{ 1394{
1388 /* We don't do anything here: idle task is faking death itself. */ 1395 /* We don't do anything here: idle task is faking death itself. */
1389 unsigned int i; 1396 unsigned int i;
@@ -1400,15 +1407,45 @@ void __cpu_die(unsigned int cpu)
1400 } 1407 }
1401 printk(KERN_ERR "CPU %u didn't die...\n", cpu); 1408 printk(KERN_ERR "CPU %u didn't die...\n", cpu);
1402} 1409}
1410
1411void play_dead_common(void)
1412{
1413 idle_task_exit();
1414 reset_lazy_tlbstate();
1415 irq_ctx_exit(raw_smp_processor_id());
1416 c1e_remove_cpu(raw_smp_processor_id());
1417
1418 mb();
1419 /* Ack it */
1420 __get_cpu_var(cpu_state) = CPU_DEAD;
1421
1422 /*
1423 * With physical CPU hotplug, we should halt the cpu
1424 */
1425 local_irq_disable();
1426}
1427
1428void native_play_dead(void)
1429{
1430 play_dead_common();
1431 wbinvd_halt();
1432}
1433
1403#else /* ... !CONFIG_HOTPLUG_CPU */ 1434#else /* ... !CONFIG_HOTPLUG_CPU */
1404int __cpu_disable(void) 1435int native_cpu_disable(void)
1405{ 1436{
1406 return -ENOSYS; 1437 return -ENOSYS;
1407} 1438}
1408 1439
1409void __cpu_die(unsigned int cpu) 1440void native_cpu_die(unsigned int cpu)
1410{ 1441{
1411 /* We said "no" in __cpu_disable */ 1442 /* We said "no" in __cpu_disable */
1412 BUG(); 1443 BUG();
1413} 1444}
1445
1446void native_play_dead(void)
1447{
1448 BUG();
1449}
1450
1414#endif 1451#endif