void do_report_trap(struct pt_regs *regs, int si_signo, int si_code, char *str) { siginfo_t info; if (user_mode(regs)) { info.si_signo = si_signo; info.si_errno = 0; info.si_code = si_code; info.si_addr = get_trap_ip(regs); force_sig_info(si_signo, &info, current); report_user_fault(regs, si_signo); } else { const struct exception_table_entry *fixup; fixup = search_exception_tables(regs->psw.addr & PSW_ADDR_INSN); if (fixup) regs->psw.addr = extable_fixup(fixup) | PSW_ADDR_AMODE; else { enum bug_trap_type btt; btt = report_bug(regs->psw.addr & PSW_ADDR_INSN, regs); if (btt == BUG_TRAP_TYPE_WARN) return; die(regs, str); } } }
void default_trap_handler(struct pt_regs *regs) { if (user_mode(regs)) { report_user_fault(regs, SIGSEGV); do_exit(SIGSEGV); } else die(regs, "Unknown program exception"); }
/* * Send SIGSEGV to task. This is an external routine * to keep the stack usage of do_page_fault small. */ static noinline void do_sigsegv(struct pt_regs *regs, int si_code) { struct siginfo si; report_user_fault(regs, SIGSEGV); si.si_signo = SIGSEGV; si.si_code = si_code; si.si_addr = (void __user *)(regs->int_parm_long & __FAIL_ADDR_MASK); force_sig_info(SIGSEGV, &si, current); }
/* * Send SIGSEGV to task. This is an external routine * to keep the stack usage of do_page_fault small. */ static noinline void do_sigsegv(struct pt_regs *regs, long int_code, int si_code, unsigned long trans_exc_code) { struct siginfo si; unsigned long address; address = trans_exc_code & __FAIL_ADDR_MASK; current->thread.prot_addr = address; current->thread.trap_no = int_code; report_user_fault(regs, int_code, SIGSEGV, address); si.si_signo = SIGSEGV; si.si_code = si_code; si.si_addr = (void __user *) address; force_sig_info(SIGSEGV, &si, current); }