- struct siginfo si;
-
- switch(iir) {
- case 0x00:
-#ifdef PRINT_USER_FAULTS
- printk(KERN_DEBUG "break 0,0: pid=%d command='%s'\n",
- current->pid, current->comm);
-#endif
- die_if_kernel("Breakpoint", regs, 0);
-#ifdef PRINT_USER_FAULTS
- show_regs(regs);
-#endif
- si.si_code = TRAP_BRKPT;
- si.si_addr = (void __user *) (regs->iaoq[0] & ~3);
- si.si_signo = SIGTRAP;
- force_sig_info(SIGTRAP, &si, current);
- break;
-
- case GDB_BREAK_INSN:
- die_if_kernel("Breakpoint", regs, 0);
- handle_gdb_break(regs, TRAP_BRKPT);
- break;
+ unsigned iir = regs->iir;
+
+ if (unlikely(iir == PARISC_BUG_BREAK_INSN && !user_mode(regs))) {
+ /* check if a BUG() or WARN() trapped here. */
+ enum bug_trap_type tt;
+ tt = report_bug(regs->iaoq[0] & ~3);
+ if (tt == BUG_TRAP_TYPE_WARN) {
+ regs->iaoq[0] += 4;
+ regs->iaoq[1] += 4;
+ return; /* return to next instruction when WARN_ON(). */
+ }
+ die_if_kernel("Unknown kernel breakpoint", regs,
+ (tt == BUG_TRAP_TYPE_NONE) ? 9 : 0);
+ }