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.c30
1 files changed, 26 insertions, 4 deletions
diff --git a/arch/sparc64/kernel/traps.c b/arch/sparc64/kernel/traps.c
index fe1796c939c3..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>
@@ -1873,6 +1873,16 @@ void sun4v_resum_error(struct pt_regs *regs, unsigned long offset)
1873 1873
1874 put_cpu(); 1874 put_cpu();
1875 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
1876 sun4v_log_error(regs, &local_copy, cpu, 1886 sun4v_log_error(regs, &local_copy, cpu,
1877 KERN_ERR "RESUMABLE ERROR", 1887 KERN_ERR "RESUMABLE ERROR",
1878 &sun4v_resum_oflow_cnt); 1888 &sun4v_resum_oflow_cnt);
@@ -2261,8 +2271,12 @@ void die_if_kernel(char *str, struct pt_regs *regs)
2261 do_exit(SIGSEGV); 2271 do_exit(SIGSEGV);
2262} 2272}
2263 2273
2274#define VIS_OPCODE_MASK ((0x3 << 30) | (0x3f << 19))
2275#define VIS_OPCODE_VAL ((0x2 << 30) | (0x36 << 19))
2276
2264extern int handle_popc(u32 insn, struct pt_regs *regs); 2277extern int handle_popc(u32 insn, struct pt_regs *regs);
2265extern 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);
2266 2280
2267void do_illegal_instruction(struct pt_regs *regs) 2281void do_illegal_instruction(struct pt_regs *regs)
2268{ 2282{
@@ -2287,10 +2301,18 @@ void do_illegal_instruction(struct pt_regs *regs)
2287 if (handle_ldf_stq(insn, regs)) 2301 if (handle_ldf_stq(insn, regs))
2288 return; 2302 return;
2289 } else if (tlb_type == hypervisor) { 2303 } else if (tlb_type == hypervisor) {
2290 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;
2291 2309
2292 if (!vis_emul(regs, insn)) 2310 /* XXX maybe verify XFSR bits like
2293 return; 2311 * XXX do_fpother() does?
2312 */
2313 if (do_mathemu(regs, f))
2314 return;
2315 }
2294 } 2316 }
2295 } 2317 }
2296 info.si_signo = SIGILL; 2318 info.si_signo = SIGILL;