patch-2.4.22 linux-2.4.22/arch/ppc64/kernel/traps.c

Next file: linux-2.4.22/arch/ppc64/kernel/xics.c
Previous file: linux-2.4.22/arch/ppc64/kernel/time.c
Back to the patch index
Back to the overall index

diff -urN linux-2.4.21/arch/ppc64/kernel/traps.c linux-2.4.22/arch/ppc64/kernel/traps.c
@@ -42,6 +42,7 @@
 #include <asm/io.h>
 #include <asm/processor.h>
 #include <asm/ppcdebug.h>
+#include <asm/machdep.h> /* for ppc_attention_msg */
 
 extern int fix_alignment(struct pt_regs *);
 extern void bad_page_fault(struct pt_regs *, unsigned long);
@@ -75,14 +76,11 @@
 void (*debugger_fault_handler)(struct pt_regs *regs);
 #else
 #ifdef CONFIG_KDB
-/* kdb has different call parms */
-/* ... */
-void (*debugger)(struct pt_regs *regs) = kdb;
+void (*debugger)(struct pt_regs *regs);
 int (*debugger_bpt)(struct pt_regs *regs);
 int (*debugger_sstep)(struct pt_regs *regs);
 int (*debugger_iabr_match)(struct pt_regs *regs);
-int (*debugger_dabr_match)(struct pt_regs *regs) = kdb;
-/* - only defined during (xmon) mread */
+int (*debugger_dabr_match)(struct pt_regs *regs);
 void (*debugger_fault_handler)(struct pt_regs *regs);
 #endif /* kdb */
 #endif /* kgdb */
@@ -100,13 +98,9 @@
 	if (!user_mode(regs))
 	{
 		show_regs(regs);
-#if defined(CONFIG_XMON) || defined(CONFIG_KGDB)
+#if defined(CONFIG_XMON) || defined(CONFIG_KGDB) || defined(CONFIG_KDB)
 		debugger(regs);
 #endif
-#if defined(CONFIG_KDB)
-		if (kdb(KDB_REASON_BREAK, 0, (kdb_eframe_t) regs))
-		    return;
-#endif
 		print_backtrace((unsigned long *)regs->gpr[1]);
 		panic("Exception in kernel pc %lx signal %d",regs->nip,signr);
 #if defined(CONFIG_PPCDBG) && (defined(CONFIG_XMON) || defined(CONFIG_KGDB))
@@ -164,30 +158,11 @@
 	}
 #if defined(CONFIG_XMON)
 	xmon(regs);
-	udbg_printf("leaving xmon...\n");
+	if (smp_processor_id() == 0)
+		udbg_printf("leaving xmon...\n");
 #endif
 #if defined(CONFIG_KDB)
-	{
-		int cpu = smp_processor_id();
-		static int reset_cpu = -1;
-		static spinlock_t reset_lock = SPIN_LOCK_UNLOCKED;
-
-		/* Give kdb some help serializing the reset */
-		spin_lock(&reset_lock);
-		if (reset_cpu == -1) {
-			reset_cpu = cpu;
-			spin_unlock(&reset_lock);
-			kdb(KDB_REASON_ENTER, regs->trap, (kdb_eframe_t) regs);
-			reset_cpu = -1;
-		} else {
-			spin_unlock(&reset_lock);
-			/* Let kdb catch this cpu with an IPI.
-			 * Ideally we need a way to enter kdb w/o it becoming
-			 * confused so we can precisely capture reset state.
-			 */
-			return;
-		}
-	}
+	kdb_reset_debugger(regs);
 #endif
 }
 
