diff -uNr linux-2.5.7/arch/i386/kernel/apic.c linux-2.5.7.kexec.reboot/arch/i386/kernel/apic.c
--- linux-2.5.7/arch/i386/kernel/apic.c	Sun Mar 10 20:09:08 2002
+++ linux-2.5.7.kexec.reboot/arch/i386/kernel/apic.c	Sat Mar 30 09:47:45 2002
@@ -23,6 +23,7 @@
 #include <linux/interrupt.h>
 #include <linux/mc146818rtc.h>
 #include <linux/kernel_stat.h>
+#include <linux/reboot.h>
 
 #include <asm/atomic.h>
 #include <asm/smp.h>
@@ -37,6 +38,13 @@
 int prof_old_multiplier[NR_CPUS] = { 1, };
 int prof_counter[NR_CPUS] = { 1, };
 
+static int apic_reboot_event(struct notifier_block *,unsigned long,void *);
+static struct notifier_block apic_reboot_notifier = {
+	apic_reboot_event,
+	NULL,
+	-1000, /* This should be the very last reboot notifier to run */
+};
+
 int get_maxlvt(void)
 {
 	unsigned int v, ver, maxlvt;
@@ -111,6 +119,8 @@
 		outb(0x70, 0x22);
 		outb(0x01, 0x23);
 	}
+
+	register_reboot_notifier(&apic_reboot_notifier);
 }
 
 void disconnect_bsp_APIC(void)
@@ -126,6 +136,36 @@
 		outb(0x70, 0x22);
 		outb(0x00, 0x23);
 	}
+	else {
+		/* Go back to Virtual Wire compatibility mode */
+		unsigned long value;
+
+		/* For the spurious interrupt use vector F, and enable it */
+		value = apic_read(APIC_SPIV);
+		value &= ~APIC_VECTOR_MASK; 
+		value |= APIC_SPIV_APIC_ENABLED;
+		value |= 0xf;
+		apic_write_around(APIC_SPIV, value);
+
+		/* For LVT0 make it edge triggered, active high, external and enabled */
+		value = apic_read(APIC_LVT0);
+		value &= ~(APIC_MODE_MASK | APIC_SEND_PENDING | 
+			APIC_INPUT_POLARITY | APIC_LVT_REMOTE_IRR | 
+			APIC_LVT_LEVEL_TRIGGER | APIC_LVT_MASKED );
+		value |= APIC_LVT_REMOTE_IRR | APIC_SEND_PENDING;
+		value = SET_APIC_DELIVERY_MODE(value, APIC_MODE_EXINT);
+		apic_write_around(APIC_LVT0, value);
+		
+		/* For LVT1 make it edge triggered, active high, nmi and enabled */
+		value = apic_read(APIC_LVT1);
+		value &= ~(
+			APIC_MODE_MASK | APIC_SEND_PENDING | 
+			APIC_INPUT_POLARITY | APIC_LVT_REMOTE_IRR | 
+			APIC_LVT_LEVEL_TRIGGER | APIC_LVT_MASKED);
+		value |= APIC_LVT_REMOTE_IRR | APIC_SEND_PENDING;
+		value = SET_APIC_DELIVERY_MODE(value, APIC_MODE_NMI);
+		apic_write_around(APIC_LVT1, value);
+	}
 }
 
 void disable_local_APIC(void)
