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.c58
1 files changed, 17 insertions, 41 deletions
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index a2e4ad3f5a75..6a881e3ea01d 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -31,29 +31,33 @@
31#include <linux/prctl.h> 31#include <linux/prctl.h>
32#include <linux/delay.h> 32#include <linux/delay.h>
33#include <linux/kprobes.h> 33#include <linux/kprobes.h>
34#include <asm/kdebug.h>
35 34
35#include <asm/kdebug.h>
36#include <asm/pgtable.h> 36#include <asm/pgtable.h>
37#include <asm/uaccess.h> 37#include <asm/uaccess.h>
38#include <asm/system.h> 38#include <asm/system.h>
39#include <asm/io.h> 39#include <asm/io.h>
40#include <asm/machdep.h>
41#include <asm/rtas.h>
42#include <asm/xmon.h>
40#ifdef CONFIG_PPC32 43#ifdef CONFIG_PPC32
41#include <asm/reg.h> 44#include <asm/reg.h>
42#include <asm/xmon.h> 45#include <asm/perfmon.h>
46#endif
43#ifdef CONFIG_PMAC_BACKLIGHT 47#ifdef CONFIG_PMAC_BACKLIGHT
44#include <asm/backlight.h> 48#include <asm/backlight.h>
45#endif 49#endif
46#include <asm/perfmon.h>
47#endif
48#ifdef CONFIG_PPC64 50#ifdef CONFIG_PPC64
51#include <asm/firmware.h>
49#include <asm/processor.h> 52#include <asm/processor.h>
50#include <asm/ppcdebug.h>
51#include <asm/rtas.h>
52#include <asm/systemcfg.h> 53#include <asm/systemcfg.h>
53#include <asm/machdep.h>
54#include <asm/pmc.h> 54#include <asm/pmc.h>
55#endif 55#endif
56 56
57#ifdef CONFIG_PPC64 /* XXX */
58#define _IO_BASE pci_io_base
59#endif
60
57#ifdef CONFIG_DEBUGGER 61#ifdef CONFIG_DEBUGGER
58int (*__debugger)(struct pt_regs *regs); 62int (*__debugger)(struct pt_regs *regs);
59int (*__debugger_ipi)(struct pt_regs *regs); 63int (*__debugger_ipi)(struct pt_regs *regs);
@@ -277,7 +281,6 @@ static inline int check_io_access(struct pt_regs *regs)
277} 281}
278 282
279#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE) 283#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
280
281/* On 4xx, the reason for the machine check or program exception 284/* On 4xx, the reason for the machine check or program exception
282 is in the ESR. */ 285 is in the ESR. */
283#define get_reason(regs) ((regs)->dsisr) 286#define get_reason(regs) ((regs)->dsisr)
@@ -296,7 +299,6 @@ static inline int check_io_access(struct pt_regs *regs)
296#define clear_single_step(regs) (current->thread.dbcr0 &= ~DBCR0_IC) 299#define clear_single_step(regs) (current->thread.dbcr0 &= ~DBCR0_IC)
297 300
298#else 301#else
299
300/* On non-4xx, the reason for the machine check or program 302/* On non-4xx, the reason for the machine check or program
301 exception is in the MSR. */ 303 exception is in the MSR. */
302#define get_reason(regs) ((regs)->msr) 304#define get_reason(regs) ((regs)->msr)
@@ -475,7 +477,7 @@ void machine_check_exception(struct pt_regs *regs)
475 * additional info, e.g. bus error registers. 477 * additional info, e.g. bus error registers.
476 */ 478 */
477 platform_machine_check(regs); 479 platform_machine_check(regs);
478#endif /* CONFIG_PPC32 */ 480#endif /* CONFIG_PPC64 */
479 481
480 if (debugger_fault_handler(regs)) 482 if (debugger_fault_handler(regs))
481 return; 483 return;
@@ -486,12 +488,10 @@ void machine_check_exception(struct pt_regs *regs)
486 panic("Unrecoverable Machine check"); 488 panic("Unrecoverable Machine check");
487} 489}
488 490
489#ifdef CONFIG_PPC32
490void SMIException(struct pt_regs *regs) 491void SMIException(struct pt_regs *regs)
491{ 492{
492 die("System Management Interrupt", regs, SIGABRT); 493 die("System Management Interrupt", regs, SIGABRT);
493} 494}
494#endif
495 495
496void unknown_exception(struct pt_regs *regs) 496void unknown_exception(struct pt_regs *regs)
497{ 497{
@@ -511,12 +511,10 @@ void instruction_breakpoint_exception(struct pt_regs *regs)
511 _exception(SIGTRAP, regs, TRAP_BRKPT, regs->nip); 511 _exception(SIGTRAP, regs, TRAP_BRKPT, regs->nip);
512} 512}
513 513
514#ifdef CONFIG_PPC32
515void RunModeException(struct pt_regs *regs) 514void RunModeException(struct pt_regs *regs)
516{ 515{
517 _exception(SIGTRAP, regs, 0, 0); 516 _exception(SIGTRAP, regs, 0, 0);
518} 517}
519#endif
520 518
521void __kprobes single_step_exception(struct pt_regs *regs) 519void __kprobes single_step_exception(struct pt_regs *regs)
522{ 520{
@@ -542,7 +540,6 @@ static void emulate_single_step(struct pt_regs *regs)
542 if (single_stepping(regs)) { 540 if (single_stepping(regs)) {
543 clear_single_step(regs); 541 clear_single_step(regs);
544 _exception(SIGTRAP, regs, TRAP_TRACE, 0); 542 _exception(SIGTRAP, regs, TRAP_TRACE, 0);
545 single_step_exception(regs);
546 } 543 }
547} 544}
548 545
@@ -587,6 +584,7 @@ static void parse_fpe(struct pt_regs *regs)
587 * There are a couple of ways to do this, either "decode" the instruction 584 * There are a couple of ways to do this, either "decode" the instruction
588 * or directly match lots of bits. In this case, matching lots of 585 * or directly match lots of bits. In this case, matching lots of
589 * bits is faster and easier. 586 * bits is faster and easier.
587 *
590 */ 588 */
591#define INST_MFSPR_PVR 0x7c1f42a6 589#define INST_MFSPR_PVR 0x7c1f42a6
592#define INST_MFSPR_PVR_MASK 0xfc1fffff 590#define INST_MFSPR_PVR_MASK 0xfc1fffff
@@ -597,8 +595,6 @@ static void parse_fpe(struct pt_regs *regs)
597#define INST_MCRXR 0x7c000400 595#define INST_MCRXR 0x7c000400
598#define INST_MCRXR_MASK 0x7c0007fe 596#define INST_MCRXR_MASK 0x7c0007fe
599 597
600#ifdef CONFIG_PPC32
601
602#define INST_STRING 0x7c00042a 598#define INST_STRING 0x7c00042a
603#define INST_STRING_MASK 0x7c0007fe 599#define INST_STRING_MASK 0x7c0007fe
604#define INST_STRING_GEN_MASK 0x7c00067e 600#define INST_STRING_GEN_MASK 0x7c00067e
@@ -674,7 +670,6 @@ static int emulate_string_inst(struct pt_regs *regs, u32 instword)
674 670
675 return 0; 671 return 0;
676} 672}
677#endif /* CONFIG_PPC32 */
678 673
679static int emulate_instruction(struct pt_regs *regs) 674static int emulate_instruction(struct pt_regs *regs)
680{ 675{
@@ -701,28 +696,17 @@ static int emulate_instruction(struct pt_regs *regs)
701 696
702 /* Emulate the mcrxr insn. */ 697 /* Emulate the mcrxr insn. */
703 if ((instword & INST_MCRXR_MASK) == INST_MCRXR) { 698 if ((instword & INST_MCRXR_MASK) == INST_MCRXR) {
704 unsigned int shift = (instword >> 21) & 0x1c; 699 int shift = (instword >> 21) & 0x1c;
705 unsigned long msk = 0xf0000000UL >> shift; 700 unsigned long msk = 0xf0000000UL >> shift;
706#ifdef CONFIG_PPC64
707 static int warned;
708 701
709 if (!warned) {
710 printk(KERN_WARNING
711 "process %d (%s) uses obsolete 'mcrxr' insn\n",
712 current->pid, current->comm);
713 warned = 1;
714 }
715#endif
716 regs->ccr = (regs->ccr & ~msk) | ((regs->xer >> shift) & msk); 702 regs->ccr = (regs->ccr & ~msk) | ((regs->xer >> shift) & msk);
717 regs->xer &= ~0xf0000000UL; 703 regs->xer &= ~0xf0000000UL;
718 return 0; 704 return 0;
719 } 705 }
720 706
721#ifdef CONFIG_PPC32
722 /* Emulate load/store string insn. */ 707 /* Emulate load/store string insn. */
723 if ((instword & INST_STRING_GEN_MASK) == INST_STRING) 708 if ((instword & INST_STRING_GEN_MASK) == INST_STRING)
724 return emulate_string_inst(regs, instword); 709 return emulate_string_inst(regs, instword);
725#endif
726 710
727 return -EINVAL; 711 return -EINVAL;
728} 712}
@@ -769,22 +753,18 @@ static int check_bug_trap(struct pt_regs *regs)
769 xmon_printf(KERN_ERR "Badness in %s at %s:%d\n", 753 xmon_printf(KERN_ERR "Badness in %s at %s:%d\n",
770 bug->function, bug->file, 754 bug->function, bug->file,
771 bug->line & ~BUG_WARNING_TRAP); 755 bug->line & ~BUG_WARNING_TRAP);
772#endif 756#endif /* CONFIG_XMON */
773 printk(KERN_ERR "Badness in %s at %s:%d\n", 757 printk(KERN_ERR "Badness in %s at %s:%d\n",
774 bug->function, bug->file, 758 bug->function, bug->file,
775 bug->line & ~BUG_WARNING_TRAP); 759 bug->line & ~BUG_WARNING_TRAP);
776#ifdef CONFIG_PPC32
777 dump_stack(); 760 dump_stack();
778#else
779 show_stack(current, (void *)regs->gpr[1]);
780#endif
781 return 1; 761 return 1;
782 } 762 }
783#if defined(CONFIG_PPC32) && defined(CONFIG_XMON) 763#ifdef CONFIG_XMON
784 xmon_printf(KERN_CRIT "kernel BUG in %s at %s:%d!\n", 764 xmon_printf(KERN_CRIT "kernel BUG in %s at %s:%d!\n",
785 bug->function, bug->file, bug->line); 765 bug->function, bug->file, bug->line);
786 xmon(regs); 766 xmon(regs);
787#endif 767#endif /* CONFIG_XMON */
788 printk(KERN_CRIT "kernel BUG in %s at %s:%d!\n", 768 printk(KERN_CRIT "kernel BUG in %s at %s:%d!\n",
789 bug->function, bug->file, bug->line); 769 bug->function, bug->file, bug->line);
790 770
@@ -873,7 +853,6 @@ void alignment_exception(struct pt_regs *regs)
873 _exception(SIGBUS, regs, BUS_ADRALN, regs->dar); 853 _exception(SIGBUS, regs, BUS_ADRALN, regs->dar);
874} 854}
875 855
876#ifdef CONFIG_PPC32
877void StackOverflow(struct pt_regs *regs) 856void StackOverflow(struct pt_regs *regs)
878{ 857{
879 printk(KERN_CRIT "Kernel stack overflow in process %p, r1=%lx\n", 858 printk(KERN_CRIT "Kernel stack overflow in process %p, r1=%lx\n",
@@ -897,7 +876,6 @@ void trace_syscall(struct pt_regs *regs)
897 current, current->pid, regs->nip, regs->link, regs->gpr[0], 876 current, current->pid, regs->nip, regs->link, regs->gpr[0],
898 regs->ccr&0x10000000?"Error=":"", regs->gpr[3], print_tainted()); 877 regs->ccr&0x10000000?"Error=":"", regs->gpr[3], print_tainted());
899} 878}
900#endif /* CONFIG_PPC32 */
901 879
902void kernel_fp_unavailable_exception(struct pt_regs *regs) 880void kernel_fp_unavailable_exception(struct pt_regs *regs)
903{ 881{
@@ -963,7 +941,6 @@ void SoftwareEmulation(struct pt_regs *regs)
963} 941}
964#endif /* CONFIG_8xx */ 942#endif /* CONFIG_8xx */
965 943
966#ifdef CONFIG_PPC32
967#if defined(CONFIG_40x) || defined(CONFIG_BOOKE) 944#if defined(CONFIG_40x) || defined(CONFIG_BOOKE)
968 945
969void DebugException(struct pt_regs *regs, unsigned long debug_status) 946void DebugException(struct pt_regs *regs, unsigned long debug_status)
@@ -992,7 +969,6 @@ void TAUException(struct pt_regs *regs)
992 regs->nip, regs->msr, regs->trap, print_tainted()); 969 regs->nip, regs->msr, regs->trap, print_tainted());
993} 970}
994#endif /* CONFIG_INT_TAU */ 971#endif /* CONFIG_INT_TAU */
995#endif /* CONFIG_PPC32*/
996 972
997#ifdef CONFIG_ALTIVEC 973#ifdef CONFIG_ALTIVEC
998void altivec_assist_exception(struct pt_regs *regs) 974void altivec_assist_exception(struct pt_regs *regs)