traps.c (552c69b36ebd966186573b9c7a286b390935cce1) traps.c (4445229445273da16cc3a4928e3ba327b0301e7f)
1/*
2 * Traps/Non-MMU Exception handling for ARC
3 *
4 * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com)
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.

--- 28 unchanged lines hidden (view full) ---

37}
38
39/*
40 * Helper called for bulk of exceptions NOT needing specific handling
41 * -for user faults enqueues requested signal
42 * -for kernel, chk if due to copy_(to|from)_user, otherwise die()
43 */
44static noinline int
1/*
2 * Traps/Non-MMU Exception handling for ARC
3 *
4 * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com)
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.

--- 28 unchanged lines hidden (view full) ---

37}
38
39/*
40 * Helper called for bulk of exceptions NOT needing specific handling
41 * -for user faults enqueues requested signal
42 * -for kernel, chk if due to copy_(to|from)_user, otherwise die()
43 */
44static noinline int
45unhandled_exception(const char *str, struct pt_regs *regs, siginfo_t *info)
45unhandled_exception(const char *str, struct pt_regs *regs,
46 int signo, int si_code, void __user *addr)
46{
47 if (user_mode(regs)) {
48 struct task_struct *tsk = current;
49
47{
48 if (user_mode(regs)) {
49 struct task_struct *tsk = current;
50
50 tsk->thread.fault_address = (__force unsigned int)info->si_addr;
51 tsk->thread.fault_address = (__force unsigned int)addr;
51
52
52 force_sig_info(info->si_signo, info, tsk);
53 force_sig_fault(signo, si_code, addr, tsk);
53
54 } else {
55 /* If not due to copy_(to|from)_user, we are doomed */
56 if (fixup_exception(regs))
57 return 0;
58
54
55 } else {
56 /* If not due to copy_(to|from)_user, we are doomed */
57 if (fixup_exception(regs))
58 return 0;
59
59 die(str, regs, (unsigned long)info->si_addr);
60 die(str, regs, (unsigned long)addr);
60 }
61
62 return 1;
63}
64
65#define DO_ERROR_INFO(signr, str, name, sicode) \
66int name(unsigned long address, struct pt_regs *regs) \
61 }
62
63 return 1;
64}
65
66#define DO_ERROR_INFO(signr, str, name, sicode) \
67int name(unsigned long address, struct pt_regs *regs) \
67{ \
68 siginfo_t info; \
69 \
70 clear_siginfo(&info); \
71 info.si_signo = signr; \
72 info.si_errno = 0; \
73 info.si_code = sicode; \
74 info.si_addr = (void __user *)address; \
75 \
76 return unhandled_exception(str, regs, &info);\
68{ \
69 return unhandled_exception(str, regs, signr, sicode, \
70 (void __user *)address); \
77}
78
79/*
80 * Entry points for exceptions NOT needing specific handling
81 */
82DO_ERROR_INFO(SIGILL, "Priv Op/Disabled Extn", do_privilege_fault, ILL_PRVOPC)
83DO_ERROR_INFO(SIGILL, "Invalid Extn Insn", do_extension_fault, ILL_ILLOPC)
84DO_ERROR_INFO(SIGILL, "Illegal Insn (or Seq)", insterror_is_error, ILL_ILLOPC)

--- 89 unchanged lines hidden ---
71}
72
73/*
74 * Entry points for exceptions NOT needing specific handling
75 */
76DO_ERROR_INFO(SIGILL, "Priv Op/Disabled Extn", do_privilege_fault, ILL_PRVOPC)
77DO_ERROR_INFO(SIGILL, "Invalid Extn Insn", do_extension_fault, ILL_ILLOPC)
78DO_ERROR_INFO(SIGILL, "Illegal Insn (or Seq)", insterror_is_error, ILL_ILLOPC)

--- 89 unchanged lines hidden ---