@@ -654,6 +694,7 @@
 void __init init_apic_mappings(void)
 {
 	unsigned long apic_phys;
+	unsigned long value;
 
 	/*
 	 * If no local APIC can be found then set up a fake all
@@ -1124,6 +1165,35 @@
 	*/
 	printk (KERN_ERR "APIC error on CPU%d: %02lx(%02lx)\n",
 	        smp_processor_id(), v , v1);
+}
+
+static int apic_reboot_event(struct notifier_block *n, 
+	unsigned long code, void *p) 
+{
+	if ((code != SYS_RESTART) && (code != SYS_HALT) && 
+		(code != SYS_POWER_OFF)) {
+		return NOTIFY_DONE;
+	}
+
+	/* By resetting the APIC's we disable the nmi watchdog */
+
+#if CONFIG_SMP
+	/*
+	 * Stop all CPUs and turn off local APICs, so
+	 * other OSs see a clean IRQ state.
+	 */
+	smp_send_stop();
+#else
+	disable_local_APIC();
+#endif
+#if defined(CONFIG_X86_IO_APIC)
+	if (smp_found_config) {
+		disable_IO_APIC();
+	}
+#endif
+	disconnect_bsp_APIC();
+
+	return NOTIFY_DONE;
 }
 
 /*
diff -uNr linux-2.5.7/arch/i386/kernel/dmi_scan.c linux-2.5.7.kexec.reboot/arch/i386/kernel/dmi_scan.c
--- linux-2.5.7/arch/i386/kernel/dmi_scan.c	Wed Mar 20 07:18:31 2002
+++ linux-2.5.7.kexec.reboot/arch/i386/kernel/dmi_scan.c	Sat Mar 30 09:47:45 2002
@@ -226,31 +226,6 @@
 	return 0;
 }
 
-/*
- * Some machines require the "reboot=s"  commandline option, this quirk makes that automatic.
- */
-static __init int set_smp_reboot(struct dmi_blacklist *d)
-{
-#ifdef CONFIG_SMP
-	extern int reboot_smp;
-	if (reboot_smp == 0)
-	{
-		reboot_smp = 1;
-		printk(KERN_INFO "%s series board detected. Selecting SMP-method for reboots.\n", d->ident);
-	}
-#endif
-	return 0;
-}
-
-/*
- * Some machines require the "reboot=b,s"  commandline option, this quirk makes that automatic.
- */
-static __init int set_smp_bios_reboot(struct dmi_blacklist *d)
-{
-	set_smp_reboot(d);
-	set_bios_reboot(d);
-	return 0;
-}
 
 /*
  * Some bioses have a broken protected mode poweroff and need to use realmode
@@ -502,7 +477,7 @@
 			MATCH(DMI_BIOS_VERSION, "4.60 PGMA"),
 			MATCH(DMI_BIOS_DATE, "134526184"), NO_MATCH
 			} },
-	{ set_smp_bios_reboot, "Dell PowerEdge 1300", {	/* Handle problems with rebooting on Dell 1300's */
+	{ set_bios_reboot, "Dell PowerEdge 1300", {	/* Handle problems with rebooting on Dell 1300's */
 			MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"),
 			MATCH(DMI_PRODUCT_NAME, "PowerEdge 1300/"),
 			NO_MATCH, NO_MATCH
diff -uNr linux-2.5.7/arch/i386/kernel/io_apic.c linux-2.5.7.kexec.reboot/arch/i386/kernel/io_apic.c
--- linux-2.5.7/arch/i386/kernel/io_apic.c	Sun Mar 10 20:09:08 2002
+++ linux-2.5.7.kexec.reboot/arch/i386/kernel/io_apic.c	Sat Mar 30 09:47:45 2002
@@ -1012,8 +1012,6 @@
 	 * Clear the IO-APIC before rebooting:
 	 */
 	clear_IO_APIC();
-
-	disconnect_bsp_APIC();
 }
 
 /*
diff -uNr linux-2.5.7/arch/i386/kernel/process.c linux-2.5.7.kexec.reboot/arch/i386/kernel/process.c
--- linux-2.5.7/arch/i386/kernel/process.c	Sun Mar 10 20:08:33 2002
+++ linux-2.5.7.kexec.reboot/arch/i386/kernel/process.c	Sat Mar 30 09:47:45 2002
@@ -165,8 +165,7 @@
 int reboot_thru_bios;
 
 #ifdef CONFIG_SMP
-int reboot_smp = 0;
-static int reboot_cpu = -1;
+int reboot_cpu = -1;  /* specifies the internal linux cpu id, not the apicid */
 /* shamelessly grabbed from lib/vsprintf.c for readability */
 #define is_digit(c)	((c) >= '0' && (c) <= '9')
 #endif
@@ -188,7 +187,6 @@
 			break;
 #ifdef CONFIG_SMP
 		case 's': /* "smp" reboot by executing reset on BSP or other CPU*/
-			reboot_smp = 1;
 			if (is_digit(*(str+1))) {
 				reboot_cpu = (int) (*(str+1) - '0');
 				if (is_digit(*(str+2))) 
@@ -374,43 +372,6 @@
 
 void machine_restart(char * __unused)
 {
-#if CONFIG_SMP
-	int cpuid;
-	
-	cpuid = GET_APIC_ID(apic_read(APIC_ID));
-
-	if (reboot_smp) {
-
-		/* check to see if reboot_cpu is valid 
-		   if its not, default to the BSP */
-		if ((reboot_cpu == -1) ||  
-		      (reboot_cpu > (NR_CPUS -1))  || 
-		      !(phys_cpu_present_map & (1<<cpuid))) 
-			reboot_cpu = boot_cpu_physical_apicid;
-
-		reboot_smp = 0;  /* use this as a flag to only go through this once*/
-		/* re-run this function on the other CPUs
-		   it will fall though this section since we have 
-		   cleared reboot_smp, and do the reboot if it is the
-		   correct CPU, otherwise it halts. */
-		if (reboot_cpu != cpuid)
-			smp_call_function((void *)machine_restart , NULL, 1, 0);
-	}
-
-	/* if reboot_cpu is still -1, then we want a tradional reboot, 
-	   and if we are not running on the reboot_cpu,, halt */
-	if ((reboot_cpu != -1) && (cpuid != reboot_cpu)) {
-		for (;;)
-		__asm__ __volatile__ ("hlt");
-	}
-	/*
-	 * Stop all CPUs and turn off local APICs and the IO-APIC, so
-	 * other OSs see a clean IRQ state.
-	 */
-	smp_send_stop();
-	disable_IO_APIC();
-#endif
-
 	if(!reboot_thru_bios) {
 		/* rebooting needs to touch the page at absolute addr 0 */
 		*((unsigned short *)__va(0x472)) = reboot_mode;
diff -uNr linux-2.5.7/arch/i386/kernel/smp.c linux-2.5.7.kexec.reboot/arch/i386/kernel/smp.c
--- linux-2.5.7/arch/i386/kernel/smp.c	Sun Mar 10 20:09:08 2002
+++ linux-2.5.7.kexec.reboot/arch/i386/kernel/smp.c	Sat Mar 30 09:47:45 2002
@@ -592,6 +592,32 @@
 
 void smp_send_stop(void)
 {
+	extern int reboot_cpu;
+	int reboot_cpu_id;
+
+ 	/* The boot cpu is always logical cpu 0 */
+	reboot_cpu_id = 0;
+
+	/* See if there has been give a command line override 
+	 * We leave off validity checking until late because
+	 * the command line is parsed before 
+	 */
+	if ((reboot_cpu != -1) && !(reboot_cpu >= NR_CPUS) && 
+		test_bit(reboot_cpu, &cpu_online_map)) {
+		reboot_cpu_id = reboot_cpu;
+	}
+	 
+	/* Make certain the the cpu I'm rebooting on is online */
+	if (!test_bit(reboot_cpu_id, &cpu_online_map)) {
+		reboot_cpu_id = smp_processor_id();
+	}
+
+	/* Make certain I only run on the appropriate processor */
+	set_cpus_allowed(current, 1 << reboot_cpu_id);
+
+	/* O.k. Now that I'm on the appropriate processor stop
+	 * all of the others.
+	 */
 	smp_call_function(stop_this_cpu, NULL, 1, 0);
 	smp_num_cpus = 1;
 
diff -uNr linux-2.5.7/include/asm-i386/apicdef.h linux-2.5.7.kexec.reboot/include/asm-i386/apicdef.h
--- linux-2.5.7/include/asm-i386/apicdef.h	Sun Aug 12 12:13:59 2001
+++ linux-2.5.7.kexec.reboot/include/asm-i386/apicdef.h	Sat Mar 30 09:47:45 2002
@@ -85,6 +85,7 @@
 #define			APIC_LVT_REMOTE_IRR		(1<<14)
 #define			APIC_INPUT_POLARITY		(1<<13)
 #define			APIC_SEND_PENDING		(1<<12)
+#define			APIC_MODE_MASK			0x700
 #define			GET_APIC_DELIVERY_MODE(x)	(((x)>>8)&0x7)
 #define			SET_APIC_DELIVERY_MODE(x,y)	(((x)&~0x700)|((y)<<8))
 #define				APIC_MODE_FIXED		0x0
