traps.c 5.1 KB

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