aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh/kernel/traps.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sh/kernel/traps.c')
-rw-r--r--arch/sh/kernel/traps.c73
1 files changed, 37 insertions, 36 deletions
diff --git a/arch/sh/kernel/traps.c b/arch/sh/kernel/traps.c
index e9f168f60f95..7b40f0ff3dfc 100644
--- a/arch/sh/kernel/traps.c
+++ b/arch/sh/kernel/traps.c
@@ -5,7 +5,7 @@
5 * SuperH version: Copyright (C) 1999 Niibe Yutaka 5 * SuperH version: Copyright (C) 1999 Niibe Yutaka
6 * Copyright (C) 2000 Philipp Rumpf 6 * Copyright (C) 2000 Philipp Rumpf
7 * Copyright (C) 2000 David Howells 7 * Copyright (C) 2000 David Howells
8 * Copyright (C) 2002 - 2006 Paul Mundt 8 * Copyright (C) 2002 - 2007 Paul Mundt
9 * 9 *
10 * This file is subject to the terms and conditions of the GNU General Public 10 * This file is subject to the terms and conditions of the GNU General Public
11 * License. See the file "COPYING" in the main directory of this archive 11 * License. See the file "COPYING" in the main directory of this archive
@@ -18,10 +18,12 @@
18#include <linux/module.h> 18#include <linux/module.h>
19#include <linux/kallsyms.h> 19#include <linux/kallsyms.h>
20#include <linux/io.h> 20#include <linux/io.h>
21#include <linux/bug.h>
21#include <linux/debug_locks.h> 22#include <linux/debug_locks.h>
22#include <linux/limits.h> 23#include <linux/limits.h>
23#include <asm/system.h> 24#include <asm/system.h>
24#include <asm/uaccess.h> 25#include <asm/uaccess.h>
26#include <asm/kdebug.h>
25 27
26#ifdef CONFIG_SH_KGDB 28#ifdef CONFIG_SH_KGDB
27#include <asm/kgdb.h> 29#include <asm/kgdb.h>
@@ -74,7 +76,21 @@ static void dump_mem(const char *str, unsigned long bottom, unsigned long top)
74 } 76 }
75} 77}
76 78
77DEFINE_SPINLOCK(die_lock); 79ATOMIC_NOTIFIER_HEAD(shdie_chain);
80
81int register_die_notifier(struct notifier_block *nb)
82{
83 return atomic_notifier_chain_register(&shdie_chain, nb);
84}
85EXPORT_SYMBOL(register_die_notifier);
86
87int unregister_die_notifier(struct notifier_block *nb)
88{
89 return atomic_notifier_chain_unregister(&shdie_chain, nb);
90}
91EXPORT_SYMBOL(unregister_die_notifier);
92
93static DEFINE_SPINLOCK(die_lock);
78 94
79void die(const char * str, struct pt_regs * regs, long err) 95void die(const char * str, struct pt_regs * regs, long err)
80{ 96{
@@ -130,40 +146,6 @@ static int die_if_no_fixup(const char * str, struct pt_regs * regs, long err)
130 return -EFAULT; 146 return -EFAULT;
131} 147}
132 148
133#ifdef CONFIG_BUG
134#ifdef CONFIG_DEBUG_BUGVERBOSE
135static inline void do_bug_verbose(struct pt_regs *regs)
136{
137 struct bug_frame f;
138 long len;
139
140 if (__copy_from_user(&f, (const void __user *)regs->pc,
141 sizeof(struct bug_frame)))
142 return;
143
144 len = __strnlen_user(f.file, PATH_MAX) - 1;
145 if (unlikely(len < 0 || len >= PATH_MAX))
146 f.file = "<bad filename>";
147 len = __strnlen_user(f.func, PATH_MAX) - 1;
148 if (unlikely(len < 0 || len >= PATH_MAX))
149 f.func = "<bad function>";
150
151 printk(KERN_ALERT "kernel BUG in %s() at %s:%d!\n",
152 f.func, f.file, f.line);
153}
154#else
155static inline void do_bug_verbose(struct pt_regs *regs)
156{
157}
158#endif /* CONFIG_DEBUG_BUGVERBOSE */
159
160void handle_BUG(struct pt_regs *regs)
161{
162 do_bug_verbose(regs);
163 die("Kernel BUG", regs, TRAPA_BUG_OPCODE & 0xff);
164}
165#endif /* CONFIG_BUG */
166
167/* 149/*
168 * handle an instruction that does an unaligned memory access by emulating the 150 * handle an instruction that does an unaligned memory access by emulating the
169 * desired behaviour 151 * desired behaviour
@@ -888,6 +870,25 @@ void __init trap_init(void)
888 per_cpu_trap_init(); 870 per_cpu_trap_init();
889} 871}
890 872
873#ifdef CONFIG_BUG
874void handle_BUG(struct pt_regs *regs)
875{
876 enum bug_trap_type tt;
877 tt = report_bug(regs->pc);
878 if (tt == BUG_TRAP_TYPE_WARN) {
879 regs->pc += 2;
880 return;
881 }
882
883 die("Kernel BUG", regs, TRAPA_BUG_OPCODE & 0xff);
884}
885
886int is_valid_bugaddr(unsigned long addr)
887{
888 return addr >= PAGE_OFFSET;
889}
890#endif
891
891void show_trace(struct task_struct *tsk, unsigned long *sp, 892void show_trace(struct task_struct *tsk, unsigned long *sp,
892 struct pt_regs *regs) 893 struct pt_regs *regs)
893{ 894{