@@ -195,7 +170,6 @@
 void
 MachineCheckException(struct pt_regs *regs)
 {
-	siginfo_t info;
 
 	if (fwnmi_active) {
 		struct rtas_error_log *errhdr = FWNMI_get_errinfo(regs);
@@ -205,54 +179,31 @@
 		FWNMI_release_errinfo();
 	}
 
-	if ( !user_mode(regs) ) {
-#if defined(CONFIG_XMON) || defined(CONFIG_KGDB)
-		if (debugger_fault_handler) {
-			debugger_fault_handler(regs);
-			return;
-		}
-#endif
-		printk("Machine check in kernel mode.\n");
-		printk("Caused by (from SRR1=%lx): ", regs->msr);
-		show_regs(regs);
 #if defined(CONFIG_XMON) || defined(CONFIG_KGDB)
-		debugger(regs);
+	if (debugger_fault_handler) {
+		debugger_fault_handler(regs);
+		return;
+	}
 #endif
-#ifdef CONFIG_KDB
-		if (kdb(KDB_REASON_FAULT, 0, regs))
-			return ;
+	printk(KERN_EMERG "Unrecoverable Machine check.\n");
+	printk(KERN_EMERG "Caused by (from SRR1=%lx): ", regs->msr);
+	show_regs(regs);
+#if defined(CONFIG_XMON) || defined(CONFIG_KGDB) || defined(CONFIG_KDB)
+	debugger(regs);
 #endif
-		print_backtrace((unsigned long *)regs->gpr[1]);
-		panic("machine check");
-	}
-	
-	/*
-	 * XXX we should check RI bit on exception exit and kill the
-	 * task if it was cleared
-	 */
-	info.si_signo = SIGBUS;
-	info.si_errno = 0;
-	info.si_code = BUS_ADRERR;
-	info.si_addr = (void *)regs->nip;
-	_exception(SIGSEGV, &info, regs);
-
+	print_backtrace((unsigned long *)regs->gpr[1]);
+	panic("machine check");
 }
 
 void
 SMIException(struct pt_regs *regs)
 {
-#if defined(CONFIG_XMON) || defined(CONFIG_KGDB)
+#if defined(CONFIG_XMON) || defined(CONFIG_KGDB) || defined(CONFIG_KDB)
 	{
 		debugger(regs);
 		return;
 	}
 #endif
-#ifdef CONFIG_KDB
-	{
-		kdb(KDB_REASON_OOPS, 0, regs);
-		return;
-	}
-#endif
 	show_regs(regs);
 	print_backtrace((unsigned long *)regs->gpr[1]);
 	panic("System Management Interrupt");
@@ -278,15 +229,10 @@
 {
 	siginfo_t info;
 	
-#if defined(CONFIG_XMON) || defined(CONFIG_KGDB)
+#if defined(CONFIG_XMON) || defined(CONFIG_KGDB) || defined (CONFIG_KDB)
 	if (debugger_iabr_match(regs))
 		return;
 #endif
-#ifdef CONFIG_KDB
-	if (kdb(KDB_REASON_BREAK, 0, regs))
-		return;
-#endif
-
 	info.si_signo = SIGTRAP;
 	info.si_errno = 0;
 	info.si_code = TRAP_BRKPT;
@@ -353,14 +299,10 @@
 	} else if (regs->msr & 0x20000) {
 		/* trap exception */
 
-#if defined(CONFIG_XMON) || defined(CONFIG_KGDB)
+#if defined(CONFIG_XMON) || defined(CONFIG_KGDB) || defined(CONFIG_KDB)
 		if (debugger_bpt(regs))
 			return;
 #endif
-#ifdef CONFIG_KDB
-		if (kdb(KDB_REASON_BREAK, 0, regs))
-			return;
-#endif
 		info.si_signo = SIGTRAP;
 		info.si_errno = 0;
 		info.si_code = TRAP_BRKPT;
@@ -377,6 +319,14 @@
 	}
 }
 
+ void
+KernelFPUnavailableException(struct pt_regs *regs)
+{
+	printk("Illegal floating point used in kernel (task=0x%016lx, pc=0x%016lx, trap=0x%08x)\n",
+		current, regs->nip, regs->trap);
+	panic("Unrecoverable FP Unavailable Exception in Kernel");
+}
+
 void
 SingleStepException(struct pt_regs *regs)
 {
@@ -384,15 +334,10 @@
 
 	regs->msr &= ~MSR_SE;  /* Turn off 'trace' bit */
 
-#if defined(CONFIG_XMON) || defined(CONFIG_KGDB)
+#if defined(CONFIG_XMON) || defined(CONFIG_KGDB) || defined(CONFIG_KDB)
 	if (debugger_sstep(regs))
 		return;
 #endif
-#ifdef CONFIG_KDB
-	if (kdb(KDB_REASON_DEBUG, 0, regs))
-		return;
-#endif
-
 	info.si_signo = SIGTRAP;
 	info.si_errno = 0;
 	info.si_code = TRAP_TRACE;

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