traps.c 4.8 KB

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