···11-/*22- * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com)33- *44- * This program is free software; you can redistribute it and/or modify55- * it under the terms of the GNU General Public License version 2 as66- * published by the Free Software Foundation.77- */
+125
arch/arc/kernel/traps.c
···11+/*22+ * Traps/Non-MMU Exception handling for ARC33+ *44+ * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com)55+ *66+ * This program is free software; you can redistribute it and/or modify77+ * it under the terms of the GNU General Public License version 2 as88+ * published by the Free Software Foundation.99+ *1010+ * Rahul Trivedi: Codito Technologies 20041111+ */1212+1313+#include <linux/sched.h>1414+#include <linux/kdebug.h>1515+#include <linux/uaccess.h>1616+#include <asm/ptrace.h>1717+#include <asm/setup.h>1818+1919+void __init trap_init(void)2020+{2121+ return;2222+}2323+2424+void die(const char *str, struct pt_regs *regs, unsigned long address,2525+ unsigned long cause_reg)2626+{2727+ show_kernel_fault_diag(str, regs, address, cause_reg);2828+2929+ /* DEAD END */3030+ __asm__("flag 1");3131+}3232+3333+/*3434+ * Helper called for bulk of exceptions NOT needing specific handling3535+ * -for user faults enqueues requested signal3636+ * -for kernel, chk if due to copy_(to|from)_user, otherwise die()3737+ */3838+static noinline int handle_exception(unsigned long cause, char *str,3939+ struct pt_regs *regs, siginfo_t *info)4040+{4141+ if (user_mode(regs)) {4242+ struct task_struct *tsk = current;4343+4444+ tsk->thread.fault_address = (__force unsigned int)info->si_addr;4545+ tsk->thread.cause_code = cause;4646+4747+ force_sig_info(info->si_signo, info, tsk);4848+4949+ } else {5050+ /* If not due to copy_(to|from)_user, we are doomed */5151+ if (fixup_exception(regs))5252+ return 0;5353+5454+ die(str, regs, (unsigned long)info->si_addr, cause);5555+ }5656+5757+ return 1;5858+}5959+6060+#define DO_ERROR_INFO(signr, str, name, sicode) \6161+int name(unsigned long cause, unsigned long address, struct pt_regs *regs) \6262+{ \6363+ siginfo_t info = { \6464+ .si_signo = signr, \6565+ .si_errno = 0, \6666+ .si_code = sicode, \6767+ .si_addr = (void __user *)address, \6868+ }; \6969+ return handle_exception(cause, str, regs, &info);\7070+}7171+7272+/*7373+ * Entry points for exceptions NOT needing specific handling7474+ */7575+DO_ERROR_INFO(SIGILL, "Priv Op/Disabled Extn", do_privilege_fault, ILL_PRVOPC)7676+DO_ERROR_INFO(SIGILL, "Invalid Extn Insn", do_extension_fault, ILL_ILLOPC)7777+DO_ERROR_INFO(SIGILL, "Illegal Insn (or Seq)", insterror_is_error, ILL_ILLOPC)7878+DO_ERROR_INFO(SIGBUS, "Invalid Mem Access", do_memory_error, BUS_ADRERR)7979+DO_ERROR_INFO(SIGTRAP, "Breakpoint Set", trap_is_brkpt, TRAP_BRKPT)8080+8181+DO_ERROR_INFO(SIGSEGV, "Misaligned Access", do_misaligned_access, SEGV_ACCERR)8282+8383+/*8484+ * Entry point for miscll errors such as Nested Exceptions8585+ * -Duplicate TLB entry is handled seperately though8686+ */8787+void do_machine_check_fault(unsigned long cause, unsigned long address,8888+ struct pt_regs *regs)8989+{9090+ die("Machine Check Exception", regs, address, cause);9191+}9292+9393+/*9494+ * Entry point for traps induced by ARCompact TRAP_S <n> insn9595+ * This is same family as TRAP0/SWI insn (use the same vector).9696+ * The only difference being SWI insn take no operand, while TRAP_S does9797+ * which reflects in ECR Reg as 8 bit param.9898+ * Thus TRAP_S <n> can be used for specific purpose9999+ * -1 used for software breakpointing (gdb)100100+ * -2 used by kprobes101101+ */102102+void do_non_swi_trap(unsigned long cause, unsigned long address,103103+ struct pt_regs *regs)104104+{105105+ unsigned int param = cause & 0xff;106106+107107+ switch (param) {108108+ case 1:109109+ trap_is_brkpt(cause, address, regs);110110+ break;111111+112112+ default:113113+ break;114114+ }115115+}116116+117117+/*118118+ * Entry point for Instruction Error Exception119119+ */120120+void do_insterror_or_kprobe(unsigned long cause,121121+ unsigned long address,122122+ struct pt_regs *regs)123123+{124124+ insterror_is_error(cause, address, regs);125125+}