traps.c 1.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. #include <linux/bug.h>
  2. #include <linux/io.h>
  3. #include <linux/types.h>
  4. #include <linux/kdebug.h>
  5. #include <linux/signal.h>
  6. #include <linux/sched.h>
  7. #include <asm/system.h>
  8. #ifdef CONFIG_BUG
  9. static void handle_BUG(struct pt_regs *regs)
  10. {
  11. enum bug_trap_type tt;
  12. tt = report_bug(regs->pc, regs);
  13. if (tt == BUG_TRAP_TYPE_WARN) {
  14. regs->pc += instruction_size(regs->pc);
  15. return;
  16. }
  17. die("Kernel BUG", regs, TRAPA_BUG_OPCODE & 0xff);
  18. }
  19. int is_valid_bugaddr(unsigned long addr)
  20. {
  21. return addr >= PAGE_OFFSET;
  22. }
  23. #endif
  24. /*
  25. * Generic trap handler.
  26. */
  27. BUILD_TRAP_HANDLER(debug)
  28. {
  29. TRAP_HANDLER_DECL;
  30. /* Rewind */
  31. regs->pc -= instruction_size(ctrl_inw(regs->pc - 4));
  32. if (notify_die(DIE_TRAP, "debug trap", regs, 0, vec & 0xff,
  33. SIGTRAP) == NOTIFY_STOP)
  34. return;
  35. force_sig(SIGTRAP, current);
  36. }
  37. /*
  38. * Special handler for BUG() traps.
  39. */
  40. BUILD_TRAP_HANDLER(bug)
  41. {
  42. TRAP_HANDLER_DECL;
  43. /* Rewind */
  44. regs->pc -= instruction_size(ctrl_inw(regs->pc - 4));
  45. if (notify_die(DIE_TRAP, "bug trap", regs, 0, TRAPA_BUG_OPCODE & 0xff,
  46. SIGTRAP) == NOTIFY_STOP)
  47. return;
  48. #ifdef CONFIG_BUG
  49. if (__kernel_text_address(instruction_pointer(regs))) {
  50. opcode_t insn = *(opcode_t *)instruction_pointer(regs);
  51. if (insn == TRAPA_BUG_OPCODE)
  52. handle_BUG(regs);
  53. }
  54. #endif
  55. force_sig(SIGTRAP, current);
  56. }