/* * arch/xtensa/kernel/traps.c * * Exception handling. * * Derived from code with the following copyrights: * Copyright (C) 1994 - 1999 by Ralf Baechle * Modified for R3000 by Paul M. Antoine, 1995, 1996 * Complete output from die() by Ulf Carlsson, 1998 * Copyright (C) 1999 Silicon Graphics, Inc. * * Essentially rewritten for the Xtensa architecture port. * * Copyright (C) 2001 - 2013 Tensilica Inc. * * Joe Taylor <joe@tensilica.com, joetylr@yahoo.com> * Chris Zankel <chris@zankel.net> * Marc Gauthier<marc@tensilica.com, marc@alumni.uwaterloo.ca> * Kevin Chea * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details.
*/
/* * The vector table must be preceded by a save area (which * implies it must be in RAM, unless one places RAM immediately * before a ROM and puts the vector at the start of the ROM (!))
*/
/* The exception table <exc_table> serves two functions: * 1. it contains three dispatch tables (fast_user, fast_kernel, default-c) * 2. it is a temporary memory buffer for the exception handlers.
*/
/* * Unhandled Exceptions. Kill user task or panic if in kernel space.
*/
void do_unhandled(struct pt_regs *regs)
{
__die_if_kernel("Caught unhandled exception - should not happen",
regs, SIGKILL);
/* If in user mode, send SIGILL signal to current process */
pr_info_ratelimited("Caught unhandled exception in '%s' " "(pid = %d, pc = %#010lx) - should not happen\n" "\tEXCCAUSE is %ld\n",
current->comm, task_pid_nr(current), regs->pc,
regs->exccause);
dump_user_code(regs);
force_sig(SIGILL);
}
#if !(PROFILING_INTLEVEL == XCHAL_EXCM_LEVEL && \
IS_POW2(XTENSA_INTLEVEL_MASK(PROFILING_INTLEVEL))) #warning"Fake NMI is requested for PMM, but there are other IRQs at or above its level." #warning"Fake NMI will be used, but there will be a bugcheck if one of those IRQs fire."
/* * Illegal instruction. Fatal if in kernel space.
*/
staticvoid do_illegal_instruction(struct pt_regs *regs)
{ #ifdef CONFIG_USER_ABI_CALL0_PROBE /* * When call0 application encounters an illegal instruction fast * exception handler will attempt to set PS.WOE and retry failing * instruction. * If we get here we know that that instruction is also illegal * with PS.WOE set, so it's not related to the windowed option * hence PS.WOE may be cleared.
*/ if (regs->pc == current_thread_info()->ps_woe_fix_addr)
regs->ps &= ~PS_WOE_MASK; #endif if (check_div0(regs)) {
do_div0(regs); return;
}
__die_if_kernel("Illegal instruction in kernel", regs, SIGKILL);
/* If in user mode, send SIGILL signal to current process. */
pr_info_ratelimited("Illegal Instruction in '%s' (pid = %d, pc = %#010lx)\n",
current->comm, task_pid_nr(current), regs->pc);
force_sig(SIGILL);
}
staticvoid do_div0(struct pt_regs *regs)
{
__die_if_kernel("Unhandled division by 0 in kernel", regs, SIGKILL);
force_sig_fault(SIGFPE, FPE_INTDIV, (void __user *)regs->pc);
}
pr_info_ratelimited("Load/store error to %08lx in '%s' (pid = %d, pc = %#010lx)\n",
regs->excvaddr, current->comm,
task_pid_nr(current), regs->pc);
force_sig_fault(SIGBUS, BUS_ADRERR, (void *)regs->excvaddr);
} #endif
/* * Handle unaligned memory accesses from user space. Kill task. * * If CONFIG_UNALIGNED_USER is not set, we don't allow unaligned memory * accesses causes from user space.
*/
/* Handle debug events. * When CONFIG_HAVE_HW_BREAKPOINT is on this handler is called with * preemption disabled to avoid rescheduling and keep mapping of hardware * breakpoint structures to debug registers intact, so that * DEBUGCAUSE.DBNUM could be used in case of data breakpoint hit.
*/ staticvoid do_debug(struct pt_regs *regs)
{ #ifdef CONFIG_HAVE_HW_BREAKPOINT int ret = check_hw_breakpoint(regs);
preempt_enable(); if (ret == 0) return; #endif
__die_if_kernel("Breakpoint in kernel", regs, SIGKILL);
/* If in user mode, send SIGTRAP signal to current process */
/* * Initialize dispatch tables. * * The exception vectors are stored compressed the __init section in the * dispatch_init_table. This function initializes the following three tables * from that compressed table: * - fast user first dispatch table for user exceptions * - fast kernel first dispatch table for kernel exceptions * - default C-handler C-handler called by the default fast handler. * * See vectors.S for more details.
*/
void __init trap_init(void)
{ int i;
/* Setup default vectors. */
for (i = 0; i < EXCCAUSE_N; i++) {
set_handler(fast_user_handler, i, user_exception);
set_handler(fast_kernel_handler, i, kernel_exception);
set_handler(default_handler, i, do_unhandled);
}
/* Setup specific handlers. */
for(i = 0; dispatch_init_table[i].cause >= 0; i++) { int fast = dispatch_init_table[i].fast; int cause = dispatch_init_table[i].cause; void *handler = dispatch_init_table[i].handler;
if (fast == 0)
set_handler(default_handler, cause, handler); if ((fast & USER) != 0)
set_handler(fast_user_handler, cause, handler); if ((fast & KRNL) != 0)
set_handler(fast_kernel_handler, cause, handler);
}
/* Initialize EXCSAVE_1 to hold the address of the exception table. */
trap_init_excsave();
trap_init_debug();
}
if (in_interrupt())
panic("Fatal exception in interrupt");
if (panic_on_oops)
panic("Fatal exception");
make_task_dead(err);
}
Messung V0.5
¤ Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.0.23Bemerkung:
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.