From: Ilya Leoshkevich <iii@linux.ibm.com>
To: Richard Henderson <richard.henderson@linaro.org>,
David Hildenbrand <david@redhat.com>,
Laurent Vivier <laurent@vivier.eu>,
Cornelia Huck <cohuck@redhat.com>
Cc: Christian Borntraeger <borntraeger@de.ibm.com>,
qemu-s390x@nongnu.org, qemu-devel@nongnu.org,
Ilya Leoshkevich <iii@linux.ibm.com>,
Andreas Krebbel <krebbel@linux.ibm.com>
Subject: [PATCH v2 1/2] target/s390x: Fix SIGILL psw.addr reporting
Date: Fri, 21 May 2021 13:19:07 +0200 [thread overview]
Message-ID: <20210521111908.2843735-2-iii@linux.ibm.com> (raw)
In-Reply-To: <20210521111908.2843735-1-iii@linux.ibm.com>
When a s390x CPU attempts to execute an illegal instruction, an
operation exception is recognized. This is a suppressing exception,
which means that the PSW is advanced by the length of the illegal
instruction.
On the real hardware or in qemu-system-s390x the kernel then raises
SIGILL with si_addr pointing to the suppressed instruction and
psw.addr containing the updated PSW.
Unfortunately qemu-s390x sets both to the address of the suppressed
instruction at the moment. Fix by sharing the PSW advancement logic
with qemu-system-s390x and setting si_addr to the address of the
instruction that raised the exception.
Buglink: https://gitlab.com/qemu-project/qemu/-/issues/319
Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
Reviewed-by: David Hildenbrand <david@redhat.com>
---
linux-user/s390x/cpu_loop.c | 6 +++-
target/s390x/excp_helper.c | 69 ++++++++++++++++++++-----------------
target/s390x/internal.h | 1 +
3 files changed, 43 insertions(+), 33 deletions(-)
diff --git a/linux-user/s390x/cpu_loop.c b/linux-user/s390x/cpu_loop.c
index f2d1215fb1..6f5462d4f8 100644
--- a/linux-user/s390x/cpu_loop.c
+++ b/linux-user/s390x/cpu_loop.c
@@ -21,6 +21,7 @@
#include "qemu-common.h"
#include "qemu.h"
#include "cpu_loop-common.h"
+#include "internal.h"
/* s390x masks the fault address it reports in si_addr for SIGSEGV and SIGBUS */
#define S390X_FAIL_ADDR_MASK -4096LL
@@ -29,6 +30,7 @@ void cpu_loop(CPUS390XState *env)
{
CPUState *cs = env_cpu(env);
int trapnr, n, sig;
+ target_ulong excp_psw_addr;
target_siginfo_t info;
target_ulong addr;
abi_long ret;
@@ -38,6 +40,7 @@ void cpu_loop(CPUS390XState *env)
trapnr = cpu_exec(cs);
cpu_exec_end(cs);
process_queued_cpu_work(cs);
+ excp_psw_addr = env->psw.addr;
switch (trapnr) {
case EXCP_INTERRUPT:
@@ -66,6 +69,7 @@ void cpu_loop(CPUS390XState *env)
n = TARGET_TRAP_BRKPT;
goto do_signal_pc;
case EXCP_PGM:
+ s390_cpu_program_interrupt_advance_psw(env);
n = env->int_pgm_code;
switch (n) {
case PGM_OPERATION:
@@ -131,7 +135,7 @@ void cpu_loop(CPUS390XState *env)
break;
do_signal_pc:
- addr = env->psw.addr;
+ addr = excp_psw_addr;
do_signal:
info.si_signo = sig;
info.si_errno = 0;
diff --git a/target/s390x/excp_helper.c b/target/s390x/excp_helper.c
index 20625c2c8f..0a323967ae 100644
--- a/target/s390x/excp_helper.c
+++ b/target/s390x/excp_helper.c
@@ -82,6 +82,42 @@ void HELPER(data_exception)(CPUS390XState *env, uint32_t dxc)
tcg_s390_data_exception(env, dxc, GETPC());
}
+void s390_cpu_program_interrupt_advance_psw(CPUS390XState *env)
+{
+ switch (env->int_pgm_code) {
+ case PGM_PER:
+ if (env->per_perc_atmid & PER_CODE_EVENT_NULLIFICATION) {
+ break;
+ }
+ /* FALL THROUGH */
+ case PGM_OPERATION:
+ case PGM_PRIVILEGED:
+ case PGM_EXECUTE:
+ case PGM_PROTECTION:
+ case PGM_ADDRESSING:
+ case PGM_SPECIFICATION:
+ case PGM_DATA:
+ case PGM_FIXPT_OVERFLOW:
+ case PGM_FIXPT_DIVIDE:
+ case PGM_DEC_OVERFLOW:
+ case PGM_DEC_DIVIDE:
+ case PGM_HFP_EXP_OVERFLOW:
+ case PGM_HFP_EXP_UNDERFLOW:
+ case PGM_HFP_SIGNIFICANCE:
+ case PGM_HFP_DIVIDE:
+ case PGM_TRANS_SPEC:
+ case PGM_SPECIAL_OP:
+ case PGM_OPERAND:
+ case PGM_HFP_SQRT:
+ case PGM_PC_TRANS_SPEC:
+ case PGM_ALET_SPEC:
+ case PGM_MONITOR:
+ /* advance the PSW if our exception is not nullifying */
+ env->psw.addr += env->int_pgm_ilen;
+ break;
+ }
+}
+
#if defined(CONFIG_USER_ONLY)
void s390_cpu_do_interrupt(CPUState *cs)
@@ -202,38 +238,7 @@ static void do_program_interrupt(CPUS390XState *env)
assert(ilen == 2 || ilen == 4 || ilen == 6);
- switch (env->int_pgm_code) {
- case PGM_PER:
- if (env->per_perc_atmid & PER_CODE_EVENT_NULLIFICATION) {
- break;
- }
- /* FALL THROUGH */
- case PGM_OPERATION:
- case PGM_PRIVILEGED:
- case PGM_EXECUTE:
- case PGM_PROTECTION:
- case PGM_ADDRESSING:
- case PGM_SPECIFICATION:
- case PGM_DATA:
- case PGM_FIXPT_OVERFLOW:
- case PGM_FIXPT_DIVIDE:
- case PGM_DEC_OVERFLOW:
- case PGM_DEC_DIVIDE:
- case PGM_HFP_EXP_OVERFLOW:
- case PGM_HFP_EXP_UNDERFLOW:
- case PGM_HFP_SIGNIFICANCE:
- case PGM_HFP_DIVIDE:
- case PGM_TRANS_SPEC:
- case PGM_SPECIAL_OP:
- case PGM_OPERAND:
- case PGM_HFP_SQRT:
- case PGM_PC_TRANS_SPEC:
- case PGM_ALET_SPEC:
- case PGM_MONITOR:
- /* advance the PSW if our exception is not nullifying */
- env->psw.addr += ilen;
- break;
- }
+ s390_cpu_program_interrupt_advance_psw(env);
qemu_log_mask(CPU_LOG_INT,
"%s: code=0x%x ilen=%d psw: %" PRIx64 " %" PRIx64 "\n",
diff --git a/target/s390x/internal.h b/target/s390x/internal.h
index 11515bb617..9f1665ccbf 100644
--- a/target/s390x/internal.h
+++ b/target/s390x/internal.h
@@ -272,6 +272,7 @@ bool s390_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
void s390x_cpu_do_unaligned_access(CPUState *cs, vaddr addr,
MMUAccessType access_type,
int mmu_idx, uintptr_t retaddr);
+void s390_cpu_program_interrupt_advance_psw(CPUS390XState *cpu);
/* fpu_helper.c */
--
2.31.1
next prev parent reply other threads:[~2021-05-21 11:22 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-05-21 11:19 [PATCH v2 0/2] target/s390x: Fix SIGILL psw.addr reporting Ilya Leoshkevich
2021-05-21 11:19 ` Ilya Leoshkevich [this message]
2021-05-21 11:19 ` [PATCH v2 2/2] tests/tcg/s390x: Test SIGILL handling Ilya Leoshkevich
2021-05-21 11:22 ` David Hildenbrand
2021-05-21 11:30 ` [PATCH v2 0/2] target/s390x: Fix SIGILL psw.addr reporting no-reply
2021-06-01 12:38 ` Ilya Leoshkevich
2021-06-01 15:52 ` Ilya Leoshkevich
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20210521111908.2843735-2-iii@linux.ibm.com \
--to=iii@linux.ibm.com \
--cc=borntraeger@de.ibm.com \
--cc=cohuck@redhat.com \
--cc=david@redhat.com \
--cc=krebbel@linux.ibm.com \
--cc=laurent@vivier.eu \
--cc=qemu-devel@nongnu.org \
--cc=qemu-s390x@nongnu.org \
--cc=richard.henderson@linaro.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).