Currently when a compare-and-trap instruction is executed, qemu will
always raise a SIGILL signal. On real hardware, a SIGFPE is raised.
Change the PGM_DATA case in cpu_loop to follow the behavior in
linux kernel /arch/s390/kernel/traps.c.
* Only raise SIGILL if DXC == 0
* If DXC matches an IEEE exception, raise SIGFPE with correct si_code
* Raise SIGFPE with si_code == 0 for everything else
When applied on 20210602002210.3144559-2-iii@linux.ibm.com, this fixes
crashes in the java jdk such as the linked bug.
Buglink: https://bugs.launchpad.net/qemu/+bug/1920913
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/319
Signed-off-by: Jonathan Albrecht <jonathan.albrecht@linux.vnet.ibm.com>
---
linux-user/s390x/cpu_loop.c | 19 ++++++++++---------
1 file changed, 10 insertions(+), 9 deletions(-)
diff --git a/linux-user/s390x/cpu_loop.c b/linux-user/s390x/cpu_loop.c
index 72ba9170ed..def5c046f7 100644
--- a/linux-user/s390x/cpu_loop.c
+++ b/linux-user/s390x/cpu_loop.c
@@ -117,11 +117,13 @@ void cpu_loop(CPUS390XState *env)
case PGM_DATA:
n = (env->fpc >> 8) & 0xff;
- if (n == 0xff) {
- /* compare-and-trap */
+ if (n == 0) {
goto do_sigill_opn;
- } else {
- /* An IEEE exception, simulated or otherwise. */
+ }
+
+ sig = TARGET_SIGFPE;
+ if ((n & 0x03) == 0) {
+ /* An IEEE exception, simulated or otherwise. */
if (n & 0x80) {
n = TARGET_FPE_FLTINV;
} else if (n & 0x40) {
@@ -132,13 +134,12 @@ void cpu_loop(CPUS390XState *env)
n = TARGET_FPE_FLTUND;
} else if (n & 0x08) {
n = TARGET_FPE_FLTRES;
- } else {
- /* ??? Quantum exception; BFP, DFP error. */
- goto do_sigill_opn;
}
- sig = TARGET_SIGFPE;
- goto do_signal_pc;
+ } else {
+ /* compare-and-trap */
+ n = 0;
}
+ goto do_signal_pc;
default:
fprintf(stderr, "Unhandled program exception: %#x\n", n);
--
2.31.1
On Mon, 2021-06-21 at 10:14 -0400, Jonathan Albrecht wrote: > Currently when a compare-and-trap instruction is executed, qemu will > always raise a SIGILL signal. On real hardware, a SIGFPE is raised. > > Change the PGM_DATA case in cpu_loop to follow the behavior in > linux kernel /arch/s390/kernel/traps.c. > * Only raise SIGILL if DXC == 0 > * If DXC matches an IEEE exception, raise SIGFPE with correct si_code > * Raise SIGFPE with si_code == 0 for everything else > > When applied on 20210602002210.3144559-2-iii@linux.ibm.com, this fixes > crashes in the java jdk such as the linked bug. > > Buglink: https://bugs.launchpad.net/qemu/+bug/1920913 > Resolves: https://gitlab.com/qemu-project/qemu/-/issues/319 > Signed-off-by: Jonathan Albrecht < > jonathan.albrecht@linux.vnet.ibm.com> > --- > linux-user/s390x/cpu_loop.c | 19 ++++++++++--------- > 1 file changed, 10 insertions(+), 9 deletions(-) I tried this on top of my SIGILL patch to run Maven, it worked without issues. Acked-by: Ilya Leoshkevich <iii@linux.ibm.com> Tested-by: Ilya Leoshkevich <iii@linux.ibm.com>
© 2016 - 2025 Red Hat, Inc.