void bad_trap(struct pt_regs *regs, long lvl) { char buffer[32]; siginfo_t info; if (notify_die(DIE_TRAP, "bad trap", regs, 0, lvl, SIGTRAP) == NOTIFY_STOP) return; if (lvl < 0x100) { sprintf(buffer, "Bad hw trap %lx at tl0\n", lvl); die_if_kernel(buffer, regs); } lvl -= 0x100; if (regs->tstate & TSTATE_PRIV) { sprintf(buffer, "Kernel bad sw trap %lx", lvl); die_if_kernel(buffer, regs); } if (test_thread_flag(TIF_32BIT)) { regs->tpc &= 0xffffffff; regs->tnpc &= 0xffffffff; } info.si_signo = SIGILL; info.si_errno = 0; info.si_code = ILL_ILLTRP; info.si_addr = (void __user *)regs->tpc; info.si_trapno = lvl; force_sig_info(SIGILL, &info, current); }
/* * This routine handles page faults. It determines the address, * and the problem, and then passes it off to handle_mm_fault(). * * mmcsr: * 0 = translation not valid * 1 = access violation * 2 = fault-on-read * 3 = fault-on-execute * 4 = fault-on-write * * cause: * -1 = instruction fetch * 0 = load * 1 = store */ asmlinkage void do_page_fault(unsigned long address, unsigned long mmcsr, long cause, unsigned long a3, unsigned long a4, unsigned long a5, struct pt_regs regs) { struct vm_area_struct * vma; vma = find_vma(current, address); if (!vma) goto bad_area; if (vma->vm_start <= address) goto good_area; if (!(vma->vm_flags & VM_GROWSDOWN)) goto bad_area; if (expand_stack(vma, address)) goto bad_area; /* * Ok, we have a good vm_area for this memory access, so * we can handle it.. */ good_area: if (cause < 0) { if (!(vma->vm_flags & VM_EXEC)) goto bad_area; } else if (!cause) { /* Allow reads even for write-only mappings */ if (!(vma->vm_flags & (VM_READ | VM_WRITE))) goto bad_area; } else { if (!(vma->vm_flags & VM_WRITE)) goto bad_area; } tbis(address); handle_mm_fault(vma, address, cause > 0); return; /* * Something tried to access memory that isn't in our memory map.. * Fix it, but check if it's kernel or user first.. */ bad_area: if (user_mode(®s)) { printk("%s: memory violation at pc=%08lx rp=%08lx (bad address = %08lx)\n", current->comm, regs.pc, regs.r26, address); die_if_kernel("oops", ®s, cause); force_sig(SIGSEGV, current); return; } /* * Oops. The kernel tried to access some bad page. We'll have to * terminate things with extreme prejudice. */ printk(KERN_ALERT "Unable to handle kernel paging request at virtual address %016lx\n", address); die_if_kernel("Oops", ®s, cause); do_exit(SIGKILL); }
asmlinkage void do_entArith(unsigned long summary, unsigned long write_mask, struct pt_regs *regs) { long si_code = FPE_FLTINV; siginfo_t info; if (summary & 1) { /* */ if (!amask(AMASK_PRECISE_TRAP)) si_code = alpha_fp_emul(regs->pc - 4); else si_code = alpha_fp_emul_imprecise(regs, write_mask); if (si_code == 0) return; } die_if_kernel("Arithmetic fault", regs, 0, NULL); info.si_signo = SIGFPE; info.si_errno = 0; info.si_code = si_code; info.si_addr = (void __user *) regs->pc; send_sig_info(SIGFPE, &info, current); }
int send_fault_sig(struct pt_regs *regs) { int signo, si_code; void __user *addr; signo = current->thread.signo; si_code = current->thread.code; addr = (void __user *)current->thread.faddr; pr_debug("send_fault_sig: %p,%d,%d\n", addr, signo, si_code); if (user_mode(regs)) { force_sig_fault(signo, si_code, addr, current); } else { if (fixup_exception(regs)) return -1; //if (signo == SIGBUS) // force_sig_fault(si_signo, si_code, addr, current); /* * Oops. The kernel tried to access some bad page. We'll have to * terminate things with extreme prejudice. */ if ((unsigned long)addr < PAGE_SIZE) pr_alert("Unable to handle kernel NULL pointer dereference"); else pr_alert("Unable to handle kernel access"); pr_cont(" at virtual address %p\n", addr); die_if_kernel("Oops", regs, 0 /*error_code*/); do_exit(SIGKILL); } return 1; }
asmlinkage void do_entArith(unsigned long summary, unsigned long write_mask, struct pt_regs *regs) { long si_code = FPE_FLTINV; siginfo_t info; if (summary & 1) { /* Software-completion summary bit is set, so try to emulate the instruction. If the processor supports precise exceptions, we don't have to search. */ if (!amask(AMASK_PRECISE_TRAP)) si_code = alpha_fp_emul(regs->pc - 4); else si_code = alpha_fp_emul_imprecise(regs, write_mask); if (si_code == 0) return; } die_if_kernel("Arithmetic fault", regs, 0, NULL); info.si_signo = SIGFPE; info.si_errno = 0; info.si_code = si_code; info.si_addr = (void __user *) regs->pc; send_sig_info(SIGFPE, &info, current); }
asmlinkage void do_adelinsn(struct pt_regs *regs) { printk("do_ADE-linsn:ema:0x%08lx:epc:0x%08lx\n", regs->cp0_ema, regs->cp0_epc); die_if_kernel("do_ade execution Exception\n", regs); force_sig(SIGBUS, current); }
asmlinkage void do_entArith(unsigned long summary, unsigned long write_mask, unsigned long a2, unsigned long a3, unsigned long a4, unsigned long a5, struct pt_regs regs) { if (summary & 1) { /* Software-completion summary bit is set, so try to emulate the instruction. */ if (!amask(AMASK_PRECISE_TRAP)) { /* 21264 (except pass 1) has precise exceptions. */ if (alpha_fp_emul(regs.pc - 4)) return; } else { if (alpha_fp_emul_imprecise(®s, write_mask)) return; } } #if 0 printk("%s: arithmetic trap at %016lx: %02lx %016lx\n", current->comm, regs.pc, summary, write_mask); #endif die_if_kernel("Arithmetic fault", ®s, 0, 0); send_sig(SIGFPE, current, 1); }
void spitfire_insn_access_exception(struct pt_regs *regs, unsigned long sfsr, unsigned long sfar) { enum ctx_state prev_state = exception_enter(); siginfo_t info; if (notify_die(DIE_TRAP, "instruction access exception", regs, 0, 0x8, SIGTRAP) == NOTIFY_STOP) goto out; if (regs->tstate & TSTATE_PRIV) { printk("spitfire_insn_access_exception: SFSR[%016lx] " "SFAR[%016lx], going.\n", sfsr, sfar); die_if_kernel("Iax", regs); } if (test_thread_flag(TIF_32BIT)) { regs->tpc &= 0xffffffff; regs->tnpc &= 0xffffffff; } info.si_signo = SIGSEGV; info.si_errno = 0; info.si_code = SEGV_MAPERR; info.si_addr = (void __user *)regs->tpc; info.si_trapno = 0; force_sig_info(SIGSEGV, &info, current); out: exception_exit(prev_state); }
void sun4v_insn_access_exception(struct pt_regs *regs, unsigned long addr, unsigned long type_ctx) { unsigned short type = (type_ctx >> 16); unsigned short ctx = (type_ctx & 0xffff); siginfo_t info; if (notify_die(DIE_TRAP, "instruction access exception", regs, 0, 0x8, SIGTRAP) == NOTIFY_STOP) return; if (regs->tstate & TSTATE_PRIV) { printk("sun4v_insn_access_exception: ADDR[%016lx] " "CTX[%04x] TYPE[%04x], going.\n", addr, ctx, type); die_if_kernel("Iax", regs); } if (test_thread_flag(TIF_32BIT)) { regs->tpc &= 0xffffffff; regs->tnpc &= 0xffffffff; } info.si_signo = SIGSEGV; info.si_errno = 0; info.si_code = SEGV_MAPERR; info.si_addr = (void __user *) addr; info.si_trapno = 0; force_sig_info(SIGSEGV, &info, current); }
/* * data store error - should only happen if accessing inactive or self-refreshing SDRAM */ asmlinkage void data_store_error(unsigned long esfr1, unsigned long esr15) { die_if_kernel("-- Data Store Error --\n" "ESR15 : %08lx\n", esr15); BUG(); } /* end data_store_error() */
dotraplinkage void do_simd_coprocessor_error(struct pt_regs *regs, long error_code) { conditional_sti(regs); #ifdef CONFIG_X86_32 if (cpu_has_xmm) { /* Handle SIMD FPU exceptions on PIII+ processors. */ ignore_fpu_irq = 1; simd_math_error((void __user *)regs->ip); return; } /* * Handle strange cache flush from user space exception * in all other cases. This is undocumented behaviour. */ if (regs->flags & X86_VM_MASK) { handle_vm86_fault((struct kernel_vm86_regs *)regs, error_code); return; } current->thread.trap_no = 19; current->thread.error_code = error_code; die_if_kernel("cache flush denied", regs, error_code); force_sig(SIGSEGV, current); #else if (!user_mode(regs) && kernel_math_error(regs, "kernel simd math error", 19)) return; simd_math_error((void __user *)regs->ip); #endif }
asmlinkage void do_entDbg(struct pt_regs *regs) { die_if_kernel("Instruction fault", regs, 0, NULL); force_sig_fault(SIGILL, ILL_ILLOPC, (void __user *)regs->pc, 0, current); }
/* * instruction or data access exception */ asmlinkage void memory_access_exception(unsigned long esr0, unsigned long ear0, unsigned long epcr0) { siginfo_t info; #ifdef CONFIG_MMU unsigned long fixup; fixup = search_exception_table(__frame->pc); if (fixup) { __frame->pc = fixup; return; } #endif die_if_kernel("-- Memory Access Exception --\n" "ESR0 : %08lx\n" "EAR0 : %08lx\n" "EPCR0 : %08lx\n", esr0, ear0, epcr0); info.si_signo = SIGSEGV; info.si_code = SEGV_ACCERR; info.si_errno = 0; info.si_addr = NULL; if ((esr0 & (ESRx_VALID | ESR0_EAV)) == (ESRx_VALID | ESR0_EAV)) info.si_addr = (void __user *) ear0; force_sig_info(info.si_signo, &info, current); } /* end memory_access_exception() */
void be_ip22_interrupt(int irq, struct pt_regs *regs) { save_and_clear_buserr(); printk(KERN_ALERT "Bus error, epc == %08lx, ra == %08lx\n", regs->cp0_epc, regs->regs[31]); die_if_kernel("Oops", regs); force_sig(SIGBUS, current); }
asmlinkage void do_entDbg(unsigned long type, unsigned long a1, unsigned long a2, unsigned long a3, unsigned long a4, unsigned long a5, struct pt_regs regs) { die_if_kernel("Instruction fault", ®s, type, 0); force_sig(SIGILL, current); }
void do_priv_instruction(struct pt_regs *regs, unsigned long pc, unsigned long npc, unsigned long psr) { if(psr & PSR_PS) die_if_kernel("Penguin instruction from Penguin mode??!?!", regs); current->tss.sig_address = pc; current->tss.sig_desc = SUBSIG_PRIVINST; send_sig(SIGILL, current, 1); }
asmlinkage void do_reserved(struct pt_regs *regs) { /* * Game over - no way to handle this if it ever occurs. Most probably * caused by a new unknown cpu type or after another deadly * hard/software error. */ die_if_kernel("do_reserved execution Exception", regs); show_regs(regs); panic("Caught reserved exception - should not happen."); }
void do_hw_interrupt(unsigned long type, unsigned long psr, unsigned long pc) { siginfo_t info; if(type < 0x80) { /* Sun OS's puke from bad traps, Linux survives! */ printk("Unimplemented Sparc TRAP, type = %02lx\n", type); die_if_kernel("Whee... Hello Mr. Penguin", current->thread.kregs); } if(psr & PSR_PS) die_if_kernel("Kernel bad trap", current->thread.kregs); info.si_signo = SIGILL; info.si_errno = 0; info.si_code = ILL_ILLTRP; info.si_addr = (void *)pc; info.si_trapno = type - 0x80; force_sig_info(SIGILL, &info, current); }
asmlinkage void do_ov(struct pt_regs *regs) { siginfo_t info; die_if_kernel("do_ov execution Exception", regs); info.si_code = FPE_INTOVF; info.si_signo = SIGFPE; info.si_errno = 0; info.si_addr = (void *)regs->cp0_epc; force_sig_info(SIGFPE, &info, current); }
asmlinkage void compound_exception(unsigned long esfr1, unsigned long esr0, unsigned long esr14, unsigned long esr15, unsigned long msr0, unsigned long msr1) { die_if_kernel("-- Compound Exception --\n" "ESR0 : %08lx\n" "ESR15 : %08lx\n" "ESR15 : %08lx\n" "MSR0 : %08lx\n" "MSR1 : %08lx\n", esr0, esr14, esr15, msr0, msr1); BUG(); } /* end compound_exception() */
void bad_trap_tl1(struct pt_regs *regs, long lvl) { char buffer[32]; if (notify_die(DIE_TRAP_TL1, "bad trap tl1", regs, 0, lvl, SIGTRAP) == NOTIFY_STOP) return; dump_tl1_traplog((struct tl1_traplog *)(regs + 1)); sprintf (buffer, "Bad trap %lx at tl>0", lvl); die_if_kernel (buffer, regs); }
asmlinkage void do_adedata(struct pt_regs *regs) { const struct exception_table_entry *fixup; fixup = search_exception_tables(regs->cp0_epc); if (fixup) { regs->cp0_epc = fixup->fixup; return; } printk("do_ADE-data:ema:0x%08lx:epc:0x%08lx\n", regs->cp0_ema, regs->cp0_epc); die_if_kernel("do_ade execution Exception\n", regs); force_sig(SIGBUS, current); }
void do_memaccess_unaligned(struct pt_regs *regs, unsigned long pc, unsigned long npc, unsigned long psr) { if(regs->psr & PSR_PS) { printk("KERNEL MNA at pc %08lx npc %08lx called by %08lx\n", pc, npc, regs->u_regs[UREG_RETPC]); die_if_kernel("BOGUS", regs); /* die_if_kernel("Kernel MNA access", regs); */ } current->tss.sig_address = pc; current->tss.sig_desc = SUBSIG_PRIVINST; send_sig(SIGBUS, current, 1); }
void do_illegal_instruction(struct pt_regs *regs, unsigned long pc, unsigned long npc, unsigned long psr) { if(psr & PSR_PS) die_if_kernel("Kernel illegal instruction", regs); #ifdef TRAP_DEBUG printk("Ill instr. at pc=%08lx instruction is %08lx\n", regs->pc, *(unsigned long *)regs->pc); #endif current->tss.sig_address = pc; current->tss.sig_desc = SUBSIG_ILLINST; send_sig(SIGILL, current, 1); }
asmlinkage void do_entDbg(struct pt_regs *regs) { siginfo_t info; die_if_kernel("Instruction fault", regs, 0, NULL); info.si_signo = SIGILL; info.si_errno = 0; info.si_code = ILL_ILLOPC; info.si_addr = (void __user *) regs->pc; force_sig_info(SIGILL, &info, current); }
void handle_break(unsigned iir, struct pt_regs *regs) { struct siginfo si; switch(iir) { case 0x00: #ifdef PRINT_USER_FAULTS printk(KERN_DEBUG "break 0,0: pid=%d command='%s'\n", current->pid, current->comm); #endif die_if_kernel("Breakpoint", regs, 0); #ifdef PRINT_USER_FAULTS show_regs(regs); #endif si.si_code = TRAP_BRKPT; si.si_addr = (void *) (regs->iaoq[0] & ~3); si.si_signo = SIGTRAP; force_sig_info(SIGTRAP, &si, current); break; case GDB_BREAK_INSN: die_if_kernel("Breakpoint", regs, 0); handle_gdb_break(regs, TRAP_BRKPT); break; default: #ifdef PRINT_USER_FAULTS printk(KERN_DEBUG "break %#08x: pid=%d command='%s'\n", iir, current->pid, current->comm); show_regs(regs); #endif si.si_signo = SIGTRAP; si.si_code = TRAP_BRKPT; si.si_addr = (void *) (regs->iaoq[0] & ~3); force_sig_info(SIGTRAP, &si, current); return; } }
void do_priv_instruction(struct pt_regs *regs, unsigned long pc, unsigned long npc, unsigned long psr) { siginfo_t info; if(psr & PSR_PS) die_if_kernel("Penguin instruction from Penguin mode??!?!", regs); info.si_signo = SIGILL; info.si_errno = 0; info.si_code = ILL_PRVOPC; info.si_addr = (void *)pc; info.si_trapno = 0; send_sig_info(SIGILL, &info, current); }
int send_fault_sig(struct pt_regs *regs) { siginfo_t siginfo = { 0, 0, 0, }; siginfo.si_signo = current->thread.signo; siginfo.si_code = current->thread.code; siginfo.si_addr = (void *)current->thread.faddr; #ifdef DEBUG printk("send_fault_sig: %p,%d,%d\n", siginfo.si_addr, siginfo.si_signo, siginfo.si_code); #endif if (user_mode(regs)) { force_sig_info(siginfo.si_signo, &siginfo, current); } else { const struct exception_table_entry *fixup; /* Are we prepared to handle this kernel fault? */ if ((fixup = search_exception_tables(regs->pc))) { struct pt_regs *tregs; /* Create a new four word stack frame, discarding the old one. */ regs->stkadj = frame_extra_sizes[regs->format]; tregs = (struct pt_regs *)((ulong)regs + regs->stkadj); tregs->vector = regs->vector; tregs->format = 0; tregs->pc = fixup->fixup; tregs->sr = regs->sr; return -1; } //if (siginfo.si_signo == SIGBUS) // force_sig_info(siginfo.si_signo, // &siginfo, current); /* * Oops. The kernel tried to access some bad page. We'll have to * terminate things with extreme prejudice. */ if ((unsigned long)siginfo.si_addr < PAGE_SIZE) printk(KERN_ALERT "Unable to handle kernel NULL pointer dereference"); else printk(KERN_ALERT "Unable to handle kernel access"); printk(" at virtual address %p\n", siginfo.si_addr); die_if_kernel("Oops", regs, 0 /*error_code*/); do_exit(SIGKILL); } return 1; }
/* * Currently dropped down to debug level */ asmlinkage void do_DataAbort(unsigned long addr, int error_code, struct pt_regs *regs, int fsr) { const struct fsr_info *inf = fsr_info + (fsr & 15); if (!inf->fn(addr, error_code, regs)) return; force_sig(inf->sig, current); printk(KERN_ALERT "Unhandled fault: %s (%X) at 0x%08lx\n", inf->name, fsr, addr); show_pte(current->mm, addr); die_if_kernel("Oops", regs, 0); return; }
void do_hw_interrupt(unsigned long type, unsigned long psr, unsigned long pc) { if(type < 0x80) { /* Sun OS's puke from bad traps, Linux survives! */ printk("Unimplemented Sparc TRAP, type = %02lx\n", type); die_if_kernel("Whee... Hello Mr. Penguin", current->tss.kregs); } if(type == SP_TRAP_SBPT) { send_sig(SIGTRAP, current, 1); return; } current->tss.sig_desc = SUBSIG_BADTRAP(type - 0x80); current->tss.sig_address = pc; send_sig(SIGILL, current, 1); }