aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel/traps.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/kernel/traps.c')
-rw-r--r--arch/powerpc/kernel/traps.c81
1 files changed, 55 insertions, 26 deletions
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index a45a63c3a0c7..1a0141426cda 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -34,6 +34,7 @@
34#include <linux/bug.h> 34#include <linux/bug.h>
35#include <linux/kdebug.h> 35#include <linux/kdebug.h>
36#include <linux/debugfs.h> 36#include <linux/debugfs.h>
37#include <linux/ratelimit.h>
37 38
38#include <asm/emulated_ops.h> 39#include <asm/emulated_ops.h>
39#include <asm/pgtable.h> 40#include <asm/pgtable.h>
@@ -55,6 +56,7 @@
55#endif 56#endif
56#include <asm/kexec.h> 57#include <asm/kexec.h>
57#include <asm/ppc-opcode.h> 58#include <asm/ppc-opcode.h>
59#include <asm/rio.h>
58 60
59#if defined(CONFIG_DEBUGGER) || defined(CONFIG_KEXEC) 61#if defined(CONFIG_DEBUGGER) || defined(CONFIG_KEXEC)
60int (*__debugger)(struct pt_regs *regs) __read_mostly; 62int (*__debugger)(struct pt_regs *regs) __read_mostly;
@@ -143,7 +145,6 @@ int die(const char *str, struct pt_regs *regs, long err)
143#endif 145#endif
144 printk("%s\n", ppc_md.name ? ppc_md.name : ""); 146 printk("%s\n", ppc_md.name ? ppc_md.name : "");
145 147
146 sysfs_printk_last_file();
147 if (notify_die(DIE_OOPS, str, regs, err, 255, 148 if (notify_die(DIE_OOPS, str, regs, err, 255,
148 SIGSEGV) == NOTIFY_STOP) 149 SIGSEGV) == NOTIFY_STOP)
149 return 1; 150 return 1;
@@ -197,12 +198,11 @@ void _exception(int signr, struct pt_regs *regs, int code, unsigned long addr)
197 if (die("Exception in kernel mode", regs, signr)) 198 if (die("Exception in kernel mode", regs, signr))
198 return; 199 return;
199 } else if (show_unhandled_signals && 200 } else if (show_unhandled_signals &&
200 unhandled_signal(current, signr) && 201 unhandled_signal(current, signr)) {
201 printk_ratelimit()) { 202 printk_ratelimited(regs->msr & MSR_64BIT ? fmt64 : fmt32,
202 printk(regs->msr & MSR_SF ? fmt64 : fmt32, 203 current->comm, current->pid, signr,
203 current->comm, current->pid, signr, 204 addr, regs->nip, regs->link, code);
204 addr, regs->nip, regs->link, code); 205 }
205 }
206 206
207 memset(&info, 0, sizeof(info)); 207 memset(&info, 0, sizeof(info));
208 info.si_signo = signr; 208 info.si_signo = signr;
@@ -221,7 +221,7 @@ void system_reset_exception(struct pt_regs *regs)
221 } 221 }
222 222
223#ifdef CONFIG_KEXEC 223#ifdef CONFIG_KEXEC
224 cpu_set(smp_processor_id(), cpus_in_sr); 224 cpumask_set_cpu(smp_processor_id(), &cpus_in_sr);
225#endif 225#endif
226 226
227 die("System Reset", regs, SIGABRT); 227 die("System Reset", regs, SIGABRT);
@@ -425,6 +425,12 @@ int machine_check_e500mc(struct pt_regs *regs)
425 unsigned long reason = mcsr; 425 unsigned long reason = mcsr;
426 int recoverable = 1; 426 int recoverable = 1;
427 427
428 if (reason & MCSR_LD) {
429 recoverable = fsl_rio_mcheck_exception(regs);
430 if (recoverable == 1)
431 goto silent_out;
432 }
433
428 printk("Machine check in kernel mode.\n"); 434 printk("Machine check in kernel mode.\n");
429 printk("Caused by (from MCSR=%lx): ", reason); 435 printk("Caused by (from MCSR=%lx): ", reason);
430 436
@@ -500,6 +506,7 @@ int machine_check_e500mc(struct pt_regs *regs)
500 reason & MCSR_MEA ? "Effective" : "Physical", addr); 506 reason & MCSR_MEA ? "Effective" : "Physical", addr);
501 } 507 }
502 508
509silent_out:
503 mtspr(SPRN_MCSR, mcsr); 510 mtspr(SPRN_MCSR, mcsr);
504 return mfspr(SPRN_MCSR) == 0 && recoverable; 511 return mfspr(SPRN_MCSR) == 0 && recoverable;
505} 512}
@@ -508,6 +515,11 @@ int machine_check_e500(struct pt_regs *regs)
508{ 515{
509 unsigned long reason = get_mc_reason(regs); 516 unsigned long reason = get_mc_reason(regs);
510 517
518 if (reason & MCSR_BUS_RBERR) {
519 if (fsl_rio_mcheck_exception(regs))
520 return 1;
521 }
522
511 printk("Machine check in kernel mode.\n"); 523 printk("Machine check in kernel mode.\n");
512 printk("Caused by (from MCSR=%lx): ", reason); 524 printk("Caused by (from MCSR=%lx): ", reason);
513 525
@@ -538,6 +550,11 @@ int machine_check_e500(struct pt_regs *regs)
538 550
539 return 0; 551 return 0;
540} 552}
553
554int machine_check_generic(struct pt_regs *regs)
555{
556 return 0;
557}
541#elif defined(CONFIG_E200) 558#elif defined(CONFIG_E200)
542int machine_check_e200(struct pt_regs *regs) 559int machine_check_e200(struct pt_regs *regs)
543{ 560{
@@ -621,12 +638,6 @@ void machine_check_exception(struct pt_regs *regs)
621 if (recover > 0) 638 if (recover > 0)
622 return; 639 return;
623 640
624 if (user_mode(regs)) {
625 regs->msr |= MSR_RI;
626 _exception(SIGBUS, regs, BUS_ADRERR, regs->nip);
627 return;
628 }
629
630#if defined(CONFIG_8xx) && defined(CONFIG_PCI) 641#if defined(CONFIG_8xx) && defined(CONFIG_PCI)
631 /* the qspan pci read routines can cause machine checks -- Cort 642 /* the qspan pci read routines can cause machine checks -- Cort
632 * 643 *
@@ -638,16 +649,12 @@ void machine_check_exception(struct pt_regs *regs)
638 return; 649 return;
639#endif 650#endif
640 651
641 if (debugger_fault_handler(regs)) { 652 if (debugger_fault_handler(regs))
642 regs->msr |= MSR_RI;
643 return; 653 return;
644 }
645 654
646 if (check_io_access(regs)) 655 if (check_io_access(regs))
647 return; 656 return;
648 657
649 if (debugger_fault_handler(regs))
650 return;
651 die("Machine check", regs, SIGBUS); 658 die("Machine check", regs, SIGBUS);
652 659
653 /* Must die if the interrupt is not recoverable */ 660 /* Must die if the interrupt is not recoverable */
@@ -914,6 +921,26 @@ static int emulate_instruction(struct pt_regs *regs)
914 return emulate_isel(regs, instword); 921 return emulate_isel(regs, instword);
915 } 922 }
916 923
924#ifdef CONFIG_PPC64
925 /* Emulate the mfspr rD, DSCR. */
926 if (((instword & PPC_INST_MFSPR_DSCR_MASK) == PPC_INST_MFSPR_DSCR) &&
927 cpu_has_feature(CPU_FTR_DSCR)) {
928 PPC_WARN_EMULATED(mfdscr, regs);
929 rd = (instword >> 21) & 0x1f;
930 regs->gpr[rd] = mfspr(SPRN_DSCR);
931 return 0;
932 }
933 /* Emulate the mtspr DSCR, rD. */
934 if (((instword & PPC_INST_MTSPR_DSCR_MASK) == PPC_INST_MTSPR_DSCR) &&
935 cpu_has_feature(CPU_FTR_DSCR)) {
936 PPC_WARN_EMULATED(mtdscr, regs);
937 rd = (instword >> 21) & 0x1f;
938 mtspr(SPRN_DSCR, regs->gpr[rd]);
939 current->thread.dscr_inherit = 1;
940 return 0;
941 }
942#endif
943
917 return -EINVAL; 944 return -EINVAL;
918} 945}
919 946
@@ -964,7 +991,7 @@ void __kprobes program_check_exception(struct pt_regs *regs)
964 * ESR_DST (!?) or 0. In the process of chasing this with the 991 * ESR_DST (!?) or 0. In the process of chasing this with the
965 * hardware people - not sure if it can happen on any illegal 992 * hardware people - not sure if it can happen on any illegal
966 * instruction or only on FP instructions, whether there is a 993 * instruction or only on FP instructions, whether there is a
967 * pattern to occurences etc. -dgibson 31/Mar/2003 */ 994 * pattern to occurrences etc. -dgibson 31/Mar/2003 */
968 switch (do_mathemu(regs)) { 995 switch (do_mathemu(regs)) {
969 case 0: 996 case 0:
970 emulate_single_step(regs); 997 emulate_single_step(regs);
@@ -1315,9 +1342,8 @@ void altivec_assist_exception(struct pt_regs *regs)
1315 } else { 1342 } else {
1316 /* didn't recognize the instruction */ 1343 /* didn't recognize the instruction */
1317 /* XXX quick hack for now: set the non-Java bit in the VSCR */ 1344 /* XXX quick hack for now: set the non-Java bit in the VSCR */
1318 if (printk_ratelimit()) 1345 printk_ratelimited(KERN_ERR "Unrecognized altivec instruction "
1319 printk(KERN_ERR "Unrecognized altivec instruction " 1346 "in %s at %lx\n", current->comm, regs->nip);
1320 "in %s at %lx\n", current->comm, regs->nip);
1321 current->thread.vscr.u[3] |= 0x10000; 1347 current->thread.vscr.u[3] |= 0x10000;
1322 } 1348 }
1323} 1349}
@@ -1511,15 +1537,18 @@ struct ppc_emulated ppc_emulated = {
1511#ifdef CONFIG_VSX 1537#ifdef CONFIG_VSX
1512 WARN_EMULATED_SETUP(vsx), 1538 WARN_EMULATED_SETUP(vsx),
1513#endif 1539#endif
1540#ifdef CONFIG_PPC64
1541 WARN_EMULATED_SETUP(mfdscr),
1542 WARN_EMULATED_SETUP(mtdscr),
1543#endif
1514}; 1544};
1515 1545
1516u32 ppc_warn_emulated; 1546u32 ppc_warn_emulated;
1517 1547
1518void ppc_warn_emulated_print(const char *type) 1548void ppc_warn_emulated_print(const char *type)
1519{ 1549{
1520 if (printk_ratelimit()) 1550 pr_warn_ratelimited("%s used emulated %s instruction\n", current->comm,
1521 pr_warning("%s used emulated %s instruction\n", current->comm, 1551 type);
1522 type);
1523} 1552}
1524 1553
1525static int __init ppc_warn_emulated_init(void) 1554static int __init ppc_warn_emulated_init(void)