From 63dc68a8cf60cb110b147dab1704d990808b39e2 Mon Sep 17 00:00:00 2001
From: Ralf Baechle <ralf@linux-mips.org>
Date: Mon, 16 Oct 2006 01:38:50 +0100
Subject: [PATCH] [MIPS] Use conditional traps for BUG_ON on MIPS II and
 better.

This shaves of around 4kB and a few cycles for the average kernel that
has CONFIG_BUG enabled.

Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
---
 arch/mips/kernel/traps.c  | 14 ++++++++++----
 include/asm-mips/bug.h    | 12 ++++++++++++
 include/asm-mips/ptrace.h |  2 --
 3 files changed, 22 insertions(+), 6 deletions(-)

diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index 0ae19e1fa867..2a932cada244 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -669,8 +669,6 @@ asmlinkage void do_bp(struct pt_regs *regs)
 	unsigned int opcode, bcode;
 	siginfo_t info;
 
-	die_if_kernel("Break instruction in kernel code", regs);
-
 	if (get_user(opcode, (unsigned int __user *) exception_epc(regs)))
 		goto out_sigsegv;
 
@@ -693,6 +691,7 @@ asmlinkage void do_bp(struct pt_regs *regs)
 	switch (bcode) {
 	case BRK_OVERFLOW << 10:
 	case BRK_DIVZERO << 10:
+		die_if_kernel("Break instruction in kernel code", regs);
 		if (bcode == (BRK_DIVZERO << 10))
 			info.si_code = FPE_INTDIV;
 		else
@@ -702,7 +701,11 @@ asmlinkage void do_bp(struct pt_regs *regs)
 		info.si_addr = (void __user *) regs->cp0_epc;
 		force_sig_info(SIGFPE, &info, current);
 		break;
+	case BRK_BUG:
+		die("Kernel bug detected", regs);
+		break;
 	default:
+		die_if_kernel("Break instruction in kernel code", regs);
 		force_sig(SIGTRAP, current);
 	}
 
@@ -715,8 +718,6 @@ asmlinkage void do_tr(struct pt_regs *regs)
 	unsigned int opcode, tcode = 0;
 	siginfo_t info;
 
-	die_if_kernel("Trap instruction in kernel code", regs);
-
 	if (get_user(opcode, (unsigned int __user *) exception_epc(regs)))
 		goto out_sigsegv;
 
@@ -733,6 +734,7 @@ asmlinkage void do_tr(struct pt_regs *regs)
 	switch (tcode) {
 	case BRK_OVERFLOW:
 	case BRK_DIVZERO:
+		die_if_kernel("Trap instruction in kernel code", regs);
 		if (tcode == BRK_DIVZERO)
 			info.si_code = FPE_INTDIV;
 		else
@@ -742,7 +744,11 @@ asmlinkage void do_tr(struct pt_regs *regs)
 		info.si_addr = (void __user *) regs->cp0_epc;
 		force_sig_info(SIGFPE, &info, current);
 		break;
+	case BRK_BUG:
+		die("Kernel bug detected", regs);
+		break;
 	default:
+		die_if_kernel("Trap instruction in kernel code", regs);
 		force_sig(SIGTRAP, current);
 	}
 
diff --git a/include/asm-mips/bug.h b/include/asm-mips/bug.h
index 7b4739dc8f3f..4d560a533940 100644
--- a/include/asm-mips/bug.h
+++ b/include/asm-mips/bug.h
@@ -1,6 +1,7 @@
 #ifndef __ASM_BUG_H
 #define __ASM_BUG_H
 
+#include <asm/sgidefs.h>
 
 #ifdef CONFIG_BUG
 
@@ -13,6 +14,17 @@ do {									\
 
 #define HAVE_ARCH_BUG
 
+#if (_MIPS_ISA > _MIPS_ISA_MIPS1)
+
+#define BUG_ON(condition)						\
+do {									\
+	__asm__ __volatile__("tne $0, %0" : : "r" (condition));		\
+} while (0)
+
+#define HAVE_ARCH_BUG_ON
+
+#endif /* _MIPS_ISA > _MIPS_ISA_MIPS1 */
+
 #endif
 
 #include <asm-generic/bug.h>
diff --git a/include/asm-mips/ptrace.h b/include/asm-mips/ptrace.h
index 5f3a9075cd28..30bf555faeaa 100644
--- a/include/asm-mips/ptrace.h
+++ b/include/asm-mips/ptrace.h
@@ -80,8 +80,6 @@ struct pt_regs {
 #define instruction_pointer(regs) ((regs)->cp0_epc)
 #define profile_pc(regs) instruction_pointer(regs)
 
-extern void show_regs(struct pt_regs *);
-
 extern asmlinkage void do_syscall_trace(struct pt_regs *regs, int entryexit);
 
 #endif
-- 
GitLab