patch-2.4.0-test2 linux/arch/i386/kernel/smpboot.c

Next file: linux/arch/i386/kernel/time.c
Previous file: linux/arch/i386/kernel/signal.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.4.0-test1/linux/arch/i386/kernel/smpboot.c linux/arch/i386/kernel/smpboot.c
@@ -344,12 +344,22 @@
 
 extern void calibrate_delay(void);
 
+static atomic_t init_deasserted;
+
 void __init smp_callin(void)
 {
 	int cpuid, phys_id;
 	unsigned long timeout;
 
 	/*
+	 * If waken up by an INIT in an 82489DX configuration
+	 * we may get here before an INIT-deassert IPI reaches
+	 * our local APIC.  We have to wait for the IPI or we'll
+	 * lock up on an APIC access.
+	 */
+	while (!atomic_read(&init_deasserted));
+
+	/*
 	 * (This works even if the APIC is not enabled.)
 	 */
 	phys_id = GET_APIC_ID(apic_read(APIC_ID));
@@ -573,6 +583,8 @@
 	 * the targeted processor.
 	 */
 
+	atomic_set(&init_deasserted, 0);
+
 	Dprintk("Setting warm reset code and vector.\n");
 
 	CMOS_WRITE(0xa, 0xf);
@@ -642,6 +654,8 @@
 		send_status = apic_read(APIC_ICR) & APIC_ICR_BUSY;
 	} while (send_status && (timeout++ < 1000));
 
+	atomic_set(&init_deasserted, 1);
+
 	/*
 	 * Should we send STARTUP IPIs ?
 	 *
@@ -869,14 +883,6 @@
 		phys_cpu_present_map |= (1 << hard_smp_processor_id());
 	}
 
-	/*
-	 * If SMP should be disabled, then really disable it!
-	 */
-	if (!max_cpus) {
-		smp_found_config = 0;
-		printk(KERN_INFO "SMP mode deactivated, forcing use of dummy APIC emulation.\n");
-	}
-
 	{
 		int reg;
 
@@ -912,6 +918,20 @@
 		Dprintk("Getting LVT1: %x\n", reg);
 	}
 
+	/*
+	 * If SMP should be disabled, then really disable it!
+	 */
+	if (!max_cpus) {
+		smp_found_config = 0;
+		printk(KERN_INFO "SMP mode deactivated, forcing use of dummy APIC emulation.\n");
+#ifndef CONFIG_VISWS
+		io_apic_irqs = 0;
+#endif
+		cpu_online_map = phys_cpu_present_map = 1;
+		smp_num_cpus = 1;
+		goto smp_done;
+	}
+
 	connect_bsp_APIC();
 	setup_local_APIC();
 
@@ -998,7 +1018,6 @@
 		setup_IO_APIC();
 #endif
 
-smp_done:
 	/*
 	 * Set up all local APIC timers in the system:
 	 */
@@ -1010,6 +1029,7 @@
 	if (cpu_has_tsc && cpucount)
 		synchronize_tsc_bp();
 
+smp_done:
 	zap_low_mappings();
 }
 

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)