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