aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/smpboot.c
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2008-10-12 06:35:23 -0400
committerIngo Molnar <mingo@elte.hu>2008-10-12 06:37:32 -0400
commit365d46dc9be9b3c833990a06f3994b1987eda578 (patch)
tree9397d1304144a288411f2118707f44ff5e862fa6 /arch/x86/kernel/smpboot.c
parent5dc64a3442b98eaa0e3730c35fcf00cf962a93e7 (diff)
parentfd048088306656824958e7783ffcee27e241b361 (diff)
Merge branch 'linus' into x86/xen
Conflicts: arch/x86/kernel/cpu/common.c arch/x86/kernel/process_64.c arch/x86/xen/enlighten.c
Diffstat (limited to 'arch/x86/kernel/smpboot.c')
-rw-r--r--arch/x86/kernel/smpboot.c48
1 files changed, 23 insertions, 25 deletions
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
index 06f1407d5542..76b6f50978f7 100644
--- a/arch/x86/kernel/smpboot.c
+++ b/arch/x86/kernel/smpboot.c
@@ -89,7 +89,7 @@ static DEFINE_PER_CPU(struct task_struct *, idle_thread_array);
89#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))
90#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))
91#else 91#else
92struct task_struct *idle_thread_array[NR_CPUS] __cpuinitdata ; 92static struct task_struct *idle_thread_array[NR_CPUS] __cpuinitdata ;
93#define get_idle_for_cpu(x) (idle_thread_array[(x)]) 93#define get_idle_for_cpu(x) (idle_thread_array[(x)])
94#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))
95#endif 95#endif
@@ -124,13 +124,12 @@ EXPORT_PER_CPU_SYMBOL(cpu_info);
124 124
125static atomic_t init_deasserted; 125static atomic_t init_deasserted;
126 126
127static int boot_cpu_logical_apicid;
128 127
129/* representing cpus for which sibling maps can be computed */ 128/* representing cpus for which sibling maps can be computed */
130static cpumask_t cpu_sibling_setup_map; 129static cpumask_t cpu_sibling_setup_map;
131 130
132/* Set if we find a B stepping CPU */ 131/* Set if we find a B stepping CPU */
133int __cpuinitdata smp_b_stepping; 132static int __cpuinitdata smp_b_stepping;
134 133
135#if defined(CONFIG_NUMA) && defined(CONFIG_X86_32) 134#if defined(CONFIG_NUMA) && defined(CONFIG_X86_32)
136 135
@@ -166,6 +165,8 @@ static void unmap_cpu_to_node(int cpu)
166#endif 165#endif
167 166
168#ifdef CONFIG_X86_32 167#ifdef CONFIG_X86_32
168static int boot_cpu_logical_apicid;
169
169u8 cpu_2_logical_apicid[NR_CPUS] __read_mostly = 170u8 cpu_2_logical_apicid[NR_CPUS] __read_mostly =
170 { [0 ... NR_CPUS-1] = BAD_APICID }; 171 { [0 ... NR_CPUS-1] = BAD_APICID };
171 172
@@ -211,7 +212,7 @@ static void __cpuinit smp_callin(void)
211 /* 212 /*
212 * (This works even if the APIC is not enabled.) 213 * (This works even if the APIC is not enabled.)
213 */ 214 */
214 phys_id = GET_APIC_ID(read_apic_id()); 215 phys_id = read_apic_id();
215 cpuid = smp_processor_id(); 216 cpuid = smp_processor_id();
216 if (cpu_isset(cpuid, cpu_callin_map)) { 217 if (cpu_isset(cpuid, cpu_callin_map)) {
217 panic("%s: phys CPU#%d, CPU#%d already present??\n", __func__, 218 panic("%s: phys CPU#%d, CPU#%d already present??\n", __func__,
@@ -258,6 +259,7 @@ static void __cpuinit smp_callin(void)
258 end_local_APIC_setup(); 259 end_local_APIC_setup();
259 map_cpu_to_logical_apicid(); 260 map_cpu_to_logical_apicid();
260 261
262 notify_cpu_starting(cpuid);
261 /* 263 /*
262 * Get our bogomips. 264 * Get our bogomips.
263 * 265 *
@@ -551,8 +553,7 @@ static inline void __inquire_remote_apic(int apicid)
551 printk(KERN_CONT 553 printk(KERN_CONT
552 "a previous APIC delivery may have failed\n"); 554 "a previous APIC delivery may have failed\n");
553 555
554 apic_write(APIC_ICR2, SET_APIC_DEST_FIELD(apicid)); 556 apic_icr_write(APIC_DM_REMRD | regs[i], apicid);
555 apic_write(APIC_ICR, APIC_DM_REMRD | regs[i]);
556 557
557 timeout = 0; 558 timeout = 0;
558 do { 559 do {
@@ -584,11 +585,9 @@ wakeup_secondary_cpu(int logical_apicid, unsigned long start_eip)
584 int maxlvt; 585 int maxlvt;
585 586
586 /* Target chip */ 587 /* Target chip */
587 apic_write(APIC_ICR2, SET_APIC_DEST_FIELD(logical_apicid));
588
589 /* Boot on the stack */ 588 /* Boot on the stack */
590 /* Kick the second */ 589 /* Kick the second */
591 apic_write(APIC_ICR, APIC_DM_NMI | APIC_DEST_LOGICAL); 590 apic_icr_write(APIC_DM_NMI | APIC_DEST_LOGICAL, logical_apicid);
592 591
593 pr_debug("Waiting for send to finish...\n"); 592 pr_debug("Waiting for send to finish...\n");
594 send_status = safe_apic_wait_icr_idle(); 593 send_status = safe_apic_wait_icr_idle();
@@ -641,13 +640,11 @@ wakeup_secondary_cpu(int phys_apicid, unsigned long start_eip)
641 /* 640 /*
642 * Turn INIT on target chip 641 * Turn INIT on target chip
643 */ 642 */
644 apic_write(APIC_ICR2, SET_APIC_DEST_FIELD(phys_apicid));
645
646 /* 643 /*
647 * Send IPI 644 * Send IPI
648 */ 645 */
649 apic_write(APIC_ICR, 646 apic_icr_write(APIC_INT_LEVELTRIG | APIC_INT_ASSERT | APIC_DM_INIT,
650 APIC_INT_LEVELTRIG | APIC_INT_ASSERT | APIC_DM_INIT); 647 phys_apicid);
651 648
652 pr_debug("Waiting for send to finish...\n"); 649 pr_debug("Waiting for send to finish...\n");
653 send_status = safe_apic_wait_icr_idle(); 650 send_status = safe_apic_wait_icr_idle();
@@ -657,10 +654,8 @@ wakeup_secondary_cpu(int phys_apicid, unsigned long start_eip)
657 pr_debug("Deasserting INIT.\n"); 654 pr_debug("Deasserting INIT.\n");
658 655
659 /* Target chip */ 656 /* Target chip */
660 apic_write(APIC_ICR2, SET_APIC_DEST_FIELD(phys_apicid));
661
662 /* Send IPI */ 657 /* Send IPI */
663 apic_write(APIC_ICR, APIC_INT_LEVELTRIG | APIC_DM_INIT); 658 apic_icr_write(APIC_INT_LEVELTRIG | APIC_DM_INIT, phys_apicid);
664 659
665 pr_debug("Waiting for send to finish...\n"); 660 pr_debug("Waiting for send to finish...\n");
666 send_status = safe_apic_wait_icr_idle(); 661 send_status = safe_apic_wait_icr_idle();
@@ -703,11 +698,10 @@ wakeup_secondary_cpu(int phys_apicid, unsigned long start_eip)
703 */ 698 */
704 699
705 /* Target chip */ 700 /* Target chip */
706 apic_write(APIC_ICR2, SET_APIC_DEST_FIELD(phys_apicid));
707
708 /* Boot on the stack */ 701 /* Boot on the stack */
709 /* Kick the second */ 702 /* Kick the second */
710 apic_write(APIC_ICR, APIC_DM_STARTUP | (start_eip >> 12)); 703 apic_icr_write(APIC_DM_STARTUP | (start_eip >> 12),
704 phys_apicid);
711 705
712 /* 706 /*
713 * Give the other CPU some time to accept the IPI. 707 * Give the other CPU some time to accept the IPI.
@@ -1176,10 +1170,17 @@ void __init native_smp_prepare_cpus(unsigned int max_cpus)
1176 * Setup boot CPU information 1170 * Setup boot CPU information
1177 */ 1171 */
1178 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
1179 boot_cpu_logical_apicid = logical_smp_processor_id(); 1174 boot_cpu_logical_apicid = logical_smp_processor_id();
1175#endif
1180 current_thread_info()->cpu = 0; /* needed? */ 1176 current_thread_info()->cpu = 0; /* needed? */
1181 set_cpu_sibling_map(0); 1177 set_cpu_sibling_map(0);
1182 1178
1179#ifdef CONFIG_X86_64
1180 enable_IR_x2apic();
1181 setup_apic_routing();
1182#endif
1183
1183 if (smp_sanity_check(max_cpus) < 0) { 1184 if (smp_sanity_check(max_cpus) < 0) {
1184 printk(KERN_INFO "SMP disabled\n"); 1185 printk(KERN_INFO "SMP disabled\n");
1185 disable_smp(); 1186 disable_smp();
@@ -1187,9 +1188,9 @@ void __init native_smp_prepare_cpus(unsigned int max_cpus)
1187 } 1188 }
1188 1189
1189 preempt_disable(); 1190 preempt_disable();
1190 if (GET_APIC_ID(read_apic_id()) != boot_cpu_physical_apicid) { 1191 if (read_apic_id() != boot_cpu_physical_apicid) {
1191 panic("Boot APIC ID in local APIC unexpected (%d vs %d)", 1192 panic("Boot APIC ID in local APIC unexpected (%d vs %d)",
1192 GET_APIC_ID(read_apic_id()), boot_cpu_physical_apicid); 1193 read_apic_id(), boot_cpu_physical_apicid);
1193 /* Or can we switch back to PIC here? */ 1194 /* Or can we switch back to PIC here? */
1194 } 1195 }
1195 preempt_enable(); 1196 preempt_enable();
@@ -1314,16 +1315,13 @@ __init void prefill_possible_map(void)
1314 if (!num_processors) 1315 if (!num_processors)
1315 num_processors = 1; 1316 num_processors = 1;
1316 1317
1317#ifdef CONFIG_HOTPLUG_CPU
1318 if (additional_cpus == -1) { 1318 if (additional_cpus == -1) {
1319 if (disabled_cpus > 0) 1319 if (disabled_cpus > 0)
1320 additional_cpus = disabled_cpus; 1320 additional_cpus = disabled_cpus;
1321 else 1321 else
1322 additional_cpus = 0; 1322 additional_cpus = 0;
1323 } 1323 }
1324#else 1324
1325 additional_cpus = 0;
1326#endif
1327 possible = num_processors + additional_cpus; 1325 possible = num_processors + additional_cpus;
1328 if (possible > NR_CPUS) 1326 if (possible > NR_CPUS)
1329 possible = NR_CPUS; 1327 possible = NR_CPUS;