mirror of
https://github.com/fail0verflow/switch-linux.git
synced 2025-05-04 02:34:21 -04:00
ARM: add notify_die() support
Kernel debuggers want to be informed of die() events, so that they can take some action to allow the problem to be inspected. Provide the hook in a similar manner to x86. Note that we currently don't implement the individual trap hooks. Acked-by: Jason Wessel <jason.wessel@windriver.com> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
This commit is contained in:
parent
2b0d8c251b
commit
a9221de66d
2 changed files with 27 additions and 13 deletions
|
@ -73,8 +73,7 @@ extern unsigned int mem_fclk_21285;
|
||||||
|
|
||||||
struct pt_regs;
|
struct pt_regs;
|
||||||
|
|
||||||
void die(const char *msg, struct pt_regs *regs, int err)
|
void die(const char *msg, struct pt_regs *regs, int err);
|
||||||
__attribute__((noreturn));
|
|
||||||
|
|
||||||
struct siginfo;
|
struct siginfo;
|
||||||
void arm_notify_die(const char *str, struct pt_regs *regs, struct siginfo *info,
|
void arm_notify_die(const char *str, struct pt_regs *regs, struct siginfo *info,
|
||||||
|
|
|
@ -12,15 +12,17 @@
|
||||||
* 'linux/arch/arm/lib/traps.S'. Mostly a debugging aid, but will probably
|
* 'linux/arch/arm/lib/traps.S'. Mostly a debugging aid, but will probably
|
||||||
* kill the offending process.
|
* kill the offending process.
|
||||||
*/
|
*/
|
||||||
#include <linux/module.h>
|
|
||||||
#include <linux/signal.h>
|
#include <linux/signal.h>
|
||||||
#include <linux/spinlock.h>
|
|
||||||
#include <linux/personality.h>
|
#include <linux/personality.h>
|
||||||
#include <linux/kallsyms.h>
|
#include <linux/kallsyms.h>
|
||||||
#include <linux/delay.h>
|
#include <linux/spinlock.h>
|
||||||
#include <linux/hardirq.h>
|
|
||||||
#include <linux/init.h>
|
|
||||||
#include <linux/uaccess.h>
|
#include <linux/uaccess.h>
|
||||||
|
#include <linux/hardirq.h>
|
||||||
|
#include <linux/kdebug.h>
|
||||||
|
#include <linux/module.h>
|
||||||
|
#include <linux/kexec.h>
|
||||||
|
#include <linux/delay.h>
|
||||||
|
#include <linux/init.h>
|
||||||
|
|
||||||
#include <asm/atomic.h>
|
#include <asm/atomic.h>
|
||||||
#include <asm/cacheflush.h>
|
#include <asm/cacheflush.h>
|
||||||
|
@ -224,14 +226,21 @@ void show_stack(struct task_struct *tsk, unsigned long *sp)
|
||||||
#define S_SMP ""
|
#define S_SMP ""
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void __die(const char *str, int err, struct thread_info *thread, struct pt_regs *regs)
|
static int __die(const char *str, int err, struct thread_info *thread, struct pt_regs *regs)
|
||||||
{
|
{
|
||||||
struct task_struct *tsk = thread->task;
|
struct task_struct *tsk = thread->task;
|
||||||
static int die_counter;
|
static int die_counter;
|
||||||
|
int ret;
|
||||||
|
|
||||||
printk(KERN_EMERG "Internal error: %s: %x [#%d]" S_PREEMPT S_SMP "\n",
|
printk(KERN_EMERG "Internal error: %s: %x [#%d]" S_PREEMPT S_SMP "\n",
|
||||||
str, err, ++die_counter);
|
str, err, ++die_counter);
|
||||||
sysfs_printk_last_file();
|
sysfs_printk_last_file();
|
||||||
|
|
||||||
|
/* trap and error numbers are mostly meaningless on ARM */
|
||||||
|
ret = notify_die(DIE_OOPS, str, regs, err, tsk->thread.trap_no, SIGSEGV);
|
||||||
|
if (ret == NOTIFY_STOP)
|
||||||
|
return ret;
|
||||||
|
|
||||||
print_modules();
|
print_modules();
|
||||||
__show_regs(regs);
|
__show_regs(regs);
|
||||||
printk(KERN_EMERG "Process %.*s (pid: %d, stack limit = 0x%p)\n",
|
printk(KERN_EMERG "Process %.*s (pid: %d, stack limit = 0x%p)\n",
|
||||||
|
@ -243,6 +252,8 @@ static void __die(const char *str, int err, struct thread_info *thread, struct p
|
||||||
dump_backtrace(regs, tsk);
|
dump_backtrace(regs, tsk);
|
||||||
dump_instr(KERN_EMERG, regs);
|
dump_instr(KERN_EMERG, regs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
DEFINE_SPINLOCK(die_lock);
|
DEFINE_SPINLOCK(die_lock);
|
||||||
|
@ -250,16 +261,21 @@ DEFINE_SPINLOCK(die_lock);
|
||||||
/*
|
/*
|
||||||
* This function is protected against re-entrancy.
|
* This function is protected against re-entrancy.
|
||||||
*/
|
*/
|
||||||
NORET_TYPE void die(const char *str, struct pt_regs *regs, int err)
|
void die(const char *str, struct pt_regs *regs, int err)
|
||||||
{
|
{
|
||||||
struct thread_info *thread = current_thread_info();
|
struct thread_info *thread = current_thread_info();
|
||||||
|
int ret;
|
||||||
|
|
||||||
oops_enter();
|
oops_enter();
|
||||||
|
|
||||||
spin_lock_irq(&die_lock);
|
spin_lock_irq(&die_lock);
|
||||||
console_verbose();
|
console_verbose();
|
||||||
bust_spinlocks(1);
|
bust_spinlocks(1);
|
||||||
__die(str, err, thread, regs);
|
ret = __die(str, err, thread, regs);
|
||||||
|
|
||||||
|
if (regs && kexec_should_crash(thread->task))
|
||||||
|
crash_kexec(regs);
|
||||||
|
|
||||||
bust_spinlocks(0);
|
bust_spinlocks(0);
|
||||||
add_taint(TAINT_DIE);
|
add_taint(TAINT_DIE);
|
||||||
spin_unlock_irq(&die_lock);
|
spin_unlock_irq(&die_lock);
|
||||||
|
@ -267,10 +283,9 @@ NORET_TYPE void die(const char *str, struct pt_regs *regs, int err)
|
||||||
|
|
||||||
if (in_interrupt())
|
if (in_interrupt())
|
||||||
panic("Fatal exception in interrupt");
|
panic("Fatal exception in interrupt");
|
||||||
|
|
||||||
if (panic_on_oops)
|
if (panic_on_oops)
|
||||||
panic("Fatal exception");
|
panic("Fatal exception");
|
||||||
|
if (ret != NOTIFY_STOP)
|
||||||
do_exit(SIGSEGV);
|
do_exit(SIGSEGV);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue