Update of /cvsroot/linux-mips/linux/arch/mips/kernel
In directory usw-pr-cvs1:/tmp/cvs-serv19122
Modified Files:
traps.c
Log Message:
Support catching data bus errors also from withim modules.
Index: traps.c
===================================================================
RCS file: /cvsroot/linux-mips/linux/arch/mips/kernel/traps.c,v
retrieving revision 1.10
retrieving revision 1.11
diff -C2 -d -r1.10 -r1.11
*** traps.c 2001/08/18 18:04:54 1.10
--- traps.c 2001/08/21 17:25:35 1.11
***************
*** 15,18 ****
--- 15,19 ----
#include <linux/init.h>
#include <linux/mm.h>
+ #include <linux/module.h>
#include <linux/sched.h>
#include <linux/smp.h>
***************
*** 26,29 ****
--- 27,31 ----
#include <asm/inst.h>
#include <asm/jazz.h>
+ #include <asm/module.h>
#include <asm/pgtable.h>
#include <asm/io.h>
***************
*** 246,261 ****
}
! #define search_dbe_table(addr) \
! search_one_table(__start___dbe_table, __stop___dbe_table - 1, (addr))
static void default_be_board_handler(struct pt_regs *regs)
{
unsigned long new_epc;
! unsigned long fixup = search_dbe_table(regs->cp0_epc);
! if (fixup) {
! new_epc = fixup_exception(dpf_reg, fixup, regs->cp0_epc);
! regs->cp0_epc = new_epc;
! return;
}
--- 248,303 ----
}
! extern spinlock_t modlist_lock;
!
! static inline unsigned long
! search_dbe_table(unsigned long addr)
! {
! unsigned long ret = 0;
!
! #ifndef CONFIG_MODULES
! /* There is only the kernel to search. */
! ret = search_one_table(__start___dbe_table, __stop___dbe_table-1, addr);
! return ret;
! #else
! unsigned long flags;
!
! /* The kernel is the last "module" -- no need to treat it special. */
! struct module *mp;
! struct archdata *ap;
!
! spin_lock_irqsave(&modlist_lock, flags);
! for (mp = module_list; mp != NULL; mp = mp->next) {
! if (!mod_member_present(mp, archdata_start) ||
! !mp->archdata_start)
! continue;
! ap = (struct archdata *)(mp->archdata_start);
!
! if (ap->dbe_table_start == NULL ||
! !(mp->flags & (MOD_RUNNING | MOD_INITIALIZING)))
! continue;
! ret = search_one_table(ap->dbe_table_start,
! ap->dbe_table_end - 1, addr);
! if (ret)
! break;
! }
! spin_unlock_irqrestore(&modlist_lock, flags);
! return ret;
! #endif
! }
static void default_be_board_handler(struct pt_regs *regs)
{
unsigned long new_epc;
! unsigned long fixup;
! int data = regs->cp0_cause & 4;
! if (data && !user_mode(regs)) {
! fixup = search_dbe_table(regs->cp0_epc);
! if (fixup) {
! new_epc = fixup_exception(dpf_reg, fixup,
! regs->cp0_epc);
! regs->cp0_epc = new_epc;
! return;
! }
}
***************
*** 263,266 ****
--- 305,312 ----
* Assume it would be too dangerous to continue ...
*/
+ printk(KERN_ALERT "%s bus error, epc == %08lx, ra == %08lx\n",
+ data ? "Data" : "Instruction",
+ regs->cp0_epc, regs->regs[31]);
+ die_if_kernel("Oops", regs);
force_sig(SIGBUS, current);
}
***************
*** 738,742 ****
void __init trap_init(void)
{
! extern char except_vec0_nevada, except_vec0_r4000, except_vec0_vr41xx;
extern char except_vec0_r4600, except_vec0_r2300;
extern char except_vec1_generic, except_vec2_generic;
--- 784,788 ----
void __init trap_init(void)
{
! extern char except_vec0_nevada, except_vec0_r4000;
extern char except_vec0_r4600, except_vec0_r2300;
extern char except_vec1_generic, except_vec2_generic;
|