diff -ur kdb/kdb.h kdb-new/kdb.h
--- kdb/kdb.h	Wed May  1 21:46:10 2002
+++ kdb-new/kdb.h	Wed May  1 21:44:51 2002
@@ -113,8 +113,8 @@
 #define KDB_STATE_HOLD_CPU	0x00000010	/* Hold this cpu inside kdb */
 #define KDB_STATE_DOING_SS	0x00000020	/* Doing ss command */
 #define KDB_STATE_DOING_SSB	0x00000040	/* Doing ssb command, DOING_SS is also set */
-#define KDB_STATE_SSBPT		0x00000080	/* Install breakpoint after one ss, independent of DOING_SS */
-#define KDB_STATE_REENTRY	0x00000100	/* Valid re-entry into kdb */
+#define KDB_STATE_DOING_SSBPT	0x00000080	/* Doing go after breakpoint, DOING_SS set */
+#define KDB_STATE_NEED_SSBPT	0x00000100	/* If users says "go", need to do "ss" */
 #define KDB_STATE_SUPPRESS	0x00000200	/* Suppress error messages */
 #define KDB_STATE_LONGJMP	0x00000400	/* longjmp() data is available */
  /* Spare, was    NO_WATCHDOG	0x00000800 */
@@ -122,7 +122,6 @@
 #define KDB_STATE_WAIT_IPI	0x00002000	/* Waiting for kdb_ipi() NMI */
 #define KDB_STATE_RECURSE	0x00004000	/* Recursive entry to kdb */
 #define KDB_STATE_IP_ADJUSTED	0x00008000	/* Restart IP has been adjusted */
-#define KDB_STATE_NO_BP_DELAY	0x00010000	/* No need to delay breakpoints */
 #define KDB_STATE_ARCH		0xff000000	/* Reserved for arch specific use */
 
 #define KDB_STATE_CPU(flag,cpu)		(kdb_state[cpu] & KDB_STATE_##flag)
