Merge with Linux 2.4.0-test5-pre3.
[linux-2.6/linux-mips.git] / arch / arm / kernel / traps.c
blobc76a95736aa7f0e77d9ca7c64661b60190e69a3d
1 /*
2 * linux/arch/arm/kernel/traps.c
4 * Copyright (C) 1995, 1996 Russell King
5 * Fragments that appear the same as linux/arch/i386/kernel/traps.c (C) Linus Torvalds
6 */
8 /*
9 * 'traps.c' handles hardware exceptions after we have saved some state in
10 * 'linux/arch/arm/lib/traps.S'. Mostly a debugging aid, but will probably
11 * kill the offending process.
13 #include <linux/config.h>
14 #include <linux/types.h>
15 #include <linux/kernel.h>
16 #include <linux/signal.h>
17 #include <linux/sched.h>
18 #include <linux/mm.h>
19 #include <linux/spinlock.h>
20 #include <linux/ptrace.h>
21 #include <linux/init.h>
23 #include <asm/atomic.h>
24 #include <asm/io.h>
25 #include <asm/pgtable.h>
26 #include <asm/system.h>
27 #include <asm/uaccess.h>
29 #include "ptrace.h"
31 extern void c_backtrace (unsigned long fp, int pmode);
33 char *processor_modes[]=
34 { "USER_26", "FIQ_26" , "IRQ_26" , "SVC_26" , "UK4_26" , "UK5_26" , "UK6_26" , "UK7_26" ,
35 "UK8_26" , "UK9_26" , "UK10_26", "UK11_26", "UK12_26", "UK13_26", "UK14_26", "UK15_26",
36 "USER_32", "FIQ_32" , "IRQ_32" , "SVC_32" , "UK4_32" , "UK5_32" , "UK6_32" , "ABT_32" ,
37 "UK8_32" , "UK9_32" , "UK10_32", "UND_32" , "UK12_32", "UK13_32", "UK14_32", "SYS_32"
40 static const char *handler[]= { "prefetch abort", "data abort", "address exception", "interrupt" };
42 static inline void console_verbose(void)
44 extern int console_loglevel;
45 console_loglevel = 15;
49 * Stack pointers should always be within the kernels view of
50 * physical memory. If it is not there, then we can't dump
51 * out any information relating to the stack.
53 static int verify_stack(unsigned long sp)
55 if (sp < PAGE_OFFSET || sp > (unsigned long)high_memory)
56 return -EFAULT;
58 return 0;
62 * Dump out the contents of some memory nicely...
64 void dump_mem(unsigned long bottom, unsigned long top)
66 unsigned long p = bottom & ~31;
67 int i;
69 for (p = bottom & ~31; p < top;) {
70 printk("%08lx: ", p);
72 for (i = 0; i < 8; i++, p += 4) {
73 if (p < bottom || p >= top)
74 printk(" ");
75 else
76 printk("%08lx ", *(unsigned long *)p);
77 if (i == 3)
78 printk(" ");
80 printk ("\n");
85 * These constants are for searching for possible module text
86 * segments. VMALLOC_OFFSET comes from mm/vmalloc.c; MODULE_RANGE is
87 * a guess of how much space is likely to be vmalloced.
89 #define VMALLOC_OFFSET (8*1024*1024)
90 #define MODULE_RANGE (8*1024*1024)
92 static void dump_instr(unsigned long pc, int user)
94 int pmin = -2, pmax = 3, ok = 0;
95 extern char start_kernel, _etext;
97 if (!user) {
98 unsigned long module_start, module_end;
99 unsigned long kernel_start, kernel_end;
101 module_start = VMALLOC_START;
102 module_end = module_start + MODULE_RANGE;
104 kernel_start = (unsigned long)&start_kernel;
105 kernel_end = (unsigned long)&_etext;
107 if (pc >= kernel_start && pc < kernel_end) {
108 if (pc + pmin < kernel_start)
109 pmin = kernel_start - pc;
110 if (pc + pmax > kernel_end)
111 pmax = kernel_end - pc;
112 ok = 1;
113 } else if (pc >= module_start && pc < module_end) {
114 if (pc + pmin < module_start)
115 pmin = module_start - pc;
116 if (pc + pmax > module_end)
117 pmax = module_end - pc;
118 ok = 1;
120 } else
121 ok = verify_area(VERIFY_READ, (void *)(pc + pmin), pmax - pmin) == 0;
123 printk ("Code: ");
124 if (ok) {
125 int i;
126 for (i = pmin; i < pmax; i++)
127 printk(i == 0 ? "(%08lx) " : "%08lx ", ((unsigned long *)pc)[i]);
128 printk ("\n");
129 } else
130 printk ("pc not in code space\n");
133 spinlock_t die_lock = SPIN_LOCK_UNLOCKED;
136 * This function is protected against re-entrancy.
138 void die(const char *str, struct pt_regs *regs, int err)
140 struct task_struct *tsk = current;
142 spin_lock_irq(&die_lock);
144 console_verbose();
145 printk("Internal error: %s: %x\n", str, err);
146 printk("CPU: %d\n", smp_processor_id());
147 show_regs(regs);
148 printk("Process %s (pid: %d, stackpage=%08lx)\n",
149 current->comm, current->pid, 4096+(unsigned long)tsk);
151 if (!user_mode(regs)) {
152 unsigned long sp = (unsigned long)(regs + 1);
153 unsigned long fp;
154 int dump_info = 1;
156 printk("Stack: ");
157 if (verify_stack(sp)) {
158 printk("invalid kernel stack pointer %08lx", sp);
159 dump_info = 0;
160 } else if (sp < 4096+(unsigned long)tsk)
161 printk("kernel stack pointer underflow");
162 printk("\n");
164 if (dump_info)
165 dump_mem(sp - 16, 8192+(unsigned long)tsk);
167 dump_info = 1;
169 printk("Backtrace: ");
170 fp = regs->ARM_fp;
171 if (!fp) {
172 printk("no frame pointer");
173 dump_info = 0;
174 } else if (verify_stack(fp)) {
175 printk("invalid frame pointer %08lx", fp);
176 dump_info = 0;
177 } else if (fp < 4096+(unsigned long)tsk)
178 printk("frame pointer underflow");
179 printk("\n");
181 if (dump_info)
182 c_backtrace(fp, processor_mode(regs));
184 dump_instr(instruction_pointer(regs), 0);
187 spin_unlock_irq(&die_lock);
188 do_exit(SIGSEGV);
191 void die_if_kernel(const char *str, struct pt_regs *regs, int err)
193 if (user_mode(regs))
194 return;
196 die(str, regs, err);
199 asmlinkage void do_undefinstr(int address, struct pt_regs *regs, int mode)
201 unsigned long addr = instruction_pointer(regs);
202 siginfo_t info;
204 #ifdef CONFIG_DEBUG_USER
205 printk(KERN_INFO "%s (%d): undefined instruction: pc=%08lx\n",
206 current->comm, current->pid, addr);
207 #endif
209 current->thread.error_code = 0;
210 current->thread.trap_no = 6;
212 info.si_signo = SIGILL;
213 info.si_errno = 0;
214 info.si_code = ILL_ILLOPC;
215 info.si_addr = (void *)addr;
217 force_sig_info(SIGILL, &info, current);
219 die_if_kernel("Oops - undefined instruction", regs, mode);
222 asmlinkage void do_excpt(int address, struct pt_regs *regs, int mode)
224 siginfo_t info;
226 #ifdef CONFIG_DEBUG_USER
227 printk(KERN_INFO "%s (%d): address exception: pc=%08lx\n",
228 current->comm, current->pid, instruction_pointer(regs));
229 #endif
231 current->thread.error_code = 0;
232 current->thread.trap_no = 11;
234 info.si_signo = SIGBUS;
235 info.si_errno = 0;
236 info.si_code = BUS_ADRERR;
237 info.si_addr = (void *)address;
239 force_sig_info(SIGBUS, &info, current);
241 die_if_kernel("Oops - address exception", regs, mode);
244 asmlinkage void do_unexp_fiq (struct pt_regs *regs)
246 #ifndef CONFIG_IGNORE_FIQ
247 printk("Hmm. Unexpected FIQ received, but trying to continue\n");
248 printk("You may have a hardware problem...\n");
249 #endif
253 * bad_mode handles the impossible case in the vectors. If you see one of
254 * these, then it's extremely serious, and could mean you have buggy hardware.
255 * It never returns, and never tries to sync. We hope that we can at least
256 * dump out some state information...
258 asmlinkage void bad_mode(struct pt_regs *regs, int reason, int proc_mode)
260 console_verbose();
262 printk(KERN_CRIT "Bad mode in %s handler detected: mode %s\n",
263 handler[reason], processor_modes[proc_mode]);
266 * Dump out the vectors and stub routines. Maybe a better solution
267 * would be to dump them out only if we detect that they are corrupted.
269 printk(KERN_CRIT "Vectors:\n");
270 dump_mem(0, 0x40);
271 printk(KERN_CRIT "Stubs:\n");
272 dump_mem(0x200, 0x4b8);
274 die("Oops", regs, 0);
275 cli();
276 while(1);
280 * Handle some more esoteric system calls
282 asmlinkage int arm_syscall(int no, struct pt_regs *regs)
284 siginfo_t info;
286 switch (no) {
287 case 0: /* branch through 0 */
288 info.si_signo = SIGSEGV;
289 info.si_errno = 0;
290 info.si_code = SEGV_MAPERR;
291 info.si_addr = NULL;
293 force_sig_info(SIGSEGV, &info, current);
295 die_if_kernel("branch through zero", regs, 0);
296 break;
298 case 1: /* SWI BREAK_POINT */
300 * The PC is always left pointing at the next
301 * instruction. Fix this.
303 regs->ARM_pc -= 4;
304 __ptrace_cancel_bpt(current);
306 info.si_signo = SIGTRAP;
307 info.si_errno = 0;
308 info.si_code = TRAP_BRKPT;
309 info.si_addr = (void *)instruction_pointer(regs);
311 force_sig_info(SIGTRAP, &info, current);
312 return regs->ARM_r0;
314 case 2: /* sys_cacheflush */
315 #ifdef CONFIG_CPU_32
316 /* r0 = start, r1 = end, r2 = flags */
317 cpu_flush_cache_area(regs->ARM_r0, regs->ARM_r1, 1);
318 #endif
319 break;
321 default:
322 /* Calls 9f00xx..9f07ff are defined to return -ENOSYS
323 if not implemented, rather than raising SIGILL. This
324 way the calling program can gracefully determine whether
325 a feature is supported. */
326 if (no <= 0x7ff)
327 return -ENOSYS;
328 #ifdef CONFIG_DEBUG_USER
329 /* experience shows that these seem to indicate that
330 * something catastrophic has happened
332 printk("[%d] %s: arm syscall %d\n", current->pid, current->comm, no);
333 if (user_mode(regs)) {
334 show_regs(regs);
335 c_backtrace(regs->ARM_fp, processor_mode(regs));
337 #endif
338 force_sig(SIGILL, current);
339 die_if_kernel("Oops", regs, no);
340 break;
342 return 0;
345 asmlinkage void deferred(int n, struct pt_regs *regs)
347 /* You might think just testing `handler' would be enough, but PER_LINUX
348 * points it to no_lcall7 to catch undercover SVr4 binaries. Gutted.
350 if (current->personality != PER_LINUX && current->exec_domain->handler) {
351 /* Hand it off to iBCS. The extra parameter and consequent type
352 * forcing is necessary because of the weird ARM calling convention.
354 void (*handler)(int nr, struct pt_regs *regs) = (void *)current->exec_domain->handler;
355 (*handler)(n, regs);
356 return;
359 #ifdef CONFIG_DEBUG_USER
360 printk(KERN_ERR "[%d] %s: obsolete system call %08x.\n", current->pid,
361 current->comm, n);
362 #endif
363 force_sig(SIGILL, current);
364 die_if_kernel("Oops", regs, n);
367 void __bad_xchg(volatile void *ptr, int size)
369 printk("xchg: bad data size: pc 0x%p, ptr 0x%p, size %d\n",
370 __builtin_return_address(0), ptr, size);
371 BUG();
375 * A data abort trap was taken, but we did not handle the instruction.
376 * Try to abort the user program, or panic if it was the kernel.
378 asmlinkage void
379 baddataabort(int code, unsigned long instr, struct pt_regs *regs)
381 unsigned long addr = instruction_pointer(regs);
382 siginfo_t info;
384 #ifdef CONFIG_DEBUG_USER
385 dump_instr(addr, 1);
387 pgd_t *pgd;
389 pgd = pgd_offset(current->mm, addr);
390 printk ("*pgd = %08lx", pgd_val (*pgd));
391 if (!pgd_none (*pgd)) {
392 pmd_t *pmd;
393 pmd = pmd_offset (pgd, addr);
394 printk (", *pmd = %08lx", pmd_val (*pmd));
395 if (!pmd_none (*pmd))
396 printk (", *pte = %08lx", pte_val(*pte_offset (pmd, addr)));
398 printk ("\n");
400 #endif
402 info.si_signo = SIGILL;
403 info.si_errno = 0;
404 info.si_code = ILL_ILLOPC;
405 info.si_addr = (void *)addr;
407 force_sig_info(SIGILL, &info, current);
408 die_if_kernel("unknown data abort code", regs, instr);
411 void __bug(const char *file, int line, void *data)
413 printk(KERN_CRIT"kernel BUG at %s:%d!", file, line);
414 if (data)
415 printk(KERN_CRIT" - extra data = %p", data);
416 printk("\n");
417 BUG();
420 void __readwrite_bug(const char *fn)
422 printk("%s called, but not implemented", fn);
423 BUG();
426 void __pte_error(const char *file, int line, unsigned long val)
428 printk("%s:%d: bad pte %08lx.\n", file, line, val);
431 void __pmd_error(const char *file, int line, unsigned long val)
433 printk("%s:%d: bad pmd %08lx.\n", file, line, val);
436 void __pgd_error(const char *file, int line, unsigned long val)
438 printk("%s:%d: bad pgd %08lx.\n", file, line, val);
441 asmlinkage void __div0(void)
443 printk("Division by zero in kernel.\n");
444 __backtrace();
447 void abort(void)
449 void *lr = __builtin_return_address(0);
451 printk(KERN_CRIT "abort() called from %p! (Please "
452 "report to rmk@arm.linux.org.uk)\n", lr);
454 BUG();
456 /* if that doesn't kill us, halt */
457 panic("Oops failed to kill thread");
460 void __init trap_init(void)
462 extern void __trap_init(void);
464 __trap_init();
465 #ifdef CONFIG_CPU_32
466 modify_domain(DOMAIN_USER, DOMAIN_CLIENT);
467 #endif