traps.c 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. /*
  2. * Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu>
  3. * Copyright (C) 2007-2009 PetaLogix
  4. * Copyright (C) 2006 Atmark Techno, Inc.
  5. *
  6. * This file is subject to the terms and conditions of the GNU General Public
  7. * License. See the file "COPYING" in the main directory of this archive
  8. * for more details.
  9. */
  10. #include <linux/kernel.h>
  11. #include <linux/kallsyms.h>
  12. #include <linux/module.h>
  13. #include <linux/sched.h>
  14. #include <linux/debug_locks.h>
  15. #include <asm/exceptions.h>
  16. #include <asm/system.h>
  17. void trap_init(void)
  18. {
  19. __enable_hw_exceptions();
  20. }
  21. static int kstack_depth_to_print = 24;
  22. static int __init kstack_setup(char *s)
  23. {
  24. kstack_depth_to_print = strict_strtoul(s, 0, NULL);
  25. return 1;
  26. }
  27. __setup("kstack=", kstack_setup);
  28. void show_trace(struct task_struct *task, unsigned long *stack)
  29. {
  30. unsigned long addr;
  31. if (!stack)
  32. stack = (unsigned long *)&stack;
  33. printk(KERN_NOTICE "Call Trace: ");
  34. #ifdef CONFIG_KALLSYMS
  35. printk(KERN_NOTICE "\n");
  36. #endif
  37. while (!kstack_end(stack)) {
  38. addr = *stack++;
  39. /*
  40. * If the address is either in the text segment of the
  41. * kernel, or in the region which contains vmalloc'ed
  42. * memory, it *may* be the address of a calling
  43. * routine; if so, print it so that someone tracing
  44. * down the cause of the crash will be able to figure
  45. * out the call path that was taken.
  46. */
  47. if (kernel_text_address(addr))
  48. print_ip_sym(addr);
  49. }
  50. printk(KERN_NOTICE "\n");
  51. if (!task)
  52. task = current;
  53. debug_show_held_locks(task);
  54. }
  55. void show_stack(struct task_struct *task, unsigned long *sp)
  56. {
  57. unsigned long *stack;
  58. int i;
  59. if (sp == NULL) {
  60. if (task)
  61. sp = (unsigned long *) ((struct thread_info *)
  62. (task->stack))->cpu_context.r1;
  63. else
  64. sp = (unsigned long *)&sp;
  65. }
  66. stack = sp;
  67. printk(KERN_INFO "\nStack:\n ");
  68. for (i = 0; i < kstack_depth_to_print; i++) {
  69. if (kstack_end(sp))
  70. break;
  71. if (i && ((i % 8) == 0))
  72. printk("\n ");
  73. printk("%08lx ", *sp++);
  74. }
  75. printk("\n");
  76. show_trace(task, stack);
  77. }
  78. void dump_stack(void)
  79. {
  80. show_stack(NULL, NULL);
  81. }
  82. EXPORT_SYMBOL(dump_stack);
  83. #ifdef CONFIG_MMU
  84. void __bug(const char *file, int line, void *data)
  85. {
  86. if (data)
  87. printk(KERN_CRIT "kernel BUG at %s:%d (data = %p)!\n",
  88. file, line, data);
  89. else
  90. printk(KERN_CRIT "kernel BUG at %s:%d!\n", file, line);
  91. machine_halt();
  92. }
  93. int bad_trap(int trap_num, struct pt_regs *regs)
  94. {
  95. printk(KERN_CRIT
  96. "unimplemented trap %d called at 0x%08lx, pid %d!\n",
  97. trap_num, regs->pc, current->pid);
  98. return -ENOSYS;
  99. }
  100. int debug_trap(struct pt_regs *regs)
  101. {
  102. int i;
  103. printk(KERN_CRIT "debug trap\n");
  104. for (i = 0; i < 32; i++) {
  105. /* printk("r%i:%08X\t",i,regs->gpr[i]); */
  106. if ((i % 4) == 3)
  107. printk(KERN_CRIT "\n");
  108. }
  109. printk(KERN_CRIT "pc:%08lX\tmsr:%08lX\n", regs->pc, regs->msr);
  110. return -ENOSYS;
  111. }
  112. #endif