summaryrefslogtreecommitdiffstats
path: root/arch/sparc/kernel/traps_64.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2012-05-25 09:31:56 +0200
committerDavid S. Miller <davem@davemloft.net>2012-05-25 09:31:56 +0200
commit456d3d42460c1fc20ba0d27442443fcd63aaac35 (patch)
tree2bdd7021420f845f3c775e91ccc91aa791ef6c45 /arch/sparc/kernel/traps_64.c
parentMerge branch 'next' of git://git.kernel.org/pub/scm/virt/kvm/kvm (diff)
downloadlinux-456d3d42460c1fc20ba0d27442443fcd63aaac35.tar.xz
linux-456d3d42460c1fc20ba0d27442443fcd63aaac35.zip
sparc64: Fix several bugs in quad floating point emulation.
UltraSPARC-T2 and later do not use the fp_exception_other trap and do not set the floating point trap type field in the %fsr at all when you try to execute an unimplemented FPU operation. Instead, it uses the illegal_instruction trap and it leaves the floating point trap type field clear. So we should not validate the %fsr trap type field when do_mathemu() is invoked from the illegal instruction handler. Also, the floating point trap type field is 3 bits, not 4 bits. Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'arch/sparc/kernel/traps_64.c')
-rw-r--r--arch/sparc/kernel/traps_64.c12
1 files changed, 7 insertions, 5 deletions
diff --git a/arch/sparc/kernel/traps_64.c b/arch/sparc/kernel/traps_64.c
index c72fdf55e1c1..3b05e6697710 100644
--- a/arch/sparc/kernel/traps_64.c
+++ b/arch/sparc/kernel/traps_64.c
@@ -2054,7 +2054,7 @@ void do_fpieee(struct pt_regs *regs)
do_fpe_common(regs);
}
-extern int do_mathemu(struct pt_regs *, struct fpustate *);
+extern int do_mathemu(struct pt_regs *, struct fpustate *, bool);
void do_fpother(struct pt_regs *regs)
{
@@ -2068,7 +2068,7 @@ void do_fpother(struct pt_regs *regs)
switch ((current_thread_info()->xfsr[0] & 0x1c000)) {
case (2 << 14): /* unfinished_FPop */
case (3 << 14): /* unimplemented_FPop */
- ret = do_mathemu(regs, f);
+ ret = do_mathemu(regs, f, false);
break;
}
if (ret)
@@ -2308,10 +2308,12 @@ void do_illegal_instruction(struct pt_regs *regs)
} else {
struct fpustate *f = FPUSTATE;
- /* XXX maybe verify XFSR bits like
- * XXX do_fpother() does?
+ /* On UltraSPARC T2 and later, FPU insns which
+ * are not implemented in HW signal an illegal
+ * instruction trap and do not set the FP Trap
+ * Trap in the %fsr to unimplemented_FPop.
*/
- if (do_mathemu(regs, f))
+ if (do_mathemu(regs, f, true))
return;
}
}