1 /* MN10300 Exception handling 2 * 3 * Copyright (C) 2007 Matsushita Electric Industrial Co., Ltd. 4 * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. 5 * Modified by David Howells (dhowells@redhat.com) 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public Licence 9 * as published by the Free Software Foundation; either version 10 * 2 of the Licence, or (at your option) any later version. 11 */ 12 #include <linux/sched.h> 13 #include <linux/sched/debug.h> 14 #include <linux/kernel.h> 15 #include <linux/string.h> 16 #include <linux/errno.h> 17 #include <linux/ptrace.h> 18 #include <linux/timer.h> 19 #include <linux/mm.h> 20 #include <linux/smp.h> 21 #include <linux/init.h> 22 #include <linux/delay.h> 23 #include <linux/spinlock.h> 24 #include <linux/interrupt.h> 25 #include <linux/kallsyms.h> 26 #include <linux/pci.h> 27 #include <linux/kdebug.h> 28 #include <linux/bug.h> 29 #include <linux/irq.h> 30 #include <linux/export.h> 31 #include <asm/processor.h> 32 #include <linux/uaccess.h> 33 #include <asm/io.h> 34 #include <linux/atomic.h> 35 #include <asm/smp.h> 36 #include <asm/pgalloc.h> 37 #include <asm/cacheflush.h> 38 #include <asm/cpu-regs.h> 39 #include <asm/busctl-regs.h> 40 #include <unit/leds.h> 41 #include <asm/fpu.h> 42 #include <asm/sections.h> 43 #include <asm/debugger.h> 44 #include "internal.h" 45 46 #if (CONFIG_INTERRUPT_VECTOR_BASE & 0xffffff) 47 #error "INTERRUPT_VECTOR_BASE not aligned to 16MiB boundary!" 48 #endif 49 50 int kstack_depth_to_print = 24; 51 52 spinlock_t die_lock = __SPIN_LOCK_UNLOCKED(die_lock); 53 54 struct exception_to_signal_map { 55 u8 signo; 56 u32 si_code; 57 }; 58 59 static const struct exception_to_signal_map exception_to_signal_map[256] = { 60 /* MMU exceptions */ 61 [EXCEP_ITLBMISS >> 3] = { 0, 0 }, 62 [EXCEP_DTLBMISS >> 3] = { 0, 0 }, 63 [EXCEP_IAERROR >> 3] = { 0, 0 }, 64 [EXCEP_DAERROR >> 3] = { 0, 0 }, 65 66 /* system exceptions */ 67 [EXCEP_TRAP >> 3] = { SIGTRAP, TRAP_BRKPT }, 68 [EXCEP_ISTEP >> 3] = { SIGTRAP, TRAP_TRACE }, /* Monitor */ 69 [EXCEP_IBREAK >> 3] = { SIGTRAP, TRAP_HWBKPT }, /* Monitor */ 70 [EXCEP_OBREAK >> 3] = { SIGTRAP, TRAP_HWBKPT }, /* Monitor */ 71 [EXCEP_PRIVINS >> 3] = { SIGILL, ILL_PRVOPC }, 72 [EXCEP_UNIMPINS >> 3] = { SIGILL, ILL_ILLOPC }, 73 [EXCEP_UNIMPEXINS >> 3] = { SIGILL, ILL_ILLOPC }, 74 [EXCEP_MEMERR >> 3] = { SIGSEGV, SEGV_ACCERR }, 75 [EXCEP_MISALIGN >> 3] = { SIGBUS, BUS_ADRALN }, 76 [EXCEP_BUSERROR >> 3] = { SIGBUS, BUS_ADRERR }, 77 [EXCEP_ILLINSACC >> 3] = { SIGSEGV, SEGV_ACCERR }, 78 [EXCEP_ILLDATACC >> 3] = { SIGSEGV, SEGV_ACCERR }, 79 [EXCEP_IOINSACC >> 3] = { SIGSEGV, SEGV_ACCERR }, 80 [EXCEP_PRIVINSACC >> 3] = { SIGSEGV, SEGV_ACCERR }, /* userspace */ 81 [EXCEP_PRIVDATACC >> 3] = { SIGSEGV, SEGV_ACCERR }, /* userspace */ 82 [EXCEP_DATINSACC >> 3] = { SIGSEGV, SEGV_ACCERR }, 83 [EXCEP_DOUBLE_FAULT >> 3] = { SIGILL, ILL_BADSTK }, 84 85 /* FPU exceptions */ 86 [EXCEP_FPU_DISABLED >> 3] = { SIGILL, ILL_COPROC }, 87 [EXCEP_FPU_UNIMPINS >> 3] = { SIGILL, ILL_COPROC }, 88 [EXCEP_FPU_OPERATION >> 3] = { SIGFPE, FPE_INTDIV }, 89 90 /* interrupts */ 91 [EXCEP_WDT >> 3] = { SIGALRM, 0 }, 92 [EXCEP_NMI >> 3] = { SIGQUIT, 0 }, 93 [EXCEP_IRQ_LEVEL0 >> 3] = { SIGINT, 0 }, 94 [EXCEP_IRQ_LEVEL1 >> 3] = { 0, 0 }, 95 [EXCEP_IRQ_LEVEL2 >> 3] = { 0, 0 }, 96 [EXCEP_IRQ_LEVEL3 >> 3] = { 0, 0 }, 97 [EXCEP_IRQ_LEVEL4 >> 3] = { 0, 0 }, 98 [EXCEP_IRQ_LEVEL5 >> 3] = { 0, 0 }, 99 [EXCEP_IRQ_LEVEL6 >> 3] = { 0, 0 }, 100 101 /* system calls */ 102 [EXCEP_SYSCALL0 >> 3] = { 0, 0 }, 103 [EXCEP_SYSCALL1 >> 3] = { SIGILL, ILL_ILLTRP }, 104 [EXCEP_SYSCALL2 >> 3] = { SIGILL, ILL_ILLTRP }, 105 [EXCEP_SYSCALL3 >> 3] = { SIGILL, ILL_ILLTRP }, 106 [EXCEP_SYSCALL4 >> 3] = { SIGILL, ILL_ILLTRP }, 107 [EXCEP_SYSCALL5 >> 3] = { SIGILL, ILL_ILLTRP }, 108 [EXCEP_SYSCALL6 >> 3] = { SIGILL, ILL_ILLTRP }, 109 [EXCEP_SYSCALL7 >> 3] = { SIGILL, ILL_ILLTRP }, 110 [EXCEP_SYSCALL8 >> 3] = { SIGILL, ILL_ILLTRP }, 111 [EXCEP_SYSCALL9 >> 3] = { SIGILL, ILL_ILLTRP }, 112 [EXCEP_SYSCALL10 >> 3] = { SIGILL, ILL_ILLTRP }, 113 [EXCEP_SYSCALL11 >> 3] = { SIGILL, ILL_ILLTRP }, 114 [EXCEP_SYSCALL12 >> 3] = { SIGILL, ILL_ILLTRP }, 115 [EXCEP_SYSCALL13 >> 3] = { SIGILL, ILL_ILLTRP }, 116 [EXCEP_SYSCALL14 >> 3] = { SIGILL, ILL_ILLTRP }, 117 [EXCEP_SYSCALL15 >> 3] = { SIGABRT, 0 }, 118 }; 119 120 /* 121 * Handle kernel exceptions. 122 * 123 * See if there's a fixup handler we can force a jump to when an exception 124 * happens due to something kernel code did 125 */ 126 int die_if_no_fixup(const char *str, struct pt_regs *regs, 127 enum exception_code code) 128 { 129 u8 opcode; 130 int signo, si_code; 131 132 if (user_mode(regs)) 133 return 0; 134 135 peripheral_leds_display_exception(code); 136 137 signo = exception_to_signal_map[code >> 3].signo; 138 si_code = exception_to_signal_map[code >> 3].si_code; 139 140 switch (code) { 141 /* see if we can fixup the kernel accessing memory */ 142 case EXCEP_ITLBMISS: 143 case EXCEP_DTLBMISS: 144 case EXCEP_IAERROR: 145 case EXCEP_DAERROR: 146 case EXCEP_MEMERR: 147 case EXCEP_MISALIGN: 148 case EXCEP_BUSERROR: 149 case EXCEP_ILLDATACC: 150 case EXCEP_IOINSACC: 151 case EXCEP_PRIVINSACC: 152 case EXCEP_PRIVDATACC: 153 case EXCEP_DATINSACC: 154 if (fixup_exception(regs)) 155 return 1; 156 break; 157 158 case EXCEP_TRAP: 159 case EXCEP_UNIMPINS: 160 if (probe_kernel_read(&opcode, (u8 *)regs->pc, 1) < 0) 161 break; 162 if (opcode == 0xff) { 163 if (notify_die(DIE_BREAKPOINT, str, regs, code, 0, 0)) 164 return 1; 165 if (at_debugger_breakpoint(regs)) 166 regs->pc++; 167 signo = SIGTRAP; 168 si_code = TRAP_BRKPT; 169 } 170 break; 171 172 case EXCEP_SYSCALL1 ... EXCEP_SYSCALL14: 173 /* syscall return addr is _after_ the instruction */ 174 regs->pc -= 2; 175 break; 176 177 case EXCEP_SYSCALL15: 178 if (report_bug(regs->pc, regs) == BUG_TRAP_TYPE_WARN) 179 return 1; 180 181 /* syscall return addr is _after_ the instruction */ 182 regs->pc -= 2; 183 break; 184 185 default: 186 break; 187 } 188 189 if (debugger_intercept(code, signo, si_code, regs) == 0) 190 return 1; 191 192 if (notify_die(DIE_GPF, str, regs, code, 0, 0)) 193 return 1; 194 195 /* make the process die as the last resort */ 196 die(str, regs, code); 197 } 198 199 /* 200 * General exception handler 201 */ 202 asmlinkage void handle_exception(struct pt_regs *regs, u32 intcode) 203 { 204 siginfo_t info; 205 206 /* deal with kernel exceptions here */ 207 if (die_if_no_fixup(NULL, regs, intcode)) 208 return; 209 210 /* otherwise it's a userspace exception */ 211 info.si_signo = exception_to_signal_map[intcode >> 3].signo; 212 info.si_code = exception_to_signal_map[intcode >> 3].si_code; 213 info.si_errno = 0; 214 info.si_addr = (void *) regs->pc; 215 force_sig_info(info.si_signo, &info, current); 216 } 217 218 /* 219 * handle NMI 220 */ 221 asmlinkage void nmi(struct pt_regs *regs, enum exception_code code) 222 { 223 /* see if gdbstub wants to deal with it */ 224 if (debugger_intercept(code, SIGQUIT, 0, regs)) 225 return; 226 227 printk(KERN_WARNING "--- Register Dump ---\n"); 228 show_registers(regs); 229 printk(KERN_WARNING "---------------------\n"); 230 } 231 232 /* 233 * show a stack trace from the specified stack pointer 234 */ 235 void show_trace(unsigned long *sp) 236 { 237 unsigned long bottom, stack, addr, fp, raslot; 238 239 printk(KERN_EMERG "\nCall Trace:\n"); 240 241 //stack = (unsigned long)sp; 242 asm("mov sp,%0" : "=a"(stack)); 243 asm("mov a3,%0" : "=r"(fp)); 244 245 raslot = ULONG_MAX; 246 bottom = (stack + THREAD_SIZE) & ~(THREAD_SIZE - 1); 247 for (; stack < bottom; stack += sizeof(addr)) { 248 addr = *(unsigned long *)stack; 249 if (stack == fp) { 250 if (addr > stack && addr < bottom) { 251 fp = addr; 252 raslot = stack + sizeof(addr); 253 continue; 254 } 255 fp = 0; 256 raslot = ULONG_MAX; 257 } 258 259 if (__kernel_text_address(addr)) { 260 printk(" [<%08lx>]", addr); 261 if (stack >= raslot) 262 raslot = ULONG_MAX; 263 else 264 printk(" ?"); 265 print_symbol(" %s", addr); 266 printk("\n"); 267 } 268 } 269 270 printk("\n"); 271 } 272 273 /* 274 * show the raw stack from the specified stack pointer 275 */ 276 void show_stack(struct task_struct *task, unsigned long *sp) 277 { 278 unsigned long *stack; 279 int i; 280 281 if (!sp) 282 sp = (unsigned long *) &sp; 283 284 stack = sp; 285 printk(KERN_EMERG "Stack:"); 286 for (i = 0; i < kstack_depth_to_print; i++) { 287 if (((long) stack & (THREAD_SIZE - 1)) == 0) 288 break; 289 if ((i % 8) == 0) 290 printk(KERN_EMERG " "); 291 printk("%08lx ", *stack++); 292 } 293 294 show_trace(sp); 295 } 296 297 /* 298 * dump the register file in the specified exception frame 299 */ 300 void show_registers_only(struct pt_regs *regs) 301 { 302 unsigned long ssp; 303 304 ssp = (unsigned long) regs + sizeof(*regs); 305 306 printk(KERN_EMERG "PC: %08lx EPSW: %08lx SSP: %08lx mode: %s\n", 307 regs->pc, regs->epsw, ssp, user_mode(regs) ? "User" : "Super"); 308 printk(KERN_EMERG "d0: %08lx d1: %08lx d2: %08lx d3: %08lx\n", 309 regs->d0, regs->d1, regs->d2, regs->d3); 310 printk(KERN_EMERG "a0: %08lx a1: %08lx a2: %08lx a3: %08lx\n", 311 regs->a0, regs->a1, regs->a2, regs->a3); 312 printk(KERN_EMERG "e0: %08lx e1: %08lx e2: %08lx e3: %08lx\n", 313 regs->e0, regs->e1, regs->e2, regs->e3); 314 printk(KERN_EMERG "e4: %08lx e5: %08lx e6: %08lx e7: %08lx\n", 315 regs->e4, regs->e5, regs->e6, regs->e7); 316 printk(KERN_EMERG "lar: %08lx lir: %08lx mdr: %08lx usp: %08lx\n", 317 regs->lar, regs->lir, regs->mdr, regs->sp); 318 printk(KERN_EMERG "cvf: %08lx crl: %08lx crh: %08lx drq: %08lx\n", 319 regs->mcvf, regs->mcrl, regs->mcrh, regs->mdrq); 320 printk(KERN_EMERG "threadinfo=%p task=%p)\n", 321 current_thread_info(), current); 322 323 if ((unsigned long) current >= PAGE_OFFSET && 324 (unsigned long) current < (unsigned long)high_memory) 325 printk(KERN_EMERG "Process %s (pid: %d)\n", 326 current->comm, current->pid); 327 328 #ifdef CONFIG_SMP 329 printk(KERN_EMERG "CPUID: %08x\n", CPUID); 330 #endif 331 printk(KERN_EMERG "CPUP: %04hx\n", CPUP); 332 printk(KERN_EMERG "TBR: %08x\n", TBR); 333 printk(KERN_EMERG "DEAR: %08x\n", DEAR); 334 printk(KERN_EMERG "sISR: %08x\n", sISR); 335 printk(KERN_EMERG "NMICR: %04hx\n", NMICR); 336 printk(KERN_EMERG "BCBERR: %08x\n", BCBERR); 337 printk(KERN_EMERG "BCBEAR: %08x\n", BCBEAR); 338 printk(KERN_EMERG "MMUFCR: %08x\n", MMUFCR); 339 printk(KERN_EMERG "IPTEU : %08x IPTEL2: %08x\n", IPTEU, IPTEL2); 340 printk(KERN_EMERG "DPTEU: %08x DPTEL2: %08x\n", DPTEU, DPTEL2); 341 } 342 343 /* 344 * dump the registers and the stack 345 */ 346 void show_registers(struct pt_regs *regs) 347 { 348 unsigned long sp; 349 int i; 350 351 show_registers_only(regs); 352 353 if (!user_mode(regs)) 354 sp = (unsigned long) regs + sizeof(*regs); 355 else 356 sp = regs->sp; 357 358 /* when in-kernel, we also print out the stack and code at the 359 * time of the fault.. 360 */ 361 if (!user_mode(regs)) { 362 printk(KERN_EMERG "\n"); 363 show_stack(current, (unsigned long *) sp); 364 365 #if 0 366 printk(KERN_EMERG "\nCode: "); 367 if (regs->pc < PAGE_OFFSET) 368 goto bad; 369 370 for (i = 0; i < 20; i++) { 371 unsigned char c; 372 if (__get_user(c, &((unsigned char *) regs->pc)[i])) 373 goto bad; 374 printk("%02x ", c); 375 } 376 #else 377 i = 0; 378 #endif 379 } 380 381 printk("\n"); 382 return; 383 384 #if 0 385 bad: 386 printk(KERN_EMERG " Bad PC value."); 387 break; 388 #endif 389 } 390 391 /* 392 * 393 */ 394 void show_trace_task(struct task_struct *tsk) 395 { 396 unsigned long sp = tsk->thread.sp; 397 398 /* User space on another CPU? */ 399 if ((sp ^ (unsigned long) tsk) & (PAGE_MASK << 1)) 400 return; 401 402 show_trace((unsigned long *) sp); 403 } 404 405 /* 406 * note the untimely death of part of the kernel 407 */ 408 void die(const char *str, struct pt_regs *regs, enum exception_code code) 409 { 410 console_verbose(); 411 spin_lock_irq(&die_lock); 412 printk(KERN_EMERG "\n%s: %04x\n", 413 str, code & 0xffff); 414 show_registers(regs); 415 416 if (regs->pc >= 0x02000000 && regs->pc < 0x04000000 && 417 (regs->epsw & (EPSW_IM | EPSW_IE)) != (EPSW_IM | EPSW_IE)) { 418 printk(KERN_EMERG "Exception in usermode interrupt handler\n"); 419 printk(KERN_EMERG "\nPlease connect to kernel debugger !!\n"); 420 asm volatile ("0: bra 0b"); 421 } 422 423 spin_unlock_irq(&die_lock); 424 do_exit(SIGSEGV); 425 } 426 427 /* 428 * display the register file when the stack pointer gets clobbered 429 */ 430 asmlinkage void do_double_fault(struct pt_regs *regs) 431 { 432 struct task_struct *tsk = current; 433 434 strcpy(tsk->comm, "emergency tsk"); 435 tsk->pid = 0; 436 console_verbose(); 437 printk(KERN_EMERG "--- double fault ---\n"); 438 show_registers(regs); 439 } 440 441 /* 442 * asynchronous bus error (external, usually I/O DMA) 443 */ 444 asmlinkage void io_bus_error(u32 bcberr, u32 bcbear, struct pt_regs *regs) 445 { 446 console_verbose(); 447 448 printk(KERN_EMERG "Asynchronous I/O Bus Error\n"); 449 printk(KERN_EMERG "==========================\n"); 450 451 if (bcberr & BCBERR_BEME) 452 printk(KERN_EMERG "- Multiple recorded errors\n"); 453 454 printk(KERN_EMERG "- Faulting Buses:%s%s%s\n", 455 bcberr & BCBERR_BEMR_CI ? " CPU-Ins-Fetch" : "", 456 bcberr & BCBERR_BEMR_CD ? " CPU-Data" : "", 457 bcberr & BCBERR_BEMR_DMA ? " DMA" : ""); 458 459 printk(KERN_EMERG "- %s %s access made to %s at address %08x\n", 460 bcberr & BCBERR_BEBST ? "Burst" : "Single", 461 bcberr & BCBERR_BERW ? "Read" : "Write", 462 bcberr & BCBERR_BESB_MON ? "Monitor Space" : 463 bcberr & BCBERR_BESB_IO ? "Internal CPU I/O Space" : 464 bcberr & BCBERR_BESB_EX ? "External I/O Bus" : 465 bcberr & BCBERR_BESB_OPEX ? "External Memory Bus" : 466 "On Chip Memory", 467 bcbear 468 ); 469 470 printk(KERN_EMERG "- Detected by the %s\n", 471 bcberr&BCBERR_BESD ? "Bus Control Unit" : "Slave Bus"); 472 473 #ifdef CONFIG_PCI 474 #define BRIDGEREGB(X) (*(volatile __u8 *)(0xBE040000 + (X))) 475 #define BRIDGEREGW(X) (*(volatile __u16 *)(0xBE040000 + (X))) 476 #define BRIDGEREGL(X) (*(volatile __u32 *)(0xBE040000 + (X))) 477 478 printk(KERN_EMERG "- PCI Memory Paging Reg: %08x\n", 479 *(volatile __u32 *) (0xBFFFFFF4)); 480 printk(KERN_EMERG "- PCI Bridge Base Address 0: %08x\n", 481 BRIDGEREGL(PCI_BASE_ADDRESS_0)); 482 printk(KERN_EMERG "- PCI Bridge AMPCI Base Address: %08x\n", 483 BRIDGEREGL(0x48)); 484 printk(KERN_EMERG "- PCI Bridge Command: %04hx\n", 485 BRIDGEREGW(PCI_COMMAND)); 486 printk(KERN_EMERG "- PCI Bridge Status: %04hx\n", 487 BRIDGEREGW(PCI_STATUS)); 488 printk(KERN_EMERG "- PCI Bridge Int Status: %08hx\n", 489 BRIDGEREGL(0x4c)); 490 #endif 491 492 printk(KERN_EMERG "\n"); 493 show_registers(regs); 494 495 panic("Halted due to asynchronous I/O Bus Error\n"); 496 } 497 498 /* 499 * handle an exception for which a handler has not yet been installed 500 */ 501 asmlinkage void uninitialised_exception(struct pt_regs *regs, 502 enum exception_code code) 503 { 504 505 /* see if gdbstub wants to deal with it */ 506 if (debugger_intercept(code, SIGSYS, 0, regs) == 0) 507 return; 508 509 peripheral_leds_display_exception(code); 510 printk(KERN_EMERG "Uninitialised Exception 0x%04x\n", code & 0xFFFF); 511 show_registers(regs); 512 513 for (;;) 514 continue; 515 } 516 517 /* 518 * set an interrupt stub to jump to a handler 519 * ! NOTE: this does *not* flush the caches 520 */ 521 void __init __set_intr_stub(enum exception_code code, void *handler) 522 { 523 unsigned long addr; 524 u8 *vector = (u8 *)(CONFIG_INTERRUPT_VECTOR_BASE + code); 525 526 addr = (unsigned long) handler - (unsigned long) vector; 527 vector[0] = 0xdc; /* JMP handler */ 528 vector[1] = addr; 529 vector[2] = addr >> 8; 530 vector[3] = addr >> 16; 531 vector[4] = addr >> 24; 532 vector[5] = 0xcb; 533 vector[6] = 0xcb; 534 vector[7] = 0xcb; 535 } 536 537 /* 538 * set an interrupt stub to jump to a handler 539 */ 540 void __init set_intr_stub(enum exception_code code, void *handler) 541 { 542 unsigned long addr; 543 u8 *vector = (u8 *)(CONFIG_INTERRUPT_VECTOR_BASE + code); 544 unsigned long flags; 545 546 addr = (unsigned long) handler - (unsigned long) vector; 547 548 flags = arch_local_cli_save(); 549 550 vector[0] = 0xdc; /* JMP handler */ 551 vector[1] = addr; 552 vector[2] = addr >> 8; 553 vector[3] = addr >> 16; 554 vector[4] = addr >> 24; 555 vector[5] = 0xcb; 556 vector[6] = 0xcb; 557 vector[7] = 0xcb; 558 559 arch_local_irq_restore(flags); 560 561 #ifndef CONFIG_MN10300_CACHE_SNOOP 562 mn10300_dcache_flush_inv(); 563 mn10300_icache_inv(); 564 #endif 565 } 566 567 /* 568 * initialise the exception table 569 */ 570 void __init trap_init(void) 571 { 572 set_excp_vector(EXCEP_TRAP, handle_exception); 573 set_excp_vector(EXCEP_ISTEP, handle_exception); 574 set_excp_vector(EXCEP_IBREAK, handle_exception); 575 set_excp_vector(EXCEP_OBREAK, handle_exception); 576 577 set_excp_vector(EXCEP_PRIVINS, handle_exception); 578 set_excp_vector(EXCEP_UNIMPINS, handle_exception); 579 set_excp_vector(EXCEP_UNIMPEXINS, handle_exception); 580 set_excp_vector(EXCEP_MEMERR, handle_exception); 581 set_excp_vector(EXCEP_MISALIGN, misalignment); 582 set_excp_vector(EXCEP_BUSERROR, handle_exception); 583 set_excp_vector(EXCEP_ILLINSACC, handle_exception); 584 set_excp_vector(EXCEP_ILLDATACC, handle_exception); 585 set_excp_vector(EXCEP_IOINSACC, handle_exception); 586 set_excp_vector(EXCEP_PRIVINSACC, handle_exception); 587 set_excp_vector(EXCEP_PRIVDATACC, handle_exception); 588 set_excp_vector(EXCEP_DATINSACC, handle_exception); 589 set_excp_vector(EXCEP_FPU_UNIMPINS, handle_exception); 590 set_excp_vector(EXCEP_FPU_OPERATION, fpu_exception); 591 592 set_excp_vector(EXCEP_NMI, nmi); 593 594 set_excp_vector(EXCEP_SYSCALL1, handle_exception); 595 set_excp_vector(EXCEP_SYSCALL2, handle_exception); 596 set_excp_vector(EXCEP_SYSCALL3, handle_exception); 597 set_excp_vector(EXCEP_SYSCALL4, handle_exception); 598 set_excp_vector(EXCEP_SYSCALL5, handle_exception); 599 set_excp_vector(EXCEP_SYSCALL6, handle_exception); 600 set_excp_vector(EXCEP_SYSCALL7, handle_exception); 601 set_excp_vector(EXCEP_SYSCALL8, handle_exception); 602 set_excp_vector(EXCEP_SYSCALL9, handle_exception); 603 set_excp_vector(EXCEP_SYSCALL10, handle_exception); 604 set_excp_vector(EXCEP_SYSCALL11, handle_exception); 605 set_excp_vector(EXCEP_SYSCALL12, handle_exception); 606 set_excp_vector(EXCEP_SYSCALL13, handle_exception); 607 set_excp_vector(EXCEP_SYSCALL14, handle_exception); 608 set_excp_vector(EXCEP_SYSCALL15, handle_exception); 609 } 610 611 /* 612 * determine if a program counter value is a valid bug address 613 */ 614 int is_valid_bugaddr(unsigned long pc) 615 { 616 return pc >= PAGE_OFFSET; 617 } 618
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.