From 01c9ccee3c3051d0a37af9af2938a15a06448964 Mon Sep 17 00:00:00 2001 From: Joseph Myers Date: Mon, 4 Nov 2013 16:55:05 +0000 Subject: [PATCH] powerpc: fix e500 SPE float SIGFPE generation The e500 SPE floating-point emulation code is called from SPEFloatingPointException and SPEFloatingPointRoundException in arch/powerpc/kernel/traps.c. Those functions have support for generating SIGFPE, but do_spe_mathemu and speround_handler don't generate a return value to indicate that this should be done. Such a return value should depend on whether an exception is raised that has been set via prctl to generate SIGFPE. This patch adds the relevant logic in these functions so that SIGFPE is generated as expected by the glibc testsuite. Signed-off-by: Joseph Myers Signed-off-by: Scott Wood --- arch/powerpc/math-emu/math_efp.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/arch/powerpc/math-emu/math_efp.c b/arch/powerpc/math-emu/math_efp.c index 01a0abb94dd..28337c9709a 100644 --- a/arch/powerpc/math-emu/math_efp.c +++ b/arch/powerpc/math-emu/math_efp.c @@ -20,6 +20,7 @@ */ #include +#include #include #include @@ -691,6 +692,23 @@ update_regs: pr_debug("va: %08x %08x\n", va.wp[0], va.wp[1]); pr_debug("vb: %08x %08x\n", vb.wp[0], vb.wp[1]); + if (current->thread.fpexc_mode & PR_FP_EXC_SW_ENABLE) { + if ((FP_CUR_EXCEPTIONS & FP_EX_DIVZERO) + && (current->thread.fpexc_mode & PR_FP_EXC_DIV)) + return 1; + if ((FP_CUR_EXCEPTIONS & FP_EX_OVERFLOW) + && (current->thread.fpexc_mode & PR_FP_EXC_OVF)) + return 1; + if ((FP_CUR_EXCEPTIONS & FP_EX_UNDERFLOW) + && (current->thread.fpexc_mode & PR_FP_EXC_UND)) + return 1; + if ((FP_CUR_EXCEPTIONS & FP_EX_INEXACT) + && (current->thread.fpexc_mode & PR_FP_EXC_RES)) + return 1; + if ((FP_CUR_EXCEPTIONS & FP_EX_INVALID) + && (current->thread.fpexc_mode & PR_FP_EXC_INV)) + return 1; + } return 0; illegal: @@ -867,6 +885,8 @@ int speround_handler(struct pt_regs *regs) pr_debug(" to fgpr: %08x %08x\n", fgpr.wp[0], fgpr.wp[1]); + if (current->thread.fpexc_mode & PR_FP_EXC_SW_ENABLE) + return (current->thread.fpexc_mode & PR_FP_EXC_RES) ? 1 : 0; return 0; } -- 2.41.0