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