aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/kernel/traps.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/kernel/traps.c')
-rw-r--r--arch/mips/kernel/traps.c213
1 files changed, 148 insertions, 65 deletions
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index 984c0d0a7b4d..cb8b0e2c7954 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -22,6 +22,7 @@
22#include <linux/kallsyms.h> 22#include <linux/kallsyms.h>
23#include <linux/bootmem.h> 23#include <linux/bootmem.h>
24#include <linux/interrupt.h> 24#include <linux/interrupt.h>
25#include <linux/ptrace.h>
25 26
26#include <asm/bootinfo.h> 27#include <asm/bootinfo.h>
27#include <asm/branch.h> 28#include <asm/branch.h>
@@ -80,19 +81,22 @@ void (*board_bind_eic_interrupt)(int irq, int regset);
80 81
81static void show_raw_backtrace(unsigned long reg29) 82static void show_raw_backtrace(unsigned long reg29)
82{ 83{
83 unsigned long *sp = (unsigned long *)reg29; 84 unsigned long *sp = (unsigned long *)(reg29 & ~3);
84 unsigned long addr; 85 unsigned long addr;
85 86
86 printk("Call Trace:"); 87 printk("Call Trace:");
87#ifdef CONFIG_KALLSYMS 88#ifdef CONFIG_KALLSYMS
88 printk("\n"); 89 printk("\n");
89#endif 90#endif
90 while (!kstack_end(sp)) { 91#define IS_KVA01(a) ((((unsigned int)a) & 0xc0000000) == 0x80000000)
91 addr = *sp++; 92 if (IS_KVA01(sp)) {
92 if (__kernel_text_address(addr)) 93 while (!kstack_end(sp)) {
93 print_ip_sym(addr); 94 addr = *sp++;
95 if (__kernel_text_address(addr))
96 print_ip_sym(addr);
97 }
98 printk("\n");
94 } 99 }
95 printk("\n");
96} 100}
97 101
98#ifdef CONFIG_KALLSYMS 102#ifdef CONFIG_KALLSYMS
@@ -192,16 +196,19 @@ EXPORT_SYMBOL(dump_stack);
192static void show_code(unsigned int __user *pc) 196static void show_code(unsigned int __user *pc)
193{ 197{
194 long i; 198 long i;
199 unsigned short __user *pc16 = NULL;
195 200
196 printk("\nCode:"); 201 printk("\nCode:");
197 202
203 if ((unsigned long)pc & 1)
204 pc16 = (unsigned short __user *)((unsigned long)pc & ~1);
198 for(i = -3 ; i < 6 ; i++) { 205 for(i = -3 ; i < 6 ; i++) {
199 unsigned int insn; 206 unsigned int insn;
200 if (__get_user(insn, pc + i)) { 207 if (pc16 ? __get_user(insn, pc16 + i) : __get_user(insn, pc + i)) {
201 printk(" (Bad address in epc)\n"); 208 printk(" (Bad address in epc)\n");
202 break; 209 break;
203 } 210 }
204 printk("%c%08x%c", (i?' ':'<'), insn, (i?' ':'>')); 211 printk("%c%0*x%c", (i?' ':'<'), pc16 ? 4 : 8, insn, (i?' ':'>'));
205 } 212 }
206} 213}
207 214
@@ -311,10 +318,21 @@ void show_regs(struct pt_regs *regs)
311 318
312void show_registers(const struct pt_regs *regs) 319void show_registers(const struct pt_regs *regs)
313{ 320{
321 const int field = 2 * sizeof(unsigned long);
322
314 __show_regs(regs); 323 __show_regs(regs);
315 print_modules(); 324 print_modules();
316 printk("Process %s (pid: %d, threadinfo=%p, task=%p)\n", 325 printk("Process %s (pid: %d, threadinfo=%p, task=%p, tls=%0*lx)\n",
317 current->comm, task_pid_nr(current), current_thread_info(), current); 326 current->comm, current->pid, current_thread_info(), current,
327 field, current_thread_info()->tp_value);
328 if (cpu_has_userlocal) {
329 unsigned long tls;
330
331 tls = read_c0_userlocal();
332 if (tls != current_thread_info()->tp_value)
333 printk("*HwTLS: %0*lx\n", field, tls);
334 }
335
318 show_stacktrace(current, regs); 336 show_stacktrace(current, regs);
319 show_code((unsigned int __user *) regs->cp0_epc); 337 show_code((unsigned int __user *) regs->cp0_epc);
320 printk("\n"); 338 printk("\n");
@@ -657,35 +675,24 @@ asmlinkage void do_fpe(struct pt_regs *regs, unsigned long fcr31)
657 force_sig_info(SIGFPE, &info, current); 675 force_sig_info(SIGFPE, &info, current);
658} 676}
659 677
660asmlinkage void do_bp(struct pt_regs *regs) 678static void do_trap_or_bp(struct pt_regs *regs, unsigned int code,
679 const char *str)
661{ 680{
662 unsigned int opcode, bcode;
663 siginfo_t info; 681 siginfo_t info;
664 682 char b[40];
665 if (__get_user(opcode, (unsigned int __user *) exception_epc(regs)))
666 goto out_sigsegv;
667
668 /*
669 * There is the ancient bug in the MIPS assemblers that the break
670 * code starts left to bit 16 instead to bit 6 in the opcode.
671 * Gas is bug-compatible, but not always, grrr...
672 * We handle both cases with a simple heuristics. --macro
673 */
674 bcode = ((opcode >> 6) & ((1 << 20) - 1));
675 if (bcode < (1 << 10))
676 bcode <<= 10;
677 683
678 /* 684 /*
679 * (A short test says that IRIX 5.3 sends SIGTRAP for all break 685 * A short test says that IRIX 5.3 sends SIGTRAP for all trap
680 * insns, even for break codes that indicate arithmetic failures. 686 * insns, even for trap and break codes that indicate arithmetic
681 * Weird ...) 687 * failures. Weird ...
682 * But should we continue the brokenness??? --macro 688 * But should we continue the brokenness??? --macro
683 */ 689 */
684 switch (bcode) { 690 switch (code) {
685 case BRK_OVERFLOW << 10: 691 case BRK_OVERFLOW:
686 case BRK_DIVZERO << 10: 692 case BRK_DIVZERO:
687 die_if_kernel("Break instruction in kernel code", regs); 693 scnprintf(b, sizeof(b), "%s instruction in kernel code", str);
688 if (bcode == (BRK_DIVZERO << 10)) 694 die_if_kernel(b, regs);
695 if (code == BRK_DIVZERO)
689 info.si_code = FPE_INTDIV; 696 info.si_code = FPE_INTDIV;
690 else 697 else
691 info.si_code = FPE_INTOVF; 698 info.si_code = FPE_INTOVF;
@@ -695,12 +702,34 @@ asmlinkage void do_bp(struct pt_regs *regs)
695 force_sig_info(SIGFPE, &info, current); 702 force_sig_info(SIGFPE, &info, current);
696 break; 703 break;
697 case BRK_BUG: 704 case BRK_BUG:
698 die("Kernel bug detected", regs); 705 die_if_kernel("Kernel bug detected", regs);
706 force_sig(SIGTRAP, current);
699 break; 707 break;
700 default: 708 default:
701 die_if_kernel("Break instruction in kernel code", regs); 709 scnprintf(b, sizeof(b), "%s instruction in kernel code", str);
710 die_if_kernel(b, regs);
702 force_sig(SIGTRAP, current); 711 force_sig(SIGTRAP, current);
703 } 712 }
713}
714
715asmlinkage void do_bp(struct pt_regs *regs)
716{
717 unsigned int opcode, bcode;
718
719 if (__get_user(opcode, (unsigned int __user *) exception_epc(regs)))
720 goto out_sigsegv;
721
722 /*
723 * There is the ancient bug in the MIPS assemblers that the break
724 * code starts left to bit 16 instead to bit 6 in the opcode.
725 * Gas is bug-compatible, but not always, grrr...
726 * We handle both cases with a simple heuristics. --macro
727 */
728 bcode = ((opcode >> 6) & ((1 << 20) - 1));
729 if (bcode >= (1 << 10))
730 bcode >>= 10;
731
732 do_trap_or_bp(regs, bcode, "Break");
704 return; 733 return;
705 734
706out_sigsegv: 735out_sigsegv:
@@ -710,7 +739,6 @@ out_sigsegv:
710asmlinkage void do_tr(struct pt_regs *regs) 739asmlinkage void do_tr(struct pt_regs *regs)
711{ 740{
712 unsigned int opcode, tcode = 0; 741 unsigned int opcode, tcode = 0;
713 siginfo_t info;
714 742
715 if (__get_user(opcode, (unsigned int __user *) exception_epc(regs))) 743 if (__get_user(opcode, (unsigned int __user *) exception_epc(regs)))
716 goto out_sigsegv; 744 goto out_sigsegv;
@@ -719,32 +747,7 @@ asmlinkage void do_tr(struct pt_regs *regs)
719 if (!(opcode & OPCODE)) 747 if (!(opcode & OPCODE))
720 tcode = ((opcode >> 6) & ((1 << 10) - 1)); 748 tcode = ((opcode >> 6) & ((1 << 10) - 1));
721 749
722 /* 750 do_trap_or_bp(regs, tcode, "Trap");
723 * (A short test says that IRIX 5.3 sends SIGTRAP for all trap
724 * insns, even for trap codes that indicate arithmetic failures.
725 * Weird ...)
726 * But should we continue the brokenness??? --macro
727 */
728 switch (tcode) {
729 case BRK_OVERFLOW:
730 case BRK_DIVZERO:
731 die_if_kernel("Trap instruction in kernel code", regs);
732 if (tcode == BRK_DIVZERO)
733 info.si_code = FPE_INTDIV;
734 else
735 info.si_code = FPE_INTOVF;
736 info.si_signo = SIGFPE;
737 info.si_errno = 0;
738 info.si_addr = (void __user *) regs->cp0_epc;
739 force_sig_info(SIGFPE, &info, current);
740 break;
741 case BRK_BUG:
742 die("Kernel bug detected", regs);
743 break;
744 default:
745 die_if_kernel("Trap instruction in kernel code", regs);
746 force_sig(SIGTRAP, current);
747 }
748 return; 751 return;
749 752
750out_sigsegv: 753out_sigsegv:
@@ -985,6 +988,21 @@ asmlinkage void do_reserved(struct pt_regs *regs)
985 (regs->cp0_cause & 0x7f) >> 2); 988 (regs->cp0_cause & 0x7f) >> 2);
986} 989}
987 990
991static int __initdata l1parity = 1;
992static int __init nol1parity(char *s)
993{
994 l1parity = 0;
995 return 1;
996}
997__setup("nol1par", nol1parity);
998static int __initdata l2parity = 1;
999static int __init nol2parity(char *s)
1000{
1001 l2parity = 0;
1002 return 1;
1003}
1004__setup("nol2par", nol2parity);
1005
988/* 1006/*
989 * Some MIPS CPUs can enable/disable for cache parity detection, but do 1007 * Some MIPS CPUs can enable/disable for cache parity detection, but do
990 * it different ways. 1008 * it different ways.
@@ -994,6 +1012,62 @@ static inline void parity_protection_init(void)
994 switch (current_cpu_type()) { 1012 switch (current_cpu_type()) {
995 case CPU_24K: 1013 case CPU_24K:
996 case CPU_34K: 1014 case CPU_34K:
1015 case CPU_74K:
1016 case CPU_1004K:
1017 {
1018#define ERRCTL_PE 0x80000000
1019#define ERRCTL_L2P 0x00800000
1020 unsigned long errctl;
1021 unsigned int l1parity_present, l2parity_present;
1022
1023 errctl = read_c0_ecc();
1024 errctl &= ~(ERRCTL_PE|ERRCTL_L2P);
1025
1026 /* probe L1 parity support */
1027 write_c0_ecc(errctl | ERRCTL_PE);
1028 back_to_back_c0_hazard();
1029 l1parity_present = (read_c0_ecc() & ERRCTL_PE);
1030
1031 /* probe L2 parity support */
1032 write_c0_ecc(errctl|ERRCTL_L2P);
1033 back_to_back_c0_hazard();
1034 l2parity_present = (read_c0_ecc() & ERRCTL_L2P);
1035
1036 if (l1parity_present && l2parity_present) {
1037 if (l1parity)
1038 errctl |= ERRCTL_PE;
1039 if (l1parity ^ l2parity)
1040 errctl |= ERRCTL_L2P;
1041 } else if (l1parity_present) {
1042 if (l1parity)
1043 errctl |= ERRCTL_PE;
1044 } else if (l2parity_present) {
1045 if (l2parity)
1046 errctl |= ERRCTL_L2P;
1047 } else {
1048 /* No parity available */
1049 }
1050
1051 printk(KERN_INFO "Writing ErrCtl register=%08lx\n", errctl);
1052
1053 write_c0_ecc(errctl);
1054 back_to_back_c0_hazard();
1055 errctl = read_c0_ecc();
1056 printk(KERN_INFO "Readback ErrCtl register=%08lx\n", errctl);
1057
1058 if (l1parity_present)
1059 printk(KERN_INFO "Cache parity protection %sabled\n",
1060 (errctl & ERRCTL_PE) ? "en" : "dis");
1061
1062 if (l2parity_present) {
1063 if (l1parity_present && l1parity)
1064 errctl ^= ERRCTL_L2P;
1065 printk(KERN_INFO "L2 cache parity protection %sabled\n",
1066 (errctl & ERRCTL_L2P) ? "en" : "dis");
1067 }
1068 }
1069 break;
1070
997 case CPU_5KC: 1071 case CPU_5KC:
998 write_c0_ecc(0x80000000); 1072 write_c0_ecc(0x80000000);
999 back_to_back_c0_hazard(); 1073 back_to_back_c0_hazard();
@@ -1306,6 +1380,17 @@ int cp0_compare_irq;
1306int cp0_perfcount_irq; 1380int cp0_perfcount_irq;
1307EXPORT_SYMBOL_GPL(cp0_perfcount_irq); 1381EXPORT_SYMBOL_GPL(cp0_perfcount_irq);
1308 1382
1383static int __cpuinitdata noulri;
1384
1385static int __init ulri_disable(char *s)
1386{
1387 pr_info("Disabling ulri\n");
1388 noulri = 1;
1389
1390 return 1;
1391}
1392__setup("noulri", ulri_disable);
1393
1309void __cpuinit per_cpu_trap_init(void) 1394void __cpuinit per_cpu_trap_init(void)
1310{ 1395{
1311 unsigned int cpu = smp_processor_id(); 1396 unsigned int cpu = smp_processor_id();
@@ -1342,16 +1427,14 @@ void __cpuinit per_cpu_trap_init(void)
1342 change_c0_status(ST0_CU|ST0_MX|ST0_RE|ST0_FR|ST0_BEV|ST0_TS|ST0_KX|ST0_SX|ST0_UX, 1427 change_c0_status(ST0_CU|ST0_MX|ST0_RE|ST0_FR|ST0_BEV|ST0_TS|ST0_KX|ST0_SX|ST0_UX,
1343 status_set); 1428 status_set);
1344 1429
1345#ifdef CONFIG_CPU_MIPSR2
1346 if (cpu_has_mips_r2) { 1430 if (cpu_has_mips_r2) {
1347 unsigned int enable = 0x0000000f; 1431 unsigned int enable = 0x0000000f;
1348 1432
1349 if (cpu_has_userlocal) 1433 if (!noulri && cpu_has_userlocal)
1350 enable |= (1 << 29); 1434 enable |= (1 << 29);
1351 1435
1352 write_c0_hwrena(enable); 1436 write_c0_hwrena(enable);
1353 } 1437 }
1354#endif
1355 1438
1356#ifdef CONFIG_MIPS_MT_SMTC 1439#ifdef CONFIG_MIPS_MT_SMTC
1357 if (!secondaryTC) { 1440 if (!secondaryTC) {