
From: "Andi Kleen" <ak@suse.de>

Add reboot=force

reboot=force doesn't wait for any other CPUs on reboot.  This is useful when
you really need a system to reboot on its own.

Signed-off-by: Andi Kleen <ak@suse.de>
Signed-off-by: Andrew Morton <akpm@osdl.org>
---

 25-akpm/arch/x86_64/kernel/reboot.c |   37 ++++++++++++++++++++++--------------
 25-akpm/arch/x86_64/kernel/smp.c    |    3 ++
 25-akpm/include/asm-x86_64/proto.h  |    2 +
 3 files changed, 28 insertions(+), 14 deletions(-)

diff -puN arch/x86_64/kernel/reboot.c~x86_64-add-reboot=force arch/x86_64/kernel/reboot.c
--- 25/arch/x86_64/kernel/reboot.c~x86_64-add-reboot=force	2004-11-28 01:54:30.116018776 -0800
+++ 25-akpm/arch/x86_64/kernel/reboot.c	2004-11-28 01:54:30.123017712 -0800
@@ -26,12 +26,14 @@ static enum { 
 	BOOT_KBD = 'k'
 } reboot_type = BOOT_KBD;
 static int reboot_mode = 0;
+int reboot_force;
 
 /* reboot=t[riple] | k[bd] [, [w]arm | [c]old]
    warm   Don't set the cold reboot flag
    cold   Set the cold reboot flag
    triple Force a triple fault (init)
    kbd    Use the keyboard controller. cold reset (default)
+   force  Avoid anything that could hang.
  */ 
 static int __init reboot_setup(char *str)
 {
@@ -50,6 +52,9 @@ static int __init reboot_setup(char *str
 		case 'k':
 			reboot_type = *str;
 			break;
+		case 'f':
+			reboot_force = 1;
+			break;
 		}
 		if((str = strchr(str,',')) != NULL)
 			str++;
@@ -65,12 +70,15 @@ __setup("reboot=", reboot_setup);
 static void smp_halt(void)
 {
 	int cpuid = safe_smp_processor_id(); 
-		static int first_entry = 1;
+	static int first_entry = 1;
+
+	if (reboot_force)
+		return;
 
-		if (first_entry) { 
-			first_entry = 0;
-			smp_call_function((void *)machine_restart, NULL, 1, 0);
-		} 
+	if (first_entry) {
+		first_entry = 0;
+		smp_call_function((void *)machine_restart, NULL, 1, 0);
+	}
 			
 	smp_stop_cpu(); 
 
@@ -99,19 +107,20 @@ void machine_restart(char * __unused)
 {
 	int i;
 
+	printk("machine restart\n");
+
 #ifdef CONFIG_SMP
 	smp_halt(); 
 #endif
 
-	local_irq_disable();
-       
+	if (!reboot_force) {
+		local_irq_disable();
 #ifndef CONFIG_SMP
-	disable_local_APIC();
+		disable_local_APIC();
 #endif
-
-	disable_IO_APIC();
-	
-	local_irq_enable();
+		disable_IO_APIC();
+		local_irq_enable();
+	}
 	
 	/* Tell the BIOS if we want cold or warm reboot */
 	*((unsigned short *)__va(0x472)) = reboot_mode;
@@ -128,8 +137,8 @@ void machine_restart(char * __unused)
 		}
 
 		case BOOT_TRIPLE: 
-		__asm__ __volatile__("lidt (%0)": :"r" (&no_idt));
-		__asm__ __volatile__("int3");
+			__asm__ __volatile__("lidt (%0)": :"r" (&no_idt));
+			__asm__ __volatile__("int3");
 
 			reboot_type = BOOT_KBD;
 			break;
diff -puN arch/x86_64/kernel/smp.c~x86_64-add-reboot=force arch/x86_64/kernel/smp.c
--- 25/arch/x86_64/kernel/smp.c~x86_64-add-reboot=force	2004-11-28 01:54:30.117018624 -0800
+++ 25-akpm/arch/x86_64/kernel/smp.c	2004-11-28 01:54:30.124017560 -0800
@@ -25,6 +25,7 @@
 #include <asm/pgalloc.h>
 #include <asm/tlbflush.h>
 #include <asm/mach_apic.h>
+#include <asm/proto.h>
 
 /*
  *	Smarter SMP flushing macros. 
@@ -361,6 +362,8 @@ static void smp_really_stop_cpu(void *du
 void smp_send_stop(void)
 {
 	int nolock = 0;
+	if (reboot_force)
+		return;
 	/* Don't deadlock on the call lock in panic */
 	if (!spin_trylock(&call_lock)) {
 		/* ignore locking because we have paniced anyways */
diff -puN include/asm-x86_64/proto.h~x86_64-add-reboot=force include/asm-x86_64/proto.h
--- 25/include/asm-x86_64/proto.h~x86_64-add-reboot=force	2004-11-28 01:54:30.118018472 -0800
+++ 25-akpm/include/asm-x86_64/proto.h	2004-11-28 01:54:30.125017408 -0800
@@ -107,6 +107,8 @@ extern int iommu_aperture_allowed;
 extern int fix_aperture;
 extern int force_iommu;
 
+extern int reboot_force;
+
 extern void smp_local_timer_interrupt(struct pt_regs * regs);
 
 long do_arch_prctl(struct task_struct *task, int code, unsigned long addr);
_
