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.c125
1 files changed, 80 insertions, 45 deletions
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
index 7985c5b3f916..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>
@@ -88,7 +89,7 @@ static DEFINE_PER_CPU(struct task_struct *, idle_thread_array);
88#define get_idle_for_cpu(x) (per_cpu(idle_thread_array, x)) 89#define get_idle_for_cpu(x) (per_cpu(idle_thread_array, x))
89#define set_idle_for_cpu(x, p) (per_cpu(idle_thread_array, x) = (p)) 90#define set_idle_for_cpu(x, p) (per_cpu(idle_thread_array, x) = (p))
90#else 91#else
91struct task_struct *idle_thread_array[NR_CPUS] __cpuinitdata ; 92static struct task_struct *idle_thread_array[NR_CPUS] __cpuinitdata ;
92#define get_idle_for_cpu(x) (idle_thread_array[(x)]) 93#define get_idle_for_cpu(x) (idle_thread_array[(x)])
93#define set_idle_for_cpu(x, p) (idle_thread_array[(x)] = (p)) 94#define set_idle_for_cpu(x, p) (idle_thread_array[(x)] = (p))
94#endif 95#endif
@@ -123,13 +124,12 @@ EXPORT_PER_CPU_SYMBOL(cpu_info);
123 124
124static atomic_t init_deasserted; 125static atomic_t init_deasserted;
125 126
126static int boot_cpu_logical_apicid;
127 127
128/* representing cpus for which sibling maps can be computed */ 128/* representing cpus for which sibling maps can be computed */
129static cpumask_t cpu_sibling_setup_map; 129static cpumask_t cpu_sibling_setup_map;
130 130
131/* Set if we find a B stepping CPU */ 131/* Set if we find a B stepping CPU */
132int __cpuinitdata smp_b_stepping; 132static int __cpuinitdata smp_b_stepping;
133 133
134#if defined(CONFIG_NUMA) && defined(CONFIG_X86_32) 134#if defined(CONFIG_NUMA) && defined(CONFIG_X86_32)
135 135
@@ -165,6 +165,8 @@ static void unmap_cpu_to_node(int cpu)
165#endif 165#endif
166 166
167#ifdef CONFIG_X86_32 167#ifdef CONFIG_X86_32
168static int boot_cpu_logical_apicid;
169
168u8 cpu_2_logical_apicid[NR_CPUS] __read_mostly = 170u8 cpu_2_logical_apicid[NR_CPUS] __read_mostly =
169 { [0 ... NR_CPUS-1] = BAD_APICID }; 171 { [0 ... NR_CPUS-1] = BAD_APICID };
170 172
@@ -210,7 +212,7 @@ static void __cpuinit smp_callin(void)
210 /* 212 /*
211 * (This works even if the APIC is not enabled.) 213 * (This works even if the APIC is not enabled.)
212 */ 214 */
213 phys_id = GET_APIC_ID(read_apic_id()); 215 phys_id = read_apic_id();
214 cpuid = smp_processor_id(); 216 cpuid = smp_processor_id();
215 if (cpu_isset(cpuid, cpu_callin_map)) { 217 if (cpu_isset(cpuid, cpu_callin_map)) {
216 panic("%s: phys CPU#%d, CPU#%d already present??\n", __func__, 218 panic("%s: phys CPU#%d, CPU#%d already present??\n", __func__,
@@ -257,6 +259,7 @@ static void __cpuinit smp_callin(void)
257 end_local_APIC_setup(); 259 end_local_APIC_setup();
258 map_cpu_to_logical_apicid(); 260 map_cpu_to_logical_apicid();
259 261
262 notify_cpu_starting(cpuid);
260 /* 263 /*
261 * Get our bogomips. 264 * Get our bogomips.
262 * 265 *
@@ -550,8 +553,7 @@ static inline void __inquire_remote_apic(int apicid)
550 printk(KERN_CONT 553 printk(KERN_CONT
551 "a previous APIC delivery may have failed\n"); 554 "a previous APIC delivery may have failed\n");
552 555
553 apic_write(APIC_ICR2, SET_APIC_DEST_FIELD(apicid)); 556 apic_icr_write(APIC_DM_REMRD | regs[i], apicid);
554 apic_write(APIC_ICR, APIC_DM_REMRD | regs[i]);
555 557
556 timeout = 0; 558 timeout = 0;
557 do { 559 do {
@@ -583,11 +585,9 @@ wakeup_secondary_cpu(int logical_apicid, unsigned long start_eip)
583 int maxlvt; 585 int maxlvt;
584 586
585 /* Target chip */ 587 /* Target chip */
586 apic_write(APIC_ICR2, SET_APIC_DEST_FIELD(logical_apicid));
587
588 /* Boot on the stack */ 588 /* Boot on the stack */
589 /* Kick the second */ 589 /* Kick the second */
590 apic_write(APIC_ICR, APIC_DM_NMI | APIC_DEST_LOGICAL); 590 apic_icr_write(APIC_DM_NMI | APIC_DEST_LOGICAL, logical_apicid);
591 591
592 pr_debug("Waiting for send to finish...\n"); 592 pr_debug("Waiting for send to finish...\n");
593 send_status = safe_apic_wait_icr_idle(); 593 send_status = safe_apic_wait_icr_idle();
@@ -640,13 +640,11 @@ wakeup_secondary_cpu(int phys_apicid, unsigned long start_eip)
640 /* 640 /*
641 * Turn INIT on target chip 641 * Turn INIT on target chip
642 */ 642 */
643 apic_write(APIC_ICR2, SET_APIC_DEST_FIELD(phys_apicid));
644
645 /* 643 /*
646 * Send IPI 644 * Send IPI
647 */ 645 */
648 apic_write(APIC_ICR, 646 apic_icr_write(APIC_INT_LEVELTRIG | APIC_INT_ASSERT | APIC_DM_INIT,
649 APIC_INT_LEVELTRIG | APIC_INT_ASSERT | APIC_DM_INIT); 647 phys_apicid);
650 648
651 pr_debug("Waiting for send to finish...\n"); 649 pr_debug("Waiting for send to finish...\n");
652 send_status = safe_apic_wait_icr_idle(); 650 send_status = safe_apic_wait_icr_idle();
@@ -656,10 +654,8 @@ wakeup_secondary_cpu(int phys_apicid, unsigned long start_eip)
656 pr_debug("Deasserting INIT.\n"); 654 pr_debug("Deasserting INIT.\n");
657 655
658 /* Target chip */ 656 /* Target chip */
659 apic_write(APIC_ICR2, SET_APIC_DEST_FIELD(phys_apicid));
660
661 /* Send IPI */ 657 /* Send IPI */
662 apic_write(APIC_ICR, APIC_INT_LEVELTRIG | APIC_DM_INIT); 658 apic_icr_write(APIC_INT_LEVELTRIG | APIC_DM_INIT, phys_apicid);
663 659
664 pr_debug("Waiting for send to finish...\n"); 660 pr_debug("Waiting for send to finish...\n");
665 send_status = safe_apic_wait_icr_idle(); 661 send_status = safe_apic_wait_icr_idle();
@@ -702,11 +698,10 @@ wakeup_secondary_cpu(int phys_apicid, unsigned long start_eip)
702 */ 698 */
703 699
704 /* Target chip */ 700 /* Target chip */
705 apic_write(APIC_ICR2, SET_APIC_DEST_FIELD(phys_apicid));
706
707 /* Boot on the stack */ 701 /* Boot on the stack */
708 /* Kick the second */ 702 /* Kick the second */
709 apic_write(APIC_ICR, APIC_DM_STARTUP | (start_eip >> 12)); 703 apic_icr_write(APIC_DM_STARTUP | (start_eip >> 12),
704 phys_apicid);
710 705
711 /* 706 /*
712 * Give the other CPU some time to accept the IPI. 707 * Give the other CPU some time to accept the IPI.
@@ -1175,10 +1170,17 @@ void __init native_smp_prepare_cpus(unsigned int max_cpus)
1175 * Setup boot CPU information 1170 * Setup boot CPU information
1176 */ 1171 */
1177 smp_store_cpu_info(0); /* Final full version of the data */ 1172 smp_store_cpu_info(0); /* Final full version of the data */
1173#ifdef CONFIG_X86_32
1178 boot_cpu_logical_apicid = logical_smp_processor_id(); 1174 boot_cpu_logical_apicid = logical_smp_processor_id();
1175#endif
1179 current_thread_info()->cpu = 0; /* needed? */ 1176 current_thread_info()->cpu = 0; /* needed? */
1180 set_cpu_sibling_map(0); 1177 set_cpu_sibling_map(0);
1181 1178
1179#ifdef CONFIG_X86_64
1180 enable_IR_x2apic();
1181 setup_apic_routing();
1182#endif
1183
1182 if (smp_sanity_check(max_cpus) < 0) { 1184 if (smp_sanity_check(max_cpus) < 0) {
1183 printk(KERN_INFO "SMP disabled\n"); 1185 printk(KERN_INFO "SMP disabled\n");
1184 disable_smp(); 1186 disable_smp();
@@ -1186,9 +1188,9 @@ void __init native_smp_prepare_cpus(unsigned int max_cpus)
1186 } 1188 }
1187 1189
1188 preempt_disable(); 1190 preempt_disable();
1189 if (GET_APIC_ID(read_apic_id()) != boot_cpu_physical_apicid) { 1191 if (read_apic_id() != boot_cpu_physical_apicid) {
1190 panic("Boot APIC ID in local APIC unexpected (%d vs %d)", 1192 panic("Boot APIC ID in local APIC unexpected (%d vs %d)",
1191 GET_APIC_ID(read_apic_id()), boot_cpu_physical_apicid); 1193 read_apic_id(), boot_cpu_physical_apicid);
1192 /* Or can we switch back to PIC here? */ 1194 /* Or can we switch back to PIC here? */
1193 } 1195 }
1194 preempt_enable(); 1196 preempt_enable();
@@ -1313,16 +1315,13 @@ __init void prefill_possible_map(void)
1313 if (!num_processors) 1315 if (!num_processors)
1314 num_processors = 1; 1316 num_processors = 1;
1315 1317
1316#ifdef CONFIG_HOTPLUG_CPU
1317 if (additional_cpus == -1) { 1318 if (additional_cpus == -1) {
1318 if (disabled_cpus > 0) 1319 if (disabled_cpus > 0)
1319 additional_cpus = disabled_cpus; 1320 additional_cpus = disabled_cpus;
1320 else 1321 else
1321 additional_cpus = 0; 1322 additional_cpus = 0;
1322 } 1323 }
1323#else 1324
1324 additional_cpus = 0;
1325#endif
1326 possible = num_processors + additional_cpus; 1325 possible = num_processors + additional_cpus;
1327 if (possible > NR_CPUS) 1326 if (possible > NR_CPUS)
1328 possible = NR_CPUS; 1327 possible = NR_CPUS;
@@ -1346,25 +1345,9 @@ static void __ref remove_cpu_from_maps(int cpu)
1346 numa_remove_cpu(cpu); 1345 numa_remove_cpu(cpu);
1347} 1346}
1348 1347
1349int __cpu_disable(void) 1348void cpu_disable_common(void)
1350{ 1349{
1351 int cpu = smp_processor_id(); 1350 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 /* 1351 /*
1369 * HACK: 1352 * HACK:
1370 * Allow any queued timer interrupts to get serviced 1353 * Allow any queued timer interrupts to get serviced
@@ -1382,10 +1365,32 @@ int __cpu_disable(void)
1382 remove_cpu_from_maps(cpu); 1365 remove_cpu_from_maps(cpu);
1383 unlock_vector_lock(); 1366 unlock_vector_lock();
1384 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();
1385 return 0; 1390 return 0;
1386} 1391}
1387 1392
1388void __cpu_die(unsigned int cpu) 1393void native_cpu_die(unsigned int cpu)
1389{ 1394{
1390 /* 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. */
1391 unsigned int i; 1396 unsigned int i;
@@ -1402,15 +1407,45 @@ void __cpu_die(unsigned int cpu)
1402 } 1407 }
1403 printk(KERN_ERR "CPU %u didn't die...\n", cpu); 1408 printk(KERN_ERR "CPU %u didn't die...\n", cpu);
1404} 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
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