diff -ur kdb/kdb_bp.c kdb-new/kdb_bp.c
--- kdb/kdb_bp.c	Wed May  1 21:47:01 2002
+++ kdb-new/kdb_bp.c	Wed May  1 21:44:58 2002
@@ -50,13 +50,18 @@
 {
 	int i;
 
+	if (KDB_DEBUG(BP))
+		kdb_printf("kdb_bp_install_global cpu %d\n", smp_processor_id());
+	
 	for(i=0; i<KDB_MAXBPT; i++) {
-		if (KDB_DEBUG(BP)) {
-			kdb_printf("kdb_bp_install_global bp %d bp_enabled %d bp_global %d\n",
-				i, kdb_breakpoints[i].bp_enabled, kdb_breakpoints[i].bp_global);
-		}
 		if (kdb_breakpoints[i].bp_enabled
 		 && kdb_breakpoints[i].bp_global) {
+			if (KDB_DEBUG(BP)) {
+				kdb_printf("kdb_bp_install_global bp %d bp_enabled %d "
+					   "bp_global %d\n", i,
+					   kdb_breakpoints[i].bp_enabled,
+					   kdb_breakpoints[i].bp_global);
+			}
 			kdba_installbp(ef, &kdb_breakpoints[i]);
 		}
 	}
@@ -87,19 +92,22 @@
 kdb_bp_install_local(kdb_eframe_t ef)
 {
 	int i;
+	int cpu = smp_processor_id();
 
+	if (KDB_DEBUG(BP))
+		kdb_printf("kdb_bp_install_local cpu %d\n", cpu);
+	
 	for(i=0; i<KDB_MAXBPT; i++) {
-		if (KDB_DEBUG(BP)) {
-			kdb_printf("kdb_bp_install_local bp %d bp_enabled %d bp_global %d cpu %d bp_cpu %d\n",
-				i, kdb_breakpoints[i].bp_enabled, kdb_breakpoints[i].bp_global,
-				smp_processor_id(), kdb_breakpoints[i].bp_cpu);
-		}
-		if (KDB_STATE(NO_BP_DELAY)) {
-			kdb_breakpoints[i].bp_delay = 0;
-		}
 		if (kdb_breakpoints[i].bp_enabled
-		 && kdb_breakpoints[i].bp_cpu == smp_processor_id()
+		 && kdb_breakpoints[i].bp_cpu == cpu
 		 && !kdb_breakpoints[i].bp_global){
+			if (KDB_DEBUG(BP)) {
+				kdb_printf("kdb_bp_install_local bp %d bp_enabled %d "
+					   "bp_global %d cpu %d\n", i,
+					   kdb_breakpoints[i].bp_enabled,
+					   kdb_breakpoints[i].bp_global,
+					   cpu);
+			}
 			kdba_installbp(ef, &kdb_breakpoints[i]);
 		}
 	}
@@ -126,13 +134,18 @@
 {
 	int i;
 
+	if (KDB_DEBUG(BP))
+		kdb_printf("kdb_bp_remove_global cpu %d\n", smp_processor_id());
+
 	for(i=KDB_MAXBPT-1; i>=0; i--) {
-		if (KDB_DEBUG(BP)) {
-			kdb_printf("kdb_bp_remove_global bp %d bp_enabled %d bp_global %d\n",
-				i, kdb_breakpoints[i].bp_enabled, kdb_breakpoints[i].bp_global);
-		}
 		if (kdb_breakpoints[i].bp_enabled
 		 && kdb_breakpoints[i].bp_global) {
+			if (KDB_DEBUG(BP)) {
+				kdb_printf("kdb_bp_remove_global bp %d bp_enabled %d "
+					   "bp_global %d\n", i,
+					   kdb_breakpoints[i].bp_enabled,
+					   kdb_breakpoints[i].bp_global);
+			}
 			kdba_removebp(&kdb_breakpoints[i]);
 		}
 	}
@@ -158,17 +171,21 @@
 void
 kdb_bp_remove_local(void)
 {
-	int i;
+	int i, cpu = smp_processor_id();
+
+	if (KDB_DEBUG(BP))
+		kdb_printf("kdb_bp_remove_local cpu %d\n", cpu);
 
 	for(i=KDB_MAXBPT-1; i>=0; i--) {
-		if (KDB_DEBUG(BP)) {
-			kdb_printf("kdb_bp_remove_local bp %d bp_enabled %d bp_global %d cpu %d bp_cpu %d\n",
-				i, kdb_breakpoints[i].bp_enabled, kdb_breakpoints[i].bp_global,
-				smp_processor_id(), kdb_breakpoints[i].bp_cpu);
-		}
 		if (kdb_breakpoints[i].bp_enabled
 		 && kdb_breakpoints[i].bp_cpu == smp_processor_id()
 		 && !kdb_breakpoints[i].bp_global){
+			if (KDB_DEBUG(BP)) {
+				kdb_printf("kdb_bp_remove_local bp %d bp_enabled %d "
+					   "bp_global %d cpu %d\n", i,
+					   kdb_breakpoints[i].bp_enabled,
+					   kdb_breakpoints[i].bp_global, cpu);
+			}
 			kdba_removebp(&kdb_breakpoints[i]);
 		}
 	}
diff -ur kdb/kdbmain.c kdb-new/kdbmain.c
--- kdb/kdbmain.c	Wed May  1 21:46:37 2002
+++ kdb-new/kdbmain.c	Wed May  1 21:45:01 2002
@@ -1024,6 +1024,8 @@
 	      kdb_dbtrap_t db_result, kdb_eframe_t ef)
 {
 	int result = 1;
+	int cpu = smp_processor_id();
+	
 	/* Stay in kdb() until 'go', 'ss[b]' or an error */
 	while (1) {
 		int i;
@@ -1036,11 +1038,28 @@
 			;
 		KDB_STATE_CLEAR(SUPPRESS);
 		KDB_DEBUG_STATE("kdb_main_loop 2", reason);
-		if (KDB_STATE(LEAVING))
-			break;	/* Another cpu said 'go' */
 
+		/*
+		 * When the user says "go", if kdb_initial_cpu is running,
+		 * it will set LEAVING for all the CPUs to tell them that
+		 * they may exit kdb. If the user says "go", but another
+		 * CPU is running, that CPU will set LEAVING only in
+		 * kdb_initial_cpu's state, and then it will switch to
+		 * kdb_initial_cpu, who then exits as if "go" had been
+		 * issued to kdb_initial_cpu directly.
+		 */
+
+		if (KDB_STATE(LEAVING)) {
+			if (cpu == kdb_initial_cpu) {
+				KDB_STATE_CLEAR(LEAVING);
+				result = KDB_CMD_GO;
+				goto got_result;
+			}
+			break;	/* Another cpu said 'go' */
+		}
 		/* Still using kdb, this processor is in control */
 		result = kdb_local(reason2, error, ef, db_result);
+got_result:
 		KDB_DEBUG_STATE("kdb_main_loop 3", result);
 
 		if (result == KDB_CMD_CPU) {
@@ -1062,20 +1081,37 @@
 			break;
 		}
 
+		if (KDB_STATE(NEED_SSBPT) && result == KDB_CMD_GO) {
+			KDB_DEBUG_STATE("kdb_main_loop 4a", reason);
+			KDB_STATE_SET(DOING_SS);
+			KDB_STATE_SET(DOING_SSBPT);
+			kdba_setsinglestep(ef);
+			break;
+		}
+
 		if (result && result != 1 && result != KDB_CMD_GO)
 			kdb_printf("\nUnexpected kdb_local return code %d\n", result);
 
 		/*
 		 * All other return codes (including KDB_CMD_GO) from
-		 * kdb_local will end kdb().  Release all other cpus
-		 * which will see KDB_STATE(LEAVING) is set.
+		 * kdb_local will end kdb().
+		 * 
+		 * If we are not the initial CPU, set its LEAVING and
+		 * switch to it. Once it has installed the global breakpoints,
+		 * it'll release all other cpus.
 		 */
-		for (i = 0; i < NR_CPUS; ++i) {
+
+		if (cpu != kdb_initial_cpu) {
+			KDB_STATE_SET(HOLD_CPU);
+			KDB_STATE_SET_CPU(LEAVING, kdb_initial_cpu);
+			KDB_STATE_CLEAR_CPU(HOLD_CPU, kdb_initial_cpu);
+			continue;
+		}
+
+		for (i = 0; i < NR_CPUS; ++i)
 			if (KDB_STATE_CPU(KDB, i))
 				KDB_STATE_SET_CPU(LEAVING, i);
-			KDB_STATE_CLEAR_CPU(WAIT_IPI, i);
-			KDB_STATE_CLEAR_CPU(HOLD_CPU, i);
-		}
+		
 		KDB_DEBUG_STATE("kdb_main_loop 4", reason);
 		break;
 	}
@@ -1110,6 +1146,8 @@
  *	the cpu is allowed to do one instruction which causes a trap
  *	into kdb with KDB_REASON_DEBUG.
  *
+ *	[Note: sparc64 leaves interrupts disabled while single-stepping]
+ *
  * Inputs:
  *	reason		The reason KDB was invoked
  *	error		The hardware-defined error code
@@ -1203,58 +1241,30 @@
 int
 kdb(kdb_reason_t reason, int error, kdb_eframe_t ef)
 {
-	kdb_intstate_t	int_state;	/* Interrupt state */
+	u_long		flags;
 	kdb_reason_t	reason2 = reason;
 	int		result = 1;	/* Default is kdb handled it */
-	int		ss_event;
+	int		ss_event, reentry, i;
+	int		recursing, cpu = smp_processor_id();
 	kdb_dbtrap_t 	db_result=KDB_DB_NOBPT;
 
 	if (!kdb_on)
 		return 0;
 
 	KDB_DEBUG_STATE("kdb 1", reason);
-	KDB_STATE_CLEAR(SUPPRESS);
 
-	/* Filter out userspace breakpoints first, no point in doing all
-	 * the kdb smp fiddling when it is really a gdb trap.
-	 * Save the single step status first, kdba_db_trap clears ss status.
+	/* kdb can validly reenter but only for certain well defined conditions.
+	 * If this is reentry, then it must have been impossible for another CPU
+	 * to have gotten control of KDB (ie. taken kdb_initial_cpu) between the
+	 * the time when this CPU last exited KDB, and now as we are re-entering.
 	 */
-	ss_event = reason != KDB_REASON_PANIC && (KDB_STATE(DOING_SS) || KDB_STATE(SSBPT));
-	if (reason == KDB_REASON_BREAK)
-		db_result = kdba_bp_trap(ef, error);	/* Only call this once */
-	if (reason == KDB_REASON_DEBUG)
-		db_result = kdba_db_trap(ef, error);	/* Only call this once */
-
-	if ((reason == KDB_REASON_BREAK || reason == KDB_REASON_DEBUG)
-	 && db_result == KDB_DB_NOBPT) {
-		KDB_DEBUG_STATE("kdb 2", reason);
-		return 0;	/* Not one of mine */
-	}
 
-	/* Turn off single step if it was being used */
-	if (ss_event) {
-		kdba_clearsinglestep(ef);
-		/* Single step after a breakpoint removes the need for a delayed reinstall */
-		if (reason == KDB_REASON_BREAK || reason == KDB_REASON_DEBUG) {
-			KDB_STATE_SET(NO_BP_DELAY);
-		}
-	}
-
-	/* kdb can validly reenter but only for certain well defined conditions */
-	if (reason == KDB_REASON_DEBUG
-	 && !KDB_STATE(HOLD_CPU)
-	 && ss_event)
-		KDB_STATE_SET(REENTRY);
-	else
-		KDB_STATE_CLEAR(REENTRY);
-
-	/* Wait for previous kdb event to completely exit before starting
-	 * a new event.
-	 */
-	while (kdb_previous_event())
-		;
-	KDB_DEBUG_STATE("kdb 3", reason);
+	local_irq_save(flags);
 
+	ss_event = reason != KDB_REASON_PANIC && KDB_STATE(DOING_SS);
+	reentry = reason == KDB_REASON_DEBUG && !KDB_STATE(HOLD_CPU) && ss_event;
+	recursing = (kdb_initial_cpu == cpu);
+	
 	/*
 	 * If kdb is already active, print a message and try to recover.
 	 * If recovery is not possible and recursion is allowed or
@@ -1263,14 +1273,14 @@
 	 * debugging the debugger.
 	 */
 	if (reason != KDB_REASON_SWITCH) {
-		if (KDB_IS_RUNNING() && !KDB_STATE(REENTRY)) {
+		if (recursing && !reentry) {
 			int recover = 1;
 			unsigned long recurse = 0;
 			kdb_printf("kdb: Debugger re-entered on cpu %d, new reason = %d\n",
-				smp_processor_id(), reason);
+				cpu, reason);
 			/* Should only re-enter from released cpu */
 			if (KDB_STATE(HOLD_CPU)) {
-				kdb_printf("     Strange, cpu %d should not be running\n", smp_processor_id());
+				kdb_printf("     Strange, cpu %d should not be running\n", cpu);
 				recover = 0;
 			}
 			if (!KDB_STATE(CMD)) {
@@ -1289,7 +1299,7 @@
 			if (recover) {
 				kdb_printf("     Attempting to abort command and recover\n");
 #ifdef KDB_HAVE_LONGJMP
-				kdba_longjmp(&kdbjmpbuf[smp_processor_id()], 0);
+				kdba_longjmp(&kdbjmpbuf[cpu], 0);
 #endif
 			}
 			if (recurse) {
@@ -1298,36 +1308,26 @@
 				} else {
 					kdb_printf("     Attempting recursive mode\n");
 					KDB_STATE_SET(RECURSE);
-					KDB_STATE_SET(REENTRY);
+					reentry = 1;
 					reason2 = KDB_REASON_RECURSE;
 					recover = 1;
 				}
 			}
 			if (!recover) {
+				extern int kdb_rd(int, const char **, const char **, struct pt_regs *);
 				kdb_printf("     Cannot recover, allowing event to proceed\n");
+				kdb_rd(0, NULL, NULL, ef);
+				local_irq_restore(flags);
 				return(0);
 			}
 		}
 	} else if (!KDB_IS_RUNNING()) {
 		kdb_printf("kdb: CPU switch without kdb running, I'm confused\n");
+		local_irq_restore(flags);
 		return(0);
 	}
 
 	/*
-	 * Disable interrupts, breakpoints etc. on this processor
-	 * during kdb command processing
-	 */
-	KDB_STATE_SET(KDB);
-	kdba_disableint(&int_state);
-	if (!KDB_STATE(KDB_CONTROL)) {
-		kdb_bp_remove_local();
-		kdba_disable_lbr();
-		KDB_STATE_SET(KDB_CONTROL);
-	}
-	else if (KDB_DEBUG(LBR))
-		kdba_print_lbr();
-
-	/*
 	 * If not entering the debugger due to CPU switch or single step
 	 * reentry, serialize access here.
 	 * The processors may race getting to this point - if,
@@ -1338,11 +1338,10 @@
 	 * the initial processor releases the debugger, the rest of
 	 * the processors will race for it.
 	 */
-	if (reason == KDB_REASON_SWITCH
-	 || KDB_STATE(REENTRY))
-		;	/* drop through */
-	else {
-		KDB_DEBUG_STATE("kdb 4", reason);
+
+	if (reason != KDB_REASON_SWITCH && !reentry && !recursing)
+	{
+		KDB_DEBUG_STATE("kdb 2", reason);
 		spin_lock(&kdb_lock);
 
 		while (KDB_IS_RUNNING() || kdb_previous_event()) {
@@ -1353,14 +1352,55 @@
 
 			spin_lock(&kdb_lock);
 		}
-		KDB_DEBUG_STATE("kdb 5", reason);
+		KDB_DEBUG_STATE("kdb 3", reason);
 
-		kdb_initial_cpu = smp_processor_id();
+		kdb_initial_cpu = cpu;
 		spin_unlock(&kdb_lock);
 	}
 
-	if (smp_processor_id() == kdb_initial_cpu
-	 && !KDB_STATE(REENTRY)) {
+	KDB_STATE_CLEAR(SUPPRESS);
+
+	/* Filter out userspace breakpoints first, no point in doing all
+	 * the kdb smp fiddling when it is really a gdb trap.
+	 * Save the single step status first, kdba_db_trap clears ss status.
+	 */
+	if (reason == KDB_REASON_BREAK)
+		db_result = kdba_bp_trap(ef, error);	/* Only call this once */
+	if (reason == KDB_REASON_DEBUG)
+		db_result = kdba_db_trap(ef, error);	/* Only call this once */
+
+	if ((reason == KDB_REASON_BREAK || reason == KDB_REASON_DEBUG)
+	 && db_result == KDB_DB_NOBPT) {
+		KDB_DEBUG_STATE("kdb 4", reason);
+		local_irq_restore(flags);
+		return 0;	/* Not one of mine */
+	}
+
+	/* Turn off single step if it was being used */
+	if (ss_event)
+		kdba_clearsinglestep(ef);
+
+	/* Wait for previous kdb event to completely exit before starting
+	 * a new event.
+	 */
+	while (kdb_previous_event())
+		;
+	KDB_DEBUG_STATE("kdb 5", reason);
+
+	/*
+	 * Disable interrupts, breakpoints etc. on this processor
+	 * during kdb command processing
+	 */
+	KDB_STATE_SET(KDB);
+	if (!KDB_STATE(KDB_CONTROL)) {
+		kdb_bp_remove_local();
+		kdba_disable_lbr();
+		KDB_STATE_SET(KDB_CONTROL);
+	}
+	else if (KDB_DEBUG(LBR))
+		kdba_print_lbr();
+
+	if (cpu == kdb_initial_cpu && !reentry) {
 		KDB_STATE_CLEAR(HOLD_CPU);
 		KDB_STATE_CLEAR(WAIT_IPI);
 		/*
@@ -1399,41 +1439,44 @@
 	KDB_DEBUG_STATE("kdb 11", result);
 
 	/* No breakpoints installed for SS */
-	if (!KDB_STATE(DOING_SS) &&
-	    !KDB_STATE(SSBPT) &&
-	    !KDB_STATE(RECURSE)) {
+	if (!KDB_STATE(DOING_SS) && !KDB_STATE(RECURSE)) {
 		KDB_DEBUG_STATE("kdb 12", result);
 		kdba_enable_lbr();
 		kdb_bp_install_local(ef);
-		KDB_STATE_CLEAR(NO_BP_DELAY);
 		KDB_STATE_CLEAR(KDB_CONTROL);
 	}
 
 	KDB_DEBUG_STATE("kdb 13", result);
-	kdba_restoreint(&int_state);
 
 	KDB_STATE_CLEAR(KDB);		/* Main kdb state has been cleared */
 	KDB_STATE_CLEAR(LEAVING);	/* Elvis has left the building ... */
+	KDB_STATE_CLEAR(NEED_SSBPT);
 	KDB_DEBUG_STATE("kdb 14", result);
 
-	if (smp_processor_id() == kdb_initial_cpu &&
+	if (cpu == kdb_initial_cpu &&
 	  !KDB_STATE(DOING_SS) &&
 	  !KDB_STATE(RECURSE)) {
 		/*
 		 * (Re)install the global breakpoints.  This is only done
-		 * once from the initial processor on final exit.
+		 * once from the initial processor on final exit. Then
+		 * release the other CPUs.
 		 */
 		KDB_DEBUG_STATE("kdb 15", reason);
 		kdb_bp_install_global(ef);
+		for (i = 0; i < NR_CPUS; ++i) {
+			KDB_STATE_CLEAR_CPU(WAIT_IPI, i);
+			KDB_STATE_CLEAR_CPU(HOLD_CPU, i);
+		}
 		/* Wait until all the other processors leave kdb */
 		while (kdb_previous_event())
 			;
 		kdb_initial_cpu = -1;	/* release kdb control */
 		KDB_DEBUG_STATE("kdb 16", reason);
-	}
-
-	KDB_STATE_CLEAR(RECURSE);
+	} else
+		KDB_STATE_CLEAR(RECURSE);
 	KDB_DEBUG_STATE("kdb 17", reason);
+	
+	local_irq_restore(flags);
 	return(result != 0);
 }
 
diff -ur kdb/kdbprivate.h kdb-new/kdbprivate.h
--- kdb/kdbprivate.h	Wed May  1 21:46:22 2002
+++ kdb-new/kdbprivate.h	Wed May  1 21:53:10 2002
@@ -90,8 +90,6 @@
 	unsigned int	bp_hardtype:1;	/* Uses hardware register */
 	unsigned int	bp_forcehw:1;	/* Force hardware register */
 	unsigned int	bp_installed:1;	/* Breakpoint is installed */
-	unsigned int	bp_delay:1;	/* Do delayed bp handling */
-	unsigned int	bp_delayed:1;	/* Delayed breakpoint */
 
 	int		bp_cpu;		/* Cpu #  (if bp_global == 0) */
 	kdbhard_bp_t	bp_template;	/* Hardware breakpoint template */
@@ -168,6 +166,7 @@
 	unsigned long	setup;		/* Bytes allocated for setup data */
 } kdb_ar_t;
 
+#if defined(CONFIG_X86) || defined(CONFIG_IA64)
 	/* 
 	 * General Stack Traceback functions.
 	 */
@@ -176,6 +175,7 @@
 				     kdb_machreg_t, kdb_machreg_t,
 				     kdb_machreg_t,
 				     kdb_ar_t *, kdb_symtab_t *);
+#endif
 
 	/* 
 	 * Architecture specific Stack Traceback functions.
@@ -186,9 +186,11 @@
 extern int	     kdba_bt_stack(struct pt_regs *, kdb_machreg_t *, 
 				   int, struct task_struct *);
 extern int	     kdba_bt_process(struct task_struct *, int);
+#if defined(CONFIG_X86) || defined(CONFIG_IA64)
 extern int	     kdba_prologue(const kdb_symtab_t *, kdb_machreg_t,
 				   kdb_machreg_t, kdb_machreg_t, kdb_machreg_t,
 				   int, kdb_ar_t *);
+#endif
 	/*
 	 * KDB Command Table
 	 */
