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.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