diff options
author | Olof Johansson <olof@lixom.net> | 2007-09-21 05:11:20 +1000 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2007-10-03 09:11:58 +1000 |
commit | 75918a4b5998c93ee1ab131fbe64b97b5d0d2315 (patch) | |
tree | f342b9101f48da82b9bd62e8b18a0f1af8a78357 /arch/powerpc/kernel | |
parent | 6f6682809b994fd9a61081fa0410df31481d5f7f (diff) |
[POWERPC] Separate out legacy machine check exception parsers
Move out the old-style exception parsers to a separate function, and
don't call it on platforms that have a platform-specific handler.
It would make sense to move out the generic versions into their platforms
instead, but that can be done gradually down the road.
Signed-off-by: Olof Johansson <olof@lixom.net>
Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch/powerpc/kernel')
-rw-r--r-- | arch/powerpc/kernel/traps.c | 66 |
1 files changed, 37 insertions, 29 deletions
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c index ccfc99dad06..5a49eabd492 100644 --- a/arch/powerpc/kernel/traps.c +++ b/arch/powerpc/kernel/traps.c @@ -324,38 +324,10 @@ static inline int check_io_access(struct pt_regs *regs) #define clear_single_step(regs) ((regs)->msr &= ~MSR_SE) #endif -void machine_check_exception(struct pt_regs *regs) +static int generic_machine_check_exception(struct pt_regs *regs) { - int recover = 0; unsigned long reason = get_mc_reason(regs); - /* See if any machine dependent calls */ - if (ppc_md.machine_check_exception) - recover = ppc_md.machine_check_exception(regs); - - if (recover) - return; - - if (user_mode(regs)) { - regs->msr |= MSR_RI; - _exception(SIGBUS, regs, BUS_ADRERR, regs->nip); - return; - } - -#if defined(CONFIG_8xx) && defined(CONFIG_PCI) - /* the qspan pci read routines can cause machine checks -- Cort */ - bad_page_fault(regs, regs->dar, SIGBUS); - return; -#endif - - if (debugger_fault_handler(regs)) { - regs->msr |= MSR_RI; - return; - } - - if (check_io_access(regs)) - return; - #if defined(CONFIG_4xx) && !defined(CONFIG_440A) if (reason & ESR_IMCP) { printk("Instruction"); @@ -471,6 +443,42 @@ void machine_check_exception(struct pt_regs *regs) } #endif /* CONFIG_4xx */ + return 0; +} + +void machine_check_exception(struct pt_regs *regs) +{ + int recover = 0; + + /* See if any machine dependent calls */ + if (ppc_md.machine_check_exception) + recover = ppc_md.machine_check_exception(regs); + else + recover = generic_machine_check_exception(regs); + + if (recover) + return; + + if (user_mode(regs)) { + regs->msr |= MSR_RI; + _exception(SIGBUS, regs, BUS_ADRERR, regs->nip); + return; + } + +#if defined(CONFIG_8xx) && defined(CONFIG_PCI) + /* the qspan pci read routines can cause machine checks -- Cort */ + bad_page_fault(regs, regs->dar, SIGBUS); + return; +#endif + + if (debugger_fault_handler(regs)) { + regs->msr |= MSR_RI; + return; + } + + if (check_io_access(regs)) + return; + if (debugger_fault_handler(regs)) return; die("Machine check", regs, SIGBUS); |