diff options
Diffstat (limited to 'arch/x86/kernel/smpboot.c')
-rw-r--r-- | arch/x86/kernel/smpboot.c | 77 |
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 | ||
1347 | int __cpu_disable(void) | 1348 | void 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 | |||
1370 | int 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 | ||
1386 | void __cpu_die(unsigned int cpu) | 1393 | void 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 | |||
1411 | void 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 | |||
1428 | void native_play_dead(void) | ||
1429 | { | ||
1430 | play_dead_common(); | ||
1431 | wbinvd_halt(); | ||
1432 | } | ||
1433 | |||
1403 | #else /* ... !CONFIG_HOTPLUG_CPU */ | 1434 | #else /* ... !CONFIG_HOTPLUG_CPU */ |
1404 | int __cpu_disable(void) | 1435 | int native_cpu_disable(void) |
1405 | { | 1436 | { |
1406 | return -ENOSYS; | 1437 | return -ENOSYS; |
1407 | } | 1438 | } |
1408 | 1439 | ||
1409 | void __cpu_die(unsigned int cpu) | 1440 | void 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 | |||
1446 | void native_play_dead(void) | ||
1447 | { | ||
1448 | BUG(); | ||
1449 | } | ||
1450 | |||
1414 | #endif | 1451 | #endif |