From: James S. <jsi...@us...> - 2001-08-21 17:25:39
|
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; |