From b533ce76b40530a3029e1c3fdafb06a91f729903 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 19 Nov 2006 14:38:25 -0800 Subject: [PATCH] --- yaml --- r: 44156 b: refs/heads/master c: 6e7726e16fb5e8f1169dbfcb75e321ac871af827 h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/arch/sparc64/kernel/traps.c | 18 +++++++++++++++--- trunk/arch/sparc64/kernel/visemul.c | 6 ------ 3 files changed, 16 insertions(+), 10 deletions(-) diff --git a/[refs] b/[refs] index 759b6f45a9f2..c36b0982d258 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 042cf50cfd0bc3e1769d8287465eb522e8a08ba6 +refs/heads/master: 6e7726e16fb5e8f1169dbfcb75e321ac871af827 diff --git a/trunk/arch/sparc64/kernel/traps.c b/trunk/arch/sparc64/kernel/traps.c index fe1796c939c3..ec7a60142bec 100644 --- a/trunk/arch/sparc64/kernel/traps.c +++ b/trunk/arch/sparc64/kernel/traps.c @@ -2261,8 +2261,12 @@ void die_if_kernel(char *str, struct pt_regs *regs) do_exit(SIGSEGV); } +#define VIS_OPCODE_MASK ((0x3 << 30) | (0x3f << 19)) +#define VIS_OPCODE_VAL ((0x2 << 30) | (0x36 << 19)) + extern int handle_popc(u32 insn, struct pt_regs *regs); extern int handle_ldf_stq(u32 insn, struct pt_regs *regs); +extern int vis_emul(struct pt_regs *, unsigned int); void do_illegal_instruction(struct pt_regs *regs) { @@ -2287,10 +2291,18 @@ void do_illegal_instruction(struct pt_regs *regs) if (handle_ldf_stq(insn, regs)) return; } else if (tlb_type == hypervisor) { - extern int vis_emul(struct pt_regs *, unsigned int); + if ((insn & VIS_OPCODE_MASK) == VIS_OPCODE_VAL) { + if (!vis_emul(regs, insn)) + return; + } else { + struct fpustate *f = FPUSTATE; - if (!vis_emul(regs, insn)) - return; + /* XXX maybe verify XFSR bits like + * XXX do_fpother() does? + */ + if (do_mathemu(regs, f)) + return; + } } } info.si_signo = SIGILL; diff --git a/trunk/arch/sparc64/kernel/visemul.c b/trunk/arch/sparc64/kernel/visemul.c index 84fedaa38aae..c3fd64706b53 100644 --- a/trunk/arch/sparc64/kernel/visemul.c +++ b/trunk/arch/sparc64/kernel/visemul.c @@ -128,9 +128,6 @@ /* 001001100 - Permute bytes as specified by GSR.MASK */ #define BSHUFFLE_OPF 0x04c -#define VIS_OPCODE_MASK ((0x3 << 30) | (0x3f << 19)) -#define VIS_OPCODE_VAL ((0x2 << 30) | (0x36 << 19)) - #define VIS_OPF_SHIFT 5 #define VIS_OPF_MASK (0x1ff << VIS_OPF_SHIFT) @@ -810,9 +807,6 @@ int vis_emul(struct pt_regs *regs, unsigned int insn) if (get_user(insn, (u32 __user *) pc)) return -EFAULT; - if ((insn & VIS_OPCODE_MASK) != VIS_OPCODE_VAL) - return -EINVAL; - opf = (insn & VIS_OPF_MASK) >> VIS_OPF_SHIFT; switch (opf) { default: