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.c75
1 files changed, 55 insertions, 20 deletions
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
index 7985c5b3f916..66b04e598817 100644
--- a/arch/x86/kernel/smpboot.c
+++ b/arch/x86/kernel/smpboot.c
@@ -1346,25 +1346,9 @@ static void __ref remove_cpu_from_maps(int cpu)
1346 numa_remove_cpu(cpu); 1346 numa_remove_cpu(cpu);
1347} 1347}
1348 1348
1349int __cpu_disable(void) 1349void cpu_disable_common(void)
1350{ 1350{
1351 int cpu = smp_processor_id(); 1351 int cpu = smp_processor_id();
1352
1353 /*
1354 * Perhaps use cpufreq to drop frequency, but that could go
1355 * into generic code.
1356 *
1357 * We won't take down the boot processor on i386 due to some
1358 * interrupts only being able to be serviced by the BSP.
1359 * Especially so if we're not using an IOAPIC -zwane
1360 */
1361 if (cpu == 0)
1362 return -EBUSY;
1363
1364 if (nmi_watchdog == NMI_LOCAL_APIC)
1365 stop_apic_nmi_watchdog(NULL);
1366 clear_local_APIC();
1367
1368 /* 1352 /*
1369 * HACK: 1353 * HACK:
1370 * Allow any queued timer interrupts to get serviced 1354 * Allow any queued timer interrupts to get serviced
@@ -1382,10 +1366,32 @@ int __cpu_disable(void)
1382 remove_cpu_from_maps(cpu); 1366 remove_cpu_from_maps(cpu);
1383 unlock_vector_lock(); 1367 unlock_vector_lock();
1384 fixup_irqs(cpu_online_map); 1368 fixup_irqs(cpu_online_map);
1369}
1370
1371int native_cpu_disable(void)
1372{
1373 int cpu = smp_processor_id();
1374
1375 /*
1376 * Perhaps use cpufreq to drop frequency, but that could go
1377 * into generic code.
1378 *
1379 * We won't take down the boot processor on i386 due to some
1380 * interrupts only being able to be serviced by the BSP.
1381 * Especially so if we're not using an IOAPIC -zwane
1382 */
1383 if (cpu == 0)
1384 return -EBUSY;
1385
1386 if (nmi_watchdog == NMI_LOCAL_APIC)
1387 stop_apic_nmi_watchdog(NULL);
1388 clear_local_APIC();
1389
1390 cpu_disable_common();
1385 return 0; 1391 return 0;
1386} 1392}
1387 1393
1388void __cpu_die(unsigned int cpu) 1394void native_cpu_die(unsigned int cpu)
1389{ 1395{
1390 /* We don't do anything here: idle task is faking death itself. */ 1396 /* We don't do anything here: idle task is faking death itself. */
1391 unsigned int i; 1397 unsigned int i;
@@ -1402,15 +1408,44 @@ void __cpu_die(unsigned int cpu)
1402 } 1408 }
1403 printk(KERN_ERR "CPU %u didn't die...\n", cpu); 1409 printk(KERN_ERR "CPU %u didn't die...\n", cpu);
1404} 1410}
1411
1412void play_dead_common(void)
1413{
1414 idle_task_exit();
1415 reset_lazy_tlbstate();
1416 irq_ctx_exit(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
1405#else /* ... !CONFIG_HOTPLUG_CPU */ 1434#else /* ... !CONFIG_HOTPLUG_CPU */
1406int __cpu_disable(void) 1435int native_cpu_disable(void)
1407{ 1436{
1408 return -ENOSYS; 1437 return -ENOSYS;
1409} 1438}
1410 1439
1411void __cpu_die(unsigned int cpu) 1440void native_cpu_die(unsigned int cpu)
1412{ 1441{
1413 /* We said "no" in __cpu_disable */ 1442 /* We said "no" in __cpu_disable */
1414 BUG(); 1443 BUG();
1415} 1444}
1445
1446void native_play_dead(void)
1447{
1448 BUG();
1449}
1450
1416#endif 1451#endif