From: Ilya Leoshkevich <[email protected]>
helper_divs32() divides the 64-bit dividend by the 32-bit divisor as a 64-bit
host operation, guarding only against a zero divisor. INT64_MIN / -1 therefore
overflows the host division before the representability check runs; on hosts
that trap this, QEMU is killed with SIGFPE instead of raising the
fixed-point-divide exception the guest expects:
qemu-s390x: QEMU internal SIGFPE {code=INTDIV, addr=...}
helper_divs64() already guards the same case; add the missing check to
helper_divs32().
Reported-by: Christian Borntraeger <[email protected]>
Fixes: b4e2bd3563af ("target-s390: Send signals for divide")
Cc: [email protected]
Signed-off-by: Ilya Leoshkevich <[email protected]>
Reviewed-by: Richard Henderson <[email protected]>
Link:
https://lore.kernel.org/qemu-devel/[email protected]
Signed-off-by: Eric Farman <[email protected]>
---
target/s390x/tcg/int_helper.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/target/s390x/tcg/int_helper.c b/target/s390x/tcg/int_helper.c
index fbda396f5b..5aedd1405b 100644
--- a/target/s390x/tcg/int_helper.c
+++ b/target/s390x/tcg/int_helper.c
@@ -39,7 +39,8 @@ uint64_t HELPER(divs32)(CPUS390XState *env, int64_t a,
int64_t b64)
int32_t b = b64;
int64_t q, r;
- if (b == 0) {
+ /* Catch divide by zero, and non-representable quotient (MIN / -1). */
+ if (b == 0 || (b == -1 && a == (1ll << 63))) {
tcg_s390_program_interrupt(env, PGM_FIXPT_DIVIDE, GETPC());
}
--
2.55.0