1/* 2 * linux/arch/arm26/kernel/traps.c 3 * 4 * Copyright (C) 1995-2002 Russell King 5 * Fragments that appear the same as linux/arch/i386/kernel/traps.c (C) Linus Torvalds 6 * Copyright (C) 2003 Ian Molton (ARM26) 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License version 2 as 10 * published by the Free Software Foundation. 11 * 12 * 'traps.c' handles hardware exceptions after we have saved some state in 13 * 'linux/arch/arm26/lib/traps.S'. Mostly a debugging aid, but will probably 14 * kill the offending process. 15 */ 16 17#include <linux/module.h> 18#include <linux/types.h> 19#include <linux/kernel.h> 20#include <linux/signal.h> 21#include <linux/sched.h> 22#include <linux/mm.h> 23#include <linux/spinlock.h> 24#include <linux/personality.h> 25#include <linux/ptrace.h> 26#include <linux/elf.h> 27#include <linux/interrupt.h> 28#include <linux/init.h> 29 30#include <asm/atomic.h> 31#include <asm/io.h> 32#include <asm/pgtable.h> 33#include <asm/system.h> 34#include <asm/uaccess.h> 35#include <asm/unistd.h> 36#include <linux/mutex.h> 37 38#include "ptrace.h" 39 40extern void c_backtrace (unsigned long fp, int pmode); 41extern void show_pte(struct mm_struct *mm, unsigned long addr); 42 43const char *processor_modes[] = { "USER_26", "FIQ_26" , "IRQ_26" , "SVC_26" }; 44 45static const char *handler[]= { "prefetch abort", "data abort", "address exception", "interrupt" "*bad reason*"}; 46 47/* 48 * Stack pointers should always be within the kernels view of 49 * physical memory. If it is not there, then we can't dump 50 * out any information relating to the stack. 51 */ 52static int verify_stack(unsigned long sp) 53{ 54 if (sp < PAGE_OFFSET || (sp > (unsigned long)high_memory && high_memory != 0)) 55 return -EFAULT; 56 57 return 0; 58} 59 60/* 61 * Dump out the contents of some memory nicely... 62 */ 63static void dump_mem(const char *str, unsigned long bottom, unsigned long top) 64{ 65 unsigned long p = bottom & ~31; 66 mm_segment_t fs; 67 int i; 68 69 /* 70 * We need to switch to kernel mode so that we can use __get_user 71 * to safely read from kernel space. Note that we now dump the 72 * code first, just in case the backtrace kills us. 73 */ 74 fs = get_fs(); 75 set_fs(KERNEL_DS); 76 77 printk("%s", str); 78 printk("(0x%08lx to 0x%08lx)\n", bottom, top); 79 80 for (p = bottom & ~31; p < top;) { 81 printk("%04lx: ", p & 0xffff); 82 83 for (i = 0; i < 8; i++, p += 4) { 84 unsigned int val; 85 86 if (p < bottom || p >= top) 87 printk(" "); 88 else { 89 __get_user(val, (unsigned long *)p); 90 printk("%08x ", val); 91 } 92 } 93 printk ("\n"); 94 } 95 96 set_fs(fs); 97} 98 99static void dump_instr(struct pt_regs *regs) 100{ 101 unsigned long addr = instruction_pointer(regs); 102 const int width = 8; 103 mm_segment_t fs; 104 int i; 105 106 /* 107 * We need to switch to kernel mode so that we can use __get_user 108 * to safely read from kernel space. Note that we now dump the 109 * code first, just in case the backtrace kills us. 110 */ 111 fs = get_fs(); 112 set_fs(KERNEL_DS); 113 114 printk("Code: "); 115 for (i = -4; i < 1; i++) { 116 unsigned int val, bad; 117 118 bad = __get_user(val, &((u32 *)addr)[i]); 119 120 if (!bad) 121 printk(i == 0 ? "(%0*x) " : "%0*x ", width, val); 122 else { 123 printk("bad PC value."); 124 break; 125 } 126 } 127 printk("\n"); 128 129 set_fs(fs); 130} 131 132/*static*/ void __dump_stack(struct task_struct *tsk, unsigned long sp) 133{ 134 dump_mem("Stack: ", sp, 8192+(unsigned long)task_stack_page(tsk)); 135} 136 137void dump_stack(void) 138{ 139#ifdef CONFIG_DEBUG_ERRORS 140 __backtrace(); 141#endif 142} 143 144EXPORT_SYMBOL(dump_stack); 145 146void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk) 147{ 148 unsigned int fp; 149 int ok = 1; 150 151 printk("Backtrace: "); 152 fp = regs->ARM_fp; 153 if (!fp) { 154 printk("no frame pointer"); 155 ok = 0; 156 } else if (verify_stack(fp)) { 157 printk("invalid frame pointer 0x%08x", fp); 158 ok = 0; 159 } else if (fp < (unsigned long)end_of_stack(tsk)) 160 printk("frame pointer underflow"); 161 printk("\n"); 162 163 if (ok) 164 c_backtrace(fp, processor_mode(regs)); 165} 166 167void show_stack(struct task_struct *task, unsigned long *sp) { 168 dump_mem("Stack: ", (unsigned long)sp, 8192+(unsigned long)task_stack_page(task)); 169} 170 171DEFINE_SPINLOCK(die_lock); 172 173/* 174 * This function is protected against re-entrancy. 175 */ 176NORET_TYPE void die(const char *str, struct pt_regs *regs, int err) 177{ 178 struct task_struct *tsk = current; 179 180 console_verbose(); 181 spin_lock_irq(&die_lock); 182 183 printk("Internal error: %s: %x\n", str, err); 184 printk("CPU: %d\n", smp_processor_id()); 185 show_regs(regs); 186 printk("Process %s (pid: %d, stack limit = 0x%p)\n", 187 current->comm, current->pid, end_of_stack(tsk)); 188 189 if (!user_mode(regs) || in_interrupt()) { 190 __dump_stack(tsk, (unsigned long)(regs + 1)); 191 dump_backtrace(regs, tsk); 192 dump_instr(regs); 193 } 194while(1); 195 spin_unlock_irq(&die_lock); 196 do_exit(SIGSEGV); 197} 198 199void die_if_kernel(const char *str, struct pt_regs *regs, int err) 200{ 201 if (user_mode(regs)) 202 return; 203 204 die(str, regs, err); 205} 206 207static DEFINE_MUTEX(undef_mutex); 208static int (*undef_hook)(struct pt_regs *); 209 210int request_undef_hook(int (*fn)(struct pt_regs *)) 211{ 212 int ret = -EBUSY; 213 214 mutex_lock(&undef_mutex); 215 if (undef_hook == NULL) { 216 undef_hook = fn; 217 ret = 0; 218 } 219 mutex_unlock(&undef_mutex); 220 221 return ret; 222} 223 224int release_undef_hook(int (*fn)(struct pt_regs *)) 225{ 226 int ret = -EINVAL; 227 228 mutex_lock(&undef_mutex); 229 if (undef_hook == fn) { 230 undef_hook = NULL; 231 ret = 0; 232 } 233 mutex_unlock(&undef_mutex); 234 235 return ret; 236} 237 238static int undefined_extension(struct pt_regs *regs, unsigned int op) 239{ 240 switch (op) { 241 case 1: /* 0xde01 / 0x?7f001f0 */ 242 ptrace_break(current, regs); 243 return 0; 244 } 245 return 1; 246} 247 248asmlinkage void do_undefinstr(struct pt_regs *regs) 249{ 250 siginfo_t info; 251 void *pc; 252 253 regs->ARM_pc -= 4; 254 255 pc = (unsigned long *)instruction_pointer(regs); /* strip PSR */ 256 257 if (user_mode(regs)) { 258 u32 instr; 259 260 get_user(instr, (u32 *)pc); 261 262 if ((instr & 0x0fff00ff) == 0x07f000f0 && 263 undefined_extension(regs, (instr >> 8) & 255) == 0) { 264 regs->ARM_pc += 4; 265 return; 266 } 267 } else { 268 if (undef_hook && undef_hook(regs) == 0) { 269 regs->ARM_pc += 4; 270 return; 271 } 272 } 273 274#ifdef CONFIG_DEBUG_USER 275 printk(KERN_INFO "%s (%d): undefined instruction: pc=%p\n", 276 current->comm, current->pid, pc); 277 dump_instr(regs); 278#endif 279 280 current->thread.error_code = 0; 281 current->thread.trap_no = 6; 282 283 info.si_signo = SIGILL; 284 info.si_errno = 0; 285 info.si_code = ILL_ILLOPC; 286 info.si_addr = pc; 287 288 force_sig_info(SIGILL, &info, current); 289 290 die_if_kernel("Oops - undefined instruction", regs, 0); 291} 292 293asmlinkage void do_excpt(unsigned long address, struct pt_regs *regs, int mode) 294{ 295 siginfo_t info; 296 297#ifdef CONFIG_DEBUG_USER 298 printk(KERN_INFO "%s (%d): address exception: pc=%08lx\n", 299 current->comm, current->pid, instruction_pointer(regs)); 300 dump_instr(regs); 301#endif 302 303 current->thread.error_code = 0; 304 current->thread.trap_no = 11; 305 306 info.si_signo = SIGBUS; 307 info.si_errno = 0; 308 info.si_code = BUS_ADRERR; 309 info.si_addr = (void *)address; 310 311 force_sig_info(SIGBUS, &info, current); 312 313 die_if_kernel("Oops - address exception", regs, mode); 314} 315 316asmlinkage void do_unexp_fiq (struct pt_regs *regs) 317{ 318#ifndef CONFIG_IGNORE_FIQ 319 printk("Hmm. Unexpected FIQ received, but trying to continue\n"); 320 printk("You may have a hardware problem...\n"); 321#endif 322} 323 324/* 325 * bad_mode handles the impossible case in the vectors. If you see one of 326 * these, then it's extremely serious, and could mean you have buggy hardware. 327 * It never returns, and never tries to sync. We hope that we can at least 328 * dump out some state information... 329 */ 330asmlinkage void bad_mode(struct pt_regs *regs, int reason, int proc_mode) 331{ 332 unsigned int vectors = vectors_base(); 333 334 console_verbose(); 335 336 printk(KERN_CRIT "Bad mode in %s handler detected: mode %s\n", 337 handler[reason<5?reason:4], processor_modes[proc_mode]); 338 339 /* 340 * Dump out the vectors and stub routines. Maybe a better solution 341 * would be to dump them out only if we detect that they are corrupted. 342 */ 343 dump_mem(KERN_CRIT "Vectors: ", vectors, vectors + 0x40); 344 dump_mem(KERN_CRIT "Stubs: ", vectors + 0x200, vectors + 0x4b8); 345 346 die("Oops", regs, 0); 347 local_irq_disable(); 348 panic("bad mode"); 349} 350 351static int bad_syscall(int n, struct pt_regs *regs) 352{ 353 struct thread_info *thread = current_thread_info(); 354 siginfo_t info; 355 356 if (current->personality != PER_LINUX && thread->exec_domain->handler) { 357 thread->exec_domain->handler(n, regs); 358 return regs->ARM_r0; 359 } 360 361#ifdef CONFIG_DEBUG_USER 362 printk(KERN_ERR "[%d] %s: obsolete system call %08x.\n", 363 current->pid, current->comm, n); 364 dump_instr(regs); 365#endif 366 367 info.si_signo = SIGILL; 368 info.si_errno = 0; 369 info.si_code = ILL_ILLTRP; 370 info.si_addr = (void *)instruction_pointer(regs) - 4; 371 372 force_sig_info(SIGILL, &info, current); 373 die_if_kernel("Oops", regs, n); 374 return regs->ARM_r0; 375} 376 377static inline void 378do_cache_op(unsigned long start, unsigned long end, int flags) 379{ 380 struct vm_area_struct *vma; 381 382 if (end < start) 383 return; 384 385 vma = find_vma(current->active_mm, start); 386 if (vma && vma->vm_start < end) { 387 if (start < vma->vm_start) 388 start = vma->vm_start; 389 if (end > vma->vm_end) 390 end = vma->vm_end; 391 } 392} 393 394/* 395 * Handle all unrecognised system calls. 396 * 0x9f0000 - 0x9fffff are some more esoteric system calls 397 */ 398#define NR(x) ((__ARM_NR_##x) - __ARM_NR_BASE) 399asmlinkage int arm_syscall(int no, struct pt_regs *regs) 400{ 401 siginfo_t info; 402 403 if ((no >> 16) != 0x9f) 404 return bad_syscall(no, regs); 405 406 switch (no & 0xffff) { 407 case 0: /* branch through 0 */ 408 info.si_signo = SIGSEGV; 409 info.si_errno = 0; 410 info.si_code = SEGV_MAPERR; 411 info.si_addr = NULL; 412 413 force_sig_info(SIGSEGV, &info, current); 414 415 die_if_kernel("branch through zero", regs, 0); 416 return 0; 417 418 case NR(breakpoint): /* SWI BREAK_POINT */ 419 ptrace_break(current, regs); 420 return regs->ARM_r0; 421 422 case NR(cacheflush): 423 return 0; 424 425 case NR(usr26): 426 break; 427 428 default: 429 /* Calls 9f00xx..9f07ff are defined to return -ENOSYS 430 if not implemented, rather than raising SIGILL. This 431 way the calling program can gracefully determine whether 432 a feature is supported. */ 433 if (no <= 0x7ff) 434 return -ENOSYS; 435 break; 436 } 437#ifdef CONFIG_DEBUG_USER 438 /* 439 * experience shows that these seem to indicate that 440 * something catastrophic has happened 441 */ 442 printk("[%d] %s: arm syscall %d\n", current->pid, current->comm, no); 443 dump_instr(regs); 444 if (user_mode(regs)) { 445 show_regs(regs); 446 c_backtrace(regs->ARM_fp, processor_mode(regs)); 447 } 448#endif 449 info.si_signo = SIGILL; 450 info.si_errno = 0; 451 info.si_code = ILL_ILLTRP; 452 info.si_addr = (void *)instruction_pointer(regs) - 4; 453 454 force_sig_info(SIGILL, &info, current); 455 die_if_kernel("Oops", regs, no); 456 return 0; 457} 458 459void __bad_xchg(volatile void *ptr, int size) 460{ 461 printk("xchg: bad data size: pc 0x%p, ptr 0x%p, size %d\n", 462 __builtin_return_address(0), ptr, size); 463 BUG(); 464} 465 466/* 467 * A data abort trap was taken, but we did not handle the instruction. 468 * Try to abort the user program, or panic if it was the kernel. 469 */ 470asmlinkage void 471baddataabort(int code, unsigned long instr, struct pt_regs *regs) 472{ 473 unsigned long addr = instruction_pointer(regs); 474 siginfo_t info; 475 476#ifdef CONFIG_DEBUG_USER 477 printk(KERN_ERR "[%d] %s: bad data abort: code %d instr 0x%08lx\n", 478 current->pid, current->comm, code, instr); 479 dump_instr(regs); 480 show_pte(current->mm, addr); 481#endif 482 483 info.si_signo = SIGILL; 484 info.si_errno = 0; 485 info.si_code = ILL_ILLOPC; 486 info.si_addr = (void *)addr; 487 488 force_sig_info(SIGILL, &info, current); 489 die_if_kernel("unknown data abort code", regs, instr); 490} 491 492volatile void __bug(const char *file, int line, void *data) 493{ 494 printk(KERN_CRIT"kernel BUG at %s:%d!", file, line); 495 if (data) 496 printk(KERN_CRIT" - extra data = %p", data); 497 printk("\n"); 498 *(int *)0 = 0; 499} 500 501void __readwrite_bug(const char *fn) 502{ 503 printk("%s called, but not implemented", fn); 504 BUG(); 505} 506 507void __pte_error(const char *file, int line, unsigned long val) 508{ 509 printk("%s:%d: bad pte %08lx.\n", file, line, val); 510} 511 512void __pmd_error(const char *file, int line, unsigned long val) 513{ 514 printk("%s:%d: bad pmd %08lx.\n", file, line, val); 515} 516 517void __pgd_error(const char *file, int line, unsigned long val) 518{ 519 printk("%s:%d: bad pgd %08lx.\n", file, line, val); 520} 521 522asmlinkage void __div0(void) 523{ 524 printk("Division by zero in kernel.\n"); 525 dump_stack(); 526} 527 528void abort(void) 529{ 530 BUG(); 531 532 /* if that doesn't kill us, halt */ 533 panic("Oops failed to kill thread"); 534} 535 536void __init trap_init(void) 537{ 538 extern void __trap_init(unsigned long); 539 unsigned long base = vectors_base(); 540 541 __trap_init(base); 542 if (base != 0) 543 printk(KERN_DEBUG "Relocating machine vectors to 0x%08lx\n", 544 base); 545} 546