traps.c 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. /*
  2. * linux/arch/cris/traps.c
  3. *
  4. * Here we handle the break vectors not used by the system call
  5. * mechanism, as well as some general stack/register dumping
  6. * things.
  7. *
  8. * Copyright (C) 2000-2007 Axis Communications AB
  9. *
  10. * Authors: Bjorn Wesen
  11. * Hans-Peter Nilsson
  12. *
  13. */
  14. #include <linux/init.h>
  15. #include <linux/module.h>
  16. #include <asm/pgtable.h>
  17. #include <asm/uaccess.h>
  18. extern void arch_enable_nmi(void);
  19. extern void stop_watchdog(void);
  20. extern void reset_watchdog(void);
  21. extern void show_registers(struct pt_regs *regs);
  22. #ifdef CONFIG_DEBUG_BUGVERBOSE
  23. extern void handle_BUG(struct pt_regs *regs);
  24. #else
  25. #define handle_BUG(regs)
  26. #endif
  27. static int kstack_depth_to_print = 24;
  28. void (*nmi_handler)(struct pt_regs *);
  29. void
  30. show_trace(unsigned long *stack)
  31. {
  32. unsigned long addr, module_start, module_end;
  33. extern char _stext, _etext;
  34. int i;
  35. printk("\nCall Trace: ");
  36. i = 1;
  37. module_start = VMALLOC_START;
  38. module_end = VMALLOC_END;
  39. while (((long)stack & (THREAD_SIZE-1)) != 0) {
  40. if (__get_user(addr, stack)) {
  41. /* This message matches "failing address" marked
  42. s390 in ksymoops, so lines containing it will
  43. not be filtered out by ksymoops. */
  44. printk("Failing address 0x%lx\n", (unsigned long)stack);
  45. break;
  46. }
  47. stack++;
  48. /*
  49. * If the address is either in the text segment of the
  50. * kernel, or in the region which contains vmalloc'ed
  51. * memory, it *may* be the address of a calling
  52. * routine; if so, print it so that someone tracing
  53. * down the cause of the crash will be able to figure
  54. * out the call path that was taken.
  55. */
  56. if (((addr >= (unsigned long)&_stext) &&
  57. (addr <= (unsigned long)&_etext)) ||
  58. ((addr >= module_start) && (addr <= module_end))) {
  59. if (i && ((i % 8) == 0))
  60. printk("\n ");
  61. printk("[<%08lx>] ", addr);
  62. i++;
  63. }
  64. }
  65. }
  66. /*
  67. * These constants are for searching for possible module text
  68. * segments. MODULE_RANGE is a guess of how much space is likely
  69. * to be vmalloced.
  70. */
  71. #define MODULE_RANGE (8*1024*1024)
  72. /*
  73. * The output (format, strings and order) is adjusted to be usable with
  74. * ksymoops-2.4.1 with some necessary CRIS-specific patches. Please don't
  75. * change it unless you're serious about adjusting ksymoops and syncing
  76. * with the ksymoops maintainer.
  77. */
  78. void
  79. show_stack(struct task_struct *task, unsigned long *sp)
  80. {
  81. unsigned long *stack, addr;
  82. int i;
  83. /*
  84. * debugging aid: "show_stack(NULL);" prints a
  85. * back trace.
  86. */
  87. if (sp == NULL) {
  88. if (task)
  89. sp = (unsigned long*)task->thread.ksp;
  90. else
  91. sp = (unsigned long*)rdsp();
  92. }
  93. stack = sp;
  94. printk("\nStack from %08lx:\n ", (unsigned long)stack);
  95. for (i = 0; i < kstack_depth_to_print; i++) {
  96. if (((long)stack & (THREAD_SIZE-1)) == 0)
  97. break;
  98. if (i && ((i % 8) == 0))
  99. printk("\n ");
  100. if (__get_user(addr, stack)) {
  101. /* This message matches "failing address" marked
  102. s390 in ksymoops, so lines containing it will
  103. not be filtered out by ksymoops. */
  104. printk("Failing address 0x%lx\n", (unsigned long)stack);
  105. break;
  106. }
  107. stack++;
  108. printk("%08lx ", addr);
  109. }
  110. show_trace(sp);
  111. }
  112. #if 0
  113. /* displays a short stack trace */
  114. int
  115. show_stack(void)
  116. {
  117. unsigned long *sp = (unsigned long *)rdusp();
  118. int i;
  119. printk("Stack dump [0x%08lx]:\n", (unsigned long)sp);
  120. for (i = 0; i < 16; i++)
  121. printk("sp + %d: 0x%08lx\n", i*4, sp[i]);
  122. return 0;
  123. }
  124. #endif
  125. void
  126. dump_stack(void)
  127. {
  128. show_stack(NULL, NULL);
  129. }
  130. EXPORT_SYMBOL(dump_stack);
  131. void
  132. set_nmi_handler(void (*handler)(struct pt_regs *))
  133. {
  134. nmi_handler = handler;
  135. arch_enable_nmi();
  136. }
  137. #ifdef CONFIG_DEBUG_NMI_OOPS
  138. void
  139. oops_nmi_handler(struct pt_regs *regs)
  140. {
  141. stop_watchdog();
  142. oops_in_progress = 1;
  143. printk("NMI!\n");
  144. show_registers(regs);
  145. oops_in_progress = 0;
  146. }
  147. static int __init
  148. oops_nmi_register(void)
  149. {
  150. set_nmi_handler(oops_nmi_handler);
  151. return 0;
  152. }
  153. __initcall(oops_nmi_register);
  154. #endif
  155. /*
  156. * This gets called from entry.S when the watchdog has bitten. Show something
  157. * similiar to an Oops dump, and if the kernel is configured to be a nice
  158. * doggy, then halt instead of reboot.
  159. */
  160. void
  161. watchdog_bite_hook(struct pt_regs *regs)
  162. {
  163. #ifdef CONFIG_ETRAX_WATCHDOG_NICE_DOGGY
  164. local_irq_disable();
  165. stop_watchdog();
  166. show_registers(regs);
  167. while (1)
  168. ; /* Do nothing. */
  169. #else
  170. show_registers(regs);
  171. #endif
  172. }
  173. /* This is normally the Oops function. */
  174. void
  175. die_if_kernel(const char *str, struct pt_regs *regs, long err)
  176. {
  177. if (user_mode(regs))
  178. return;
  179. #ifdef CONFIG_ETRAX_WATCHDOG_NICE_DOGGY
  180. /*
  181. * This printout might take too long and could trigger
  182. * the watchdog normally. If NICE_DOGGY is set, simply
  183. * stop the watchdog during the printout.
  184. */
  185. stop_watchdog();
  186. #endif
  187. handle_BUG(regs);
  188. printk("%s: %04lx\n", str, err & 0xffff);
  189. show_registers(regs);
  190. oops_in_progress = 0;
  191. #ifdef CONFIG_ETRAX_WATCHDOG_NICE_DOGGY
  192. reset_watchdog();
  193. #endif
  194. do_exit(SIGSEGV);
  195. }
  196. void __init
  197. trap_init(void)
  198. {
  199. /* Nothing needs to be done */
  200. }