diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2021-08-03 19:50:43 +0100 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2021-08-03 19:50:43 +0100 |
commit | cb2f4b8750b7e1c954570d19b104d4fdbeb8739a (patch) | |
tree | 5e2cae8b93c7f33f34524ab7ba68560bd446463c /linux-user | |
parent | 2cd9e2bd093a8b6f0e9fc6d75f4fd8f0e3250474 (diff) | |
parent | 50e36dd61652a4a4f2af245655ed3ca08ef0a3ed (diff) | |
download | qemu-cb2f4b8750b7e1c954570d19b104d4fdbeb8739a.zip qemu-cb2f4b8750b7e1c954570d19b104d4fdbeb8739a.tar.gz qemu-cb2f4b8750b7e1c954570d19b104d4fdbeb8739a.tar.bz2 |
Merge remote-tracking branch 'remotes/thuth-gitlab/tags/pull-request-2021-08-03' into staging
* Fixes for SIGILL and SIGFPE of the s390x linux-user target
# gpg: Signature made Tue 03 Aug 2021 14:30:54 BST
# gpg: using RSA key 27B88847EEE0250118F3EAB92ED9D774FE702DB5
# gpg: issuer "thuth@redhat.com"
# gpg: Good signature from "Thomas Huth <th.huth@gmx.de>" [full]
# gpg: aka "Thomas Huth <thuth@redhat.com>" [full]
# gpg: aka "Thomas Huth <huth@tuxfamily.org>" [full]
# gpg: aka "Thomas Huth <th.huth@posteo.de>" [unknown]
# Primary key fingerprint: 27B8 8847 EEE0 2501 18F3 EAB9 2ED9 D774 FE70 2DB5
* remotes/thuth-gitlab/tags/pull-request-2021-08-03:
tests/tcg: Test that compare-and-trap raises SIGFPE
linux-user/s390x: signal with SIGFPE on compare-and-trap
target/s390x: Fix SIGILL and SIGFPE psw.addr reporting
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'linux-user')
-rw-r--r-- | linux-user/s390x/cpu_loop.c | 66 |
1 files changed, 45 insertions, 21 deletions
diff --git a/linux-user/s390x/cpu_loop.c b/linux-user/s390x/cpu_loop.c index f2d1215..6a69a6d 100644 --- a/linux-user/s390x/cpu_loop.c +++ b/linux-user/s390x/cpu_loop.c @@ -25,6 +25,35 @@ /* s390x masks the fault address it reports in si_addr for SIGSEGV and SIGBUS */ #define S390X_FAIL_ADDR_MASK -4096LL +static int get_pgm_data_si_code(int dxc_code) +{ + switch (dxc_code) { + /* Non-simulated IEEE exceptions */ + case 0x80: + return TARGET_FPE_FLTINV; + case 0x40: + return TARGET_FPE_FLTDIV; + case 0x20: + case 0x28: + case 0x2c: + return TARGET_FPE_FLTOVF; + case 0x10: + case 0x18: + case 0x1c: + return TARGET_FPE_FLTUND; + case 0x08: + case 0x0c: + return TARGET_FPE_FLTRES; + } + /* + * Non-IEEE and simulated IEEE: + * Includes compare-and-trap, quantum exception, etc. + * Simulated IEEE are included here to match current + * s390x linux kernel. + */ + return 0; +} + void cpu_loop(CPUS390XState *env) { CPUState *cs = env_cpu(env); @@ -64,7 +93,13 @@ void cpu_loop(CPUS390XState *env) case EXCP_DEBUG: sig = TARGET_SIGTRAP; n = TARGET_TRAP_BRKPT; - goto do_signal_pc; + /* + * For SIGTRAP the PSW must point after the instruction, which it + * already does thanks to s390x_tr_tb_stop(). si_addr doesn't need + * to be filled. + */ + addr = 0; + goto do_signal; case EXCP_PGM: n = env->int_pgm_code; switch (n) { @@ -100,29 +135,14 @@ 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. */ - if (n & 0x80) { - n = TARGET_FPE_FLTINV; - } else if (n & 0x40) { - n = TARGET_FPE_FLTDIV; - } else if (n & 0x20) { - n = TARGET_FPE_FLTOVF; - } else if (n & 0x10) { - 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; } + sig = TARGET_SIGFPE; + n = get_pgm_data_si_code(n); + goto do_signal_pc; + default: fprintf(stderr, "Unhandled program exception: %#x\n", n); cpu_dump_state(cs, stderr, 0); @@ -132,6 +152,10 @@ void cpu_loop(CPUS390XState *env) do_signal_pc: addr = env->psw.addr; + /* + * For SIGILL and SIGFPE the PSW must point after the instruction. + */ + env->psw.addr += env->int_pgm_ilen; do_signal: info.si_signo = sig; info.si_errno = 0; |