aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc64/kernel/traps.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sparc64/kernel/traps.c')
-rw-r--r--arch/sparc64/kernel/traps.c38
1 files changed, 34 insertions, 4 deletions
diff --git a/arch/sparc64/kernel/traps.c b/arch/sparc64/kernel/traps.c
index 68420e2dad0e..ad67784292db 100644
--- a/arch/sparc64/kernel/traps.c
+++ b/arch/sparc64/kernel/traps.c
@@ -10,7 +10,7 @@
10 */ 10 */
11 11
12#include <linux/module.h> 12#include <linux/module.h>
13#include <linux/sched.h> /* for jiffies */ 13#include <linux/sched.h>
14#include <linux/kernel.h> 14#include <linux/kernel.h>
15#include <linux/kallsyms.h> 15#include <linux/kallsyms.h>
16#include <linux/signal.h> 16#include <linux/signal.h>
@@ -87,6 +87,7 @@ static void dump_tl1_traplog(struct tl1_traplog *p)
87 i + 1, 87 i + 1,
88 p->trapstack[i].tstate, p->trapstack[i].tpc, 88 p->trapstack[i].tstate, p->trapstack[i].tpc,
89 p->trapstack[i].tnpc, p->trapstack[i].tt); 89 p->trapstack[i].tnpc, p->trapstack[i].tt);
90 print_symbol("TRAPLOG: TPC<%s>\n", p->trapstack[i].tpc);
90 } 91 }
91} 92}
92 93
@@ -1134,6 +1135,9 @@ static void cheetah_log_errors(struct pt_regs *regs, struct cheetah_err_info *in
1134 printk("%s" "ERROR(%d): TPC[%lx] TNPC[%lx] O7[%lx] TSTATE[%lx]\n", 1135 printk("%s" "ERROR(%d): TPC[%lx] TNPC[%lx] O7[%lx] TSTATE[%lx]\n",
1135 (recoverable ? KERN_WARNING : KERN_CRIT), smp_processor_id(), 1136 (recoverable ? KERN_WARNING : KERN_CRIT), smp_processor_id(),
1136 regs->tpc, regs->tnpc, regs->u_regs[UREG_I7], regs->tstate); 1137 regs->tpc, regs->tnpc, regs->u_regs[UREG_I7], regs->tstate);
1138 printk("%s" "ERROR(%d): ",
1139 (recoverable ? KERN_WARNING : KERN_CRIT), smp_processor_id());
1140 print_symbol("TPC<%s>\n", regs->tpc);
1137 printk("%s" "ERROR(%d): M_SYND(%lx), E_SYND(%lx)%s%s\n", 1141 printk("%s" "ERROR(%d): M_SYND(%lx), E_SYND(%lx)%s%s\n",
1138 (recoverable ? KERN_WARNING : KERN_CRIT), smp_processor_id(), 1142 (recoverable ? KERN_WARNING : KERN_CRIT), smp_processor_id(),
1139 (afsr & CHAFSR_M_SYNDROME) >> CHAFSR_M_SYNDROME_SHIFT, 1143 (afsr & CHAFSR_M_SYNDROME) >> CHAFSR_M_SYNDROME_SHIFT,
@@ -1741,6 +1745,7 @@ void cheetah_plus_parity_error(int type, struct pt_regs *regs)
1741 smp_processor_id(), 1745 smp_processor_id(),
1742 (type & 0x1) ? 'I' : 'D', 1746 (type & 0x1) ? 'I' : 'D',
1743 regs->tpc); 1747 regs->tpc);
1748 print_symbol(KERN_EMERG "TPC<%s>\n", regs->tpc);
1744 panic("Irrecoverable Cheetah+ parity error."); 1749 panic("Irrecoverable Cheetah+ parity error.");
1745 } 1750 }
1746 1751
@@ -1748,6 +1753,7 @@ void cheetah_plus_parity_error(int type, struct pt_regs *regs)
1748 smp_processor_id(), 1753 smp_processor_id(),
1749 (type & 0x1) ? 'I' : 'D', 1754 (type & 0x1) ? 'I' : 'D',
1750 regs->tpc); 1755 regs->tpc);
1756 print_symbol(KERN_WARNING "TPC<%s>\n", regs->tpc);
1751} 1757}
1752 1758
1753struct sun4v_error_entry { 1759struct sun4v_error_entry {
@@ -1867,6 +1873,16 @@ void sun4v_resum_error(struct pt_regs *regs, unsigned long offset)
1867 1873
1868 put_cpu(); 1874 put_cpu();
1869 1875
1876 if (ent->err_type == SUN4V_ERR_TYPE_WARNING_RES) {
1877 /* If err_type is 0x4, it's a powerdown request. Do
1878 * not do the usual resumable error log because that
1879 * makes it look like some abnormal error.
1880 */
1881 printk(KERN_INFO "Power down request...\n");
1882 kill_cad_pid(SIGINT, 1);
1883 return;
1884 }
1885
1870 sun4v_log_error(regs, &local_copy, cpu, 1886 sun4v_log_error(regs, &local_copy, cpu,
1871 KERN_ERR "RESUMABLE ERROR", 1887 KERN_ERR "RESUMABLE ERROR",
1872 &sun4v_resum_oflow_cnt); 1888 &sun4v_resum_oflow_cnt);
@@ -1946,6 +1962,7 @@ void sun4v_itlb_error_report(struct pt_regs *regs, int tl)
1946 1962
1947 printk(KERN_EMERG "SUN4V-ITLB: Error at TPC[%lx], tl %d\n", 1963 printk(KERN_EMERG "SUN4V-ITLB: Error at TPC[%lx], tl %d\n",
1948 regs->tpc, tl); 1964 regs->tpc, tl);
1965 print_symbol(KERN_EMERG "SUN4V-ITLB: TPC<%s>\n", regs->tpc);
1949 printk(KERN_EMERG "SUN4V-ITLB: vaddr[%lx] ctx[%lx] " 1966 printk(KERN_EMERG "SUN4V-ITLB: vaddr[%lx] ctx[%lx] "
1950 "pte[%lx] error[%lx]\n", 1967 "pte[%lx] error[%lx]\n",
1951 sun4v_err_itlb_vaddr, sun4v_err_itlb_ctx, 1968 sun4v_err_itlb_vaddr, sun4v_err_itlb_ctx,
@@ -1966,6 +1983,7 @@ void sun4v_dtlb_error_report(struct pt_regs *regs, int tl)
1966 1983
1967 printk(KERN_EMERG "SUN4V-DTLB: Error at TPC[%lx], tl %d\n", 1984 printk(KERN_EMERG "SUN4V-DTLB: Error at TPC[%lx], tl %d\n",
1968 regs->tpc, tl); 1985 regs->tpc, tl);
1986 print_symbol(KERN_EMERG "SUN4V-DTLB: TPC<%s>\n", regs->tpc);
1969 printk(KERN_EMERG "SUN4V-DTLB: vaddr[%lx] ctx[%lx] " 1987 printk(KERN_EMERG "SUN4V-DTLB: vaddr[%lx] ctx[%lx] "
1970 "pte[%lx] error[%lx]\n", 1988 "pte[%lx] error[%lx]\n",
1971 sun4v_err_dtlb_vaddr, sun4v_err_dtlb_ctx, 1989 sun4v_err_dtlb_vaddr, sun4v_err_dtlb_ctx,
@@ -2253,8 +2271,12 @@ void die_if_kernel(char *str, struct pt_regs *regs)
2253 do_exit(SIGSEGV); 2271 do_exit(SIGSEGV);
2254} 2272}
2255 2273
2274#define VIS_OPCODE_MASK ((0x3 << 30) | (0x3f << 19))
2275#define VIS_OPCODE_VAL ((0x2 << 30) | (0x36 << 19))
2276
2256extern int handle_popc(u32 insn, struct pt_regs *regs); 2277extern int handle_popc(u32 insn, struct pt_regs *regs);
2257extern int handle_ldf_stq(u32 insn, struct pt_regs *regs); 2278extern int handle_ldf_stq(u32 insn, struct pt_regs *regs);
2279extern int vis_emul(struct pt_regs *, unsigned int);
2258 2280
2259void do_illegal_instruction(struct pt_regs *regs) 2281void do_illegal_instruction(struct pt_regs *regs)
2260{ 2282{
@@ -2279,10 +2301,18 @@ void do_illegal_instruction(struct pt_regs *regs)
2279 if (handle_ldf_stq(insn, regs)) 2301 if (handle_ldf_stq(insn, regs))
2280 return; 2302 return;
2281 } else if (tlb_type == hypervisor) { 2303 } else if (tlb_type == hypervisor) {
2282 extern int vis_emul(struct pt_regs *, unsigned int); 2304 if ((insn & VIS_OPCODE_MASK) == VIS_OPCODE_VAL) {
2305 if (!vis_emul(regs, insn))
2306 return;
2307 } else {
2308 struct fpustate *f = FPUSTATE;
2283 2309
2284 if (!vis_emul(regs, insn)) 2310 /* XXX maybe verify XFSR bits like
2285 return; 2311 * XXX do_fpother() does?
2312 */
2313 if (do_mathemu(regs, f))
2314 return;
2315 }
2286 } 2316 }
2287 } 2317 }
2288 info.si_signo = SIGILL; 2318 info.si_signo = SIGILL;