aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/kernel/cpu/common.c27
-rw-r--r--arch/x86/kernel/smpboot.c99
2 files changed, 79 insertions, 47 deletions
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index a4bcbacdbe0b..a135239badb7 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -1221,17 +1221,6 @@ static void dbg_restore_debug_regs(void)
1221#define dbg_restore_debug_regs() 1221#define dbg_restore_debug_regs()
1222#endif /* ! CONFIG_KGDB */ 1222#endif /* ! CONFIG_KGDB */
1223 1223
1224static void wait_for_master_cpu(int cpu)
1225{
1226 /*
1227 * wait for ACK from master CPU before continuing
1228 * with AP initialization
1229 */
1230 WARN_ON(cpumask_test_and_set_cpu(cpu, cpu_initialized_mask));
1231 while (!cpumask_test_cpu(cpu, cpu_callout_mask))
1232 cpu_relax();
1233}
1234
1235/* 1224/*
1236 * cpu_init() initializes state that is per-CPU. Some data is already 1225 * cpu_init() initializes state that is per-CPU. Some data is already
1237 * initialized (naturally) in the bootstrap process, such as the GDT 1226 * initialized (naturally) in the bootstrap process, such as the GDT
@@ -1247,17 +1236,16 @@ void cpu_init(void)
1247 struct task_struct *me; 1236 struct task_struct *me;
1248 struct tss_struct *t; 1237 struct tss_struct *t;
1249 unsigned long v; 1238 unsigned long v;
1250 int cpu = stack_smp_processor_id(); 1239 int cpu;
1251 int i; 1240 int i;
1252 1241
1253 wait_for_master_cpu(cpu);
1254
1255 /* 1242 /*
1256 * Load microcode on this cpu if a valid microcode is available. 1243 * Load microcode on this cpu if a valid microcode is available.
1257 * This is early microcode loading procedure. 1244 * This is early microcode loading procedure.
1258 */ 1245 */
1259 load_ucode_ap(); 1246 load_ucode_ap();
1260 1247
1248 cpu = stack_smp_processor_id();
1261 t = &per_cpu(init_tss, cpu); 1249 t = &per_cpu(init_tss, cpu);
1262 oist = &per_cpu(orig_ist, cpu); 1250 oist = &per_cpu(orig_ist, cpu);
1263 1251
@@ -1269,6 +1257,9 @@ void cpu_init(void)
1269 1257
1270 me = current; 1258 me = current;
1271 1259
1260 if (cpumask_test_and_set_cpu(cpu, cpu_initialized_mask))
1261 panic("CPU#%d already initialized!\n", cpu);
1262
1272 pr_debug("Initializing CPU#%d\n", cpu); 1263 pr_debug("Initializing CPU#%d\n", cpu);
1273 1264
1274 clear_in_cr4(X86_CR4_VME|X86_CR4_PVI|X86_CR4_TSD|X86_CR4_DE); 1265 clear_in_cr4(X86_CR4_VME|X86_CR4_PVI|X86_CR4_TSD|X86_CR4_DE);
@@ -1345,10 +1336,14 @@ void cpu_init(void)
1345 struct tss_struct *t = &per_cpu(init_tss, cpu); 1336 struct tss_struct *t = &per_cpu(init_tss, cpu);
1346 struct thread_struct *thread = &curr->thread; 1337 struct thread_struct *thread = &curr->thread;
1347 1338
1348 wait_for_master_cpu(cpu);
1349
1350 show_ucode_info_early(); 1339 show_ucode_info_early();
1351 1340
1341 if (cpumask_test_and_set_cpu(cpu, cpu_initialized_mask)) {
1342 printk(KERN_WARNING "CPU#%d already initialized!\n", cpu);
1343 for (;;)
1344 local_irq_enable();
1345 }
1346
1352 printk(KERN_INFO "Initializing CPU#%d\n", cpu); 1347 printk(KERN_INFO "Initializing CPU#%d\n", cpu);
1353 1348
1354 if (cpu_has_vme || cpu_has_tsc || cpu_has_de) 1349 if (cpu_has_vme || cpu_has_tsc || cpu_has_de)
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
index bc52fac39dd3..ae2fd975b782 100644
--- a/arch/x86/kernel/smpboot.c
+++ b/arch/x86/kernel/smpboot.c
@@ -111,6 +111,7 @@ atomic_t init_deasserted;
111static void smp_callin(void) 111static void smp_callin(void)
112{ 112{
113 int cpuid, phys_id; 113 int cpuid, phys_id;
114 unsigned long timeout;
114 115
115 /* 116 /*
116 * If waken up by an INIT in an 82489DX configuration 117 * If waken up by an INIT in an 82489DX configuration
@@ -129,6 +130,37 @@ static void smp_callin(void)
129 * (This works even if the APIC is not enabled.) 130 * (This works even if the APIC is not enabled.)
130 */ 131 */
131 phys_id = read_apic_id(); 132 phys_id = read_apic_id();
133 if (cpumask_test_cpu(cpuid, cpu_callin_mask)) {
134 panic("%s: phys CPU#%d, CPU#%d already present??\n", __func__,
135 phys_id, cpuid);
136 }
137 pr_debug("CPU#%d (phys ID: %d) waiting for CALLOUT\n", cpuid, phys_id);
138
139 /*
140 * STARTUP IPIs are fragile beasts as they might sometimes
141 * trigger some glue motherboard logic. Complete APIC bus
142 * silence for 1 second, this overestimates the time the
143 * boot CPU is spending to send the up to 2 STARTUP IPIs
144 * by a factor of two. This should be enough.
145 */
146
147 /*
148 * Waiting 2s total for startup (udelay is not yet working)
149 */
150 timeout = jiffies + 2*HZ;
151 while (time_before(jiffies, timeout)) {
152 /*
153 * Has the boot CPU finished it's STARTUP sequence?
154 */
155 if (cpumask_test_cpu(cpuid, cpu_callout_mask))
156 break;
157 cpu_relax();
158 }
159
160 if (!time_before(jiffies, timeout)) {
161 panic("%s: CPU%d started up but did not get a callout!\n",
162 __func__, cpuid);
163 }
132 164
133 /* 165 /*
134 * the boot CPU has finished the init stage and is spinning 166 * the boot CPU has finished the init stage and is spinning
@@ -718,8 +750,8 @@ static int do_boot_cpu(int apicid, int cpu, struct task_struct *idle)
718 unsigned long start_ip = real_mode_header->trampoline_start; 750 unsigned long start_ip = real_mode_header->trampoline_start;
719 751
720 unsigned long boot_error = 0; 752 unsigned long boot_error = 0;
753 int timeout;
721 int cpu0_nmi_registered = 0; 754 int cpu0_nmi_registered = 0;
722 unsigned long timeout;
723 755
724 /* Just in case we booted with a single CPU. */ 756 /* Just in case we booted with a single CPU. */
725 alternatives_enable_smp(); 757 alternatives_enable_smp();
@@ -767,15 +799,6 @@ static int do_boot_cpu(int apicid, int cpu, struct task_struct *idle)
767 } 799 }
768 800
769 /* 801 /*
770 * AP might wait on cpu_callout_mask in cpu_init() with
771 * cpu_initialized_mask set if previous attempt to online
772 * it timed-out. Clear cpu_initialized_mask so that after
773 * INIT/SIPI it could start with a clean state.
774 */
775 cpumask_clear_cpu(cpu, cpu_initialized_mask);
776 smp_mb();
777
778 /*
779 * Wake up a CPU in difference cases: 802 * Wake up a CPU in difference cases:
780 * - Use the method in the APIC driver if it's defined 803 * - Use the method in the APIC driver if it's defined
781 * Otherwise, 804 * Otherwise,
@@ -787,41 +810,55 @@ static int do_boot_cpu(int apicid, int cpu, struct task_struct *idle)
787 boot_error = wakeup_cpu_via_init_nmi(cpu, start_ip, apicid, 810 boot_error = wakeup_cpu_via_init_nmi(cpu, start_ip, apicid,
788 &cpu0_nmi_registered); 811 &cpu0_nmi_registered);
789 812
790
791 if (!boot_error) { 813 if (!boot_error) {
792 /* 814 /*
793 * Wait 10s total for a response from AP 815 * allow APs to start initializing.
794 */ 816 */
795 boot_error = -1; 817 pr_debug("Before Callout %d\n", cpu);
796 timeout = jiffies + 10*HZ; 818 cpumask_set_cpu(cpu, cpu_callout_mask);
797 while (time_before(jiffies, timeout)) { 819 pr_debug("After Callout %d\n", cpu);
798 if (cpumask_test_cpu(cpu, cpu_initialized_mask)) {
799 /*
800 * Tell AP to proceed with initialization
801 */
802 cpumask_set_cpu(cpu, cpu_callout_mask);
803 boot_error = 0;
804 break;
805 }
806 udelay(100);
807 schedule();
808 }
809 }
810 820
811 if (!boot_error) {
812 /* 821 /*
813 * Wait till AP completes initial initialization 822 * Wait 5s total for a response
814 */ 823 */
815 while (!cpumask_test_cpu(cpu, cpu_callin_mask)) { 824 for (timeout = 0; timeout < 50000; timeout++) {
825 if (cpumask_test_cpu(cpu, cpu_callin_mask))
826 break; /* It has booted */
827 udelay(100);
816 /* 828 /*
817 * Allow other tasks to run while we wait for the 829 * Allow other tasks to run while we wait for the
818 * AP to come online. This also gives a chance 830 * AP to come online. This also gives a chance
819 * for the MTRR work(triggered by the AP coming online) 831 * for the MTRR work(triggered by the AP coming online)
820 * to be completed in the stop machine context. 832 * to be completed in the stop machine context.
821 */ 833 */
822 udelay(100);
823 schedule(); 834 schedule();
824 } 835 }
836
837 if (cpumask_test_cpu(cpu, cpu_callin_mask)) {
838 print_cpu_msr(&cpu_data(cpu));
839 pr_debug("CPU%d: has booted.\n", cpu);
840 } else {
841 boot_error = 1;
842 if (*trampoline_status == 0xA5A5A5A5)
843 /* trampoline started but...? */
844 pr_err("CPU%d: Stuck ??\n", cpu);
845 else
846 /* trampoline code not run */
847 pr_err("CPU%d: Not responding\n", cpu);
848 if (apic->inquire_remote_apic)
849 apic->inquire_remote_apic(apicid);
850 }
851 }
852
853 if (boot_error) {
854 /* Try to put things back the way they were before ... */
855 numa_remove_cpu(cpu); /* was set by numa_add_cpu */
856
857 /* was set by do_boot_cpu() */
858 cpumask_clear_cpu(cpu, cpu_callout_mask);
859
860 /* was set by cpu_init() */
861 cpumask_clear_cpu(cpu, cpu_initialized_mask);
825 } 862 }
826 863
827 /* mark "stuck" area as not stuck */ 864 /* mark "stuck" area as not stuck */