qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v3 00/18] target/s390: Use tcg unwinding for ilen
@ 2019-09-26 16:25 Richard Henderson
  2019-09-26 16:25 ` [PATCH v3 01/18] target/s390x: Truncate 32-bit psw_addr before creating TB Richard Henderson
                   ` (18 more replies)
  0 siblings, 19 replies; 49+ messages in thread
From: Richard Henderson @ 2019-09-26 16:25 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-s390x, david

David's cleanup of some of the mmu code reminded me of an old branch
that I have laying around.  His new code allowed me to finish this
idea up to completely transition away from ILEN_AUTO.

V1 was posted back in 2017:
   https://lists.gnu.org/archive/html/qemu-devel/2017-07/msg07607.html
V2 was posted back in April:
   https://lists.gnu.org/archive/html/qemu-devel/2019-04/msg00063.html

Based-on: <20190925125236.4043-1-david@redhat.com> \
  ("s390x/mmu: DAT translation rewrite")


r~


Richard Henderson (18):
  target/s390x: Truncate 32-bit psw_addr before creating TB
  target/s390x: Add ilen to unwind data
  target/s390x: Remove ilen parameter from tcg_s390_program_interrupt
  target/s390x: Remove ilen parameter from s390_program_interrupt
  target/s390x: Use tcg_s390_program_interrupt in TCG helpers
  target/s390x: Push trigger_pgm_exception lower in s390_cpu_tlb_fill
  target/s390x: Handle tec in s390_cpu_tlb_fill
  target/s390: Return exception from mmu_translate_real
  target/s390x: Remove exc argument to mmu_translate_asce
  target/s390: Return exception from mmu_translate
  target/s390: Return exception from translate_pages
  target/s390x: Remove fail variable from s390_cpu_tlb_fill
  target/s390x: Simplify helper_lra
  target/s390x: Rely on unwinding in s390_cpu_tlb_fill
  target/s390x: Rely on unwinding in s390_cpu_virt_mem_rw
  target/s390x: Remove ILEN_AUTO
  target/s390x: Remove ilen argument from trigger_access_exception
  target/s390x: Remove ilen argument from trigger_pgm_exception

 target/s390x/cpu.h           | 35 ++++++++++++++-------
 target/s390x/internal.h      |  6 ++--
 target/s390x/tcg_s390x.h     |  4 +--
 hw/s390x/s390-pci-inst.c     | 58 +++++++++++++++++-----------------
 target/s390x/cc_helper.c     |  4 +--
 target/s390x/crypto_helper.c |  7 ++---
 target/s390x/diag.c          | 14 ++++-----
 target/s390x/excp_helper.c   | 60 ++++++++++++++++-------------------
 target/s390x/fpu_helper.c    |  6 ++--
 target/s390x/int_helper.c    | 15 ++++-----
 target/s390x/interrupt.c     |  9 +++---
 target/s390x/ioinst.c        | 40 +++++++++++------------
 target/s390x/mem_helper.c    | 61 +++++++++++++++++-------------------
 target/s390x/misc_helper.c   | 27 ++++++----------
 target/s390x/mmu_helper.c    | 60 +++++++++++++++--------------------
 target/s390x/tcg-stub.c      |  4 +--
 target/s390x/translate.c     | 27 ++++++++++------
 17 files changed, 214 insertions(+), 223 deletions(-)

-- 
2.17.1



^ permalink raw reply	[flat|nested] 49+ messages in thread

* [PATCH v3 01/18] target/s390x: Truncate 32-bit psw_addr before creating TB
  2019-09-26 16:25 [PATCH v3 00/18] target/s390: Use tcg unwinding for ilen Richard Henderson
@ 2019-09-26 16:25 ` Richard Henderson
  2019-09-27 10:23   ` David Hildenbrand
  2019-09-26 16:25 ` [PATCH v3 02/18] target/s390x: Add ilen to unwind data Richard Henderson
                   ` (17 subsequent siblings)
  18 siblings, 1 reply; 49+ messages in thread
From: Richard Henderson @ 2019-09-26 16:25 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-s390x, david

If, somehow, the psw_addr is out of range, truncate early
rather than after we get into gen_intermediate_code.

Reviewed-by: David Hildenbrand <david@redhat.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/s390x/cpu.h       | 26 +++++++++++++++++++-------
 target/s390x/translate.c |  6 ------
 2 files changed, 19 insertions(+), 13 deletions(-)

diff --git a/target/s390x/cpu.h b/target/s390x/cpu.h
index e74a809257..ce20dafd23 100644
--- a/target/s390x/cpu.h
+++ b/target/s390x/cpu.h
@@ -357,18 +357,30 @@ static inline int cpu_mmu_index(CPUS390XState *env, bool ifetch)
 #endif
 }
 
-static inline void cpu_get_tb_cpu_state(CPUS390XState* env, target_ulong *pc,
-                                        target_ulong *cs_base, uint32_t *flags)
+static inline void cpu_get_tb_cpu_state(CPUS390XState* env,
+                                        target_ulong *p_pc,
+                                        target_ulong *cs_base,
+                                        uint32_t *p_flags)
 {
-    *pc = env->psw.addr;
-    *cs_base = env->ex_value;
-    *flags = (env->psw.mask >> FLAG_MASK_PSW_SHIFT) & FLAG_MASK_PSW;
+    uint32_t flags;
+    uint64_t pc;
+
+    flags = (env->psw.mask >> FLAG_MASK_PSW_SHIFT) & FLAG_MASK_PSW;
     if (env->cregs[0] & CR0_AFP) {
-        *flags |= FLAG_MASK_AFP;
+        flags |= FLAG_MASK_AFP;
     }
     if (env->cregs[0] & CR0_VECTOR) {
-        *flags |= FLAG_MASK_VECTOR;
+        flags |= FLAG_MASK_VECTOR;
     }
+
+    pc = env->psw.addr;
+    if (!(flags & FLAG_MASK_64)) {
+        pc &= 0x7fffffff;
+    }
+
+    *p_pc = pc;
+    *cs_base = env->ex_value;
+    *p_flags = flags;
 }
 
 /* PER bits from control register 9 */
diff --git a/target/s390x/translate.c b/target/s390x/translate.c
index a3e43ff9ec..e1c54ab03b 100644
--- a/target/s390x/translate.c
+++ b/target/s390x/translate.c
@@ -6446,12 +6446,6 @@ static void s390x_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
 {
     DisasContext *dc = container_of(dcbase, DisasContext, base);
 
-    /* 31-bit mode */
-    if (!(dc->base.tb->flags & FLAG_MASK_64)) {
-        dc->base.pc_first &= 0x7fffffff;
-        dc->base.pc_next = dc->base.pc_first;
-    }
-
     dc->cc_op = CC_OP_DYNAMIC;
     dc->ex_value = dc->base.tb->cs_base;
     dc->do_debug = dc->base.singlestep_enabled;
-- 
2.17.1



^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH v3 02/18] target/s390x: Add ilen to unwind data
  2019-09-26 16:25 [PATCH v3 00/18] target/s390: Use tcg unwinding for ilen Richard Henderson
  2019-09-26 16:25 ` [PATCH v3 01/18] target/s390x: Truncate 32-bit psw_addr before creating TB Richard Henderson
@ 2019-09-26 16:25 ` Richard Henderson
  2019-09-27 10:30   ` David Hildenbrand
  2019-09-26 16:26 ` [PATCH v3 03/18] target/s390x: Remove ilen parameter from tcg_s390_program_interrupt Richard Henderson
                   ` (16 subsequent siblings)
  18 siblings, 1 reply; 49+ messages in thread
From: Richard Henderson @ 2019-09-26 16:25 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-s390x, Richard Henderson, david

From: Richard Henderson <rth@twiddle.net>

Use ILEN_UNWIND to signal that we have in fact that
cpu_restore_state will have been called by the time
we arrive in do_program_interrupt.

Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 target/s390x/cpu.h       |  4 +++-
 target/s390x/interrupt.c |  5 ++++-
 target/s390x/translate.c | 21 ++++++++++++++++++---
 3 files changed, 25 insertions(+), 5 deletions(-)

diff --git a/target/s390x/cpu.h b/target/s390x/cpu.h
index ce20dafd23..080ebcd6bb 100644
--- a/target/s390x/cpu.h
+++ b/target/s390x/cpu.h
@@ -30,7 +30,7 @@
 /* The z/Architecture has a strong memory model with some store-after-load re-ordering */
 #define TCG_GUEST_DEFAULT_MO      (TCG_MO_ALL & ~TCG_MO_ST_LD)
 
-#define TARGET_INSN_START_EXTRA_WORDS 1
+#define TARGET_INSN_START_EXTRA_WORDS 2
 
 #define MMU_MODE0_SUFFIX _primary
 #define MMU_MODE1_SUFFIX _secondary
@@ -814,6 +814,8 @@ int cpu_s390x_signal_handler(int host_signum, void *pinfo, void *puc);
 void s390_crw_mchk(void);
 void s390_io_interrupt(uint16_t subchannel_id, uint16_t subchannel_nr,
                        uint32_t io_int_parm, uint32_t io_int_word);
+/* instruction length set by unwind info */
+#define ILEN_UNWIND                 0
 /* automatically detect the instruction length */
 #define ILEN_AUTO                   0xff
 #define RA_IGNORED                  0
diff --git a/target/s390x/interrupt.c b/target/s390x/interrupt.c
index a841f7187d..30a9fb8852 100644
--- a/target/s390x/interrupt.c
+++ b/target/s390x/interrupt.c
@@ -28,7 +28,10 @@ void trigger_pgm_exception(CPUS390XState *env, uint32_t code, uint32_t ilen)
 
     cs->exception_index = EXCP_PGM;
     env->int_pgm_code = code;
-    env->int_pgm_ilen = ilen;
+    /* If ILEN_UNWIND, int_pgm_ilen already has the correct value.  */
+    if (ilen != ILEN_UNWIND) {
+        env->int_pgm_ilen = ilen;
+    }
 }
 
 void s390_program_interrupt(CPUS390XState *env, uint32_t code, int ilen,
diff --git a/target/s390x/translate.c b/target/s390x/translate.c
index e1c54ab03b..08f99454de 100644
--- a/target/s390x/translate.c
+++ b/target/s390x/translate.c
@@ -6309,6 +6309,9 @@ static DisasJumpType translate_one(CPUS390XState *env, DisasContext *s)
     /* Search for the insn in the table.  */
     insn = extract_insn(env, s, &f);
 
+    /* Emit insn_start now that we know the ILEN.  */
+    tcg_gen_insn_start(s->base.pc_next, s->cc_op, s->ilen);
+
     /* Not found means unimplemented/illegal opcode.  */
     if (insn == NULL) {
         qemu_log_mask(LOG_UNIMP, "unimplemented opcode 0x%02x%02x\n",
@@ -6457,9 +6460,6 @@ static void s390x_tr_tb_start(DisasContextBase *db, CPUState *cs)
 
 static void s390x_tr_insn_start(DisasContextBase *dcbase, CPUState *cs)
 {
-    DisasContext *dc = container_of(dcbase, DisasContext, base);
-
-    tcg_gen_insn_start(dc->base.pc_next, dc->cc_op);
 }
 
 static bool s390x_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cs,
@@ -6467,6 +6467,12 @@ static bool s390x_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cs,
 {
     DisasContext *dc = container_of(dcbase, DisasContext, base);
 
+    /*
+     * Emit an insn_start to accompany the breakpoint exception.
+     * The ILEN value is a dummy, since we didn't actually read an insn.
+     */
+    tcg_gen_insn_start(dc->base.pc_next, dc->cc_op, 0);
+
     dc->base.is_jmp = DISAS_PC_STALE;
     dc->do_debug = true;
     /* The address covered by the breakpoint must be included in
@@ -6561,8 +6567,17 @@ void restore_state_to_opc(CPUS390XState *env, TranslationBlock *tb,
                           target_ulong *data)
 {
     int cc_op = data[1];
+    int ilen = data[2];
+
     env->psw.addr = data[0];
+
+    /* Update the CC opcode if it is not already up-to-date.  */
     if ((cc_op != CC_OP_DYNAMIC) && (cc_op != CC_OP_STATIC)) {
         env->cc_op = cc_op;
     }
+
+    /* Update ILEN, except for breakpoint, where we didn't load an insn.  */
+    if (ilen) {
+        env->int_pgm_ilen = ilen;
+    }
 }
-- 
2.17.1



^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH v3 03/18] target/s390x: Remove ilen parameter from tcg_s390_program_interrupt
  2019-09-26 16:25 [PATCH v3 00/18] target/s390: Use tcg unwinding for ilen Richard Henderson
  2019-09-26 16:25 ` [PATCH v3 01/18] target/s390x: Truncate 32-bit psw_addr before creating TB Richard Henderson
  2019-09-26 16:25 ` [PATCH v3 02/18] target/s390x: Add ilen to unwind data Richard Henderson
@ 2019-09-26 16:26 ` Richard Henderson
  2019-09-27 10:31   ` David Hildenbrand
  2019-09-26 16:26 ` [PATCH v3 04/18] target/s390x: Remove ilen parameter from s390_program_interrupt Richard Henderson
                   ` (15 subsequent siblings)
  18 siblings, 1 reply; 49+ messages in thread
From: Richard Henderson @ 2019-09-26 16:26 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-s390x, david

Since we begin the operation with an unwind, we have the proper
value of ilen immediately available.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/s390x/tcg_s390x.h   | 4 ++--
 target/s390x/excp_helper.c | 8 ++++----
 target/s390x/interrupt.c   | 2 +-
 target/s390x/tcg-stub.c    | 4 ++--
 4 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/target/s390x/tcg_s390x.h b/target/s390x/tcg_s390x.h
index 2813f9d48e..2f54ccb027 100644
--- a/target/s390x/tcg_s390x.h
+++ b/target/s390x/tcg_s390x.h
@@ -14,8 +14,8 @@
 #define TCG_S390X_H
 
 void tcg_s390_tod_updated(CPUState *cs, run_on_cpu_data opaque);
-void QEMU_NORETURN tcg_s390_program_interrupt(CPUS390XState *env, uint32_t code,
-                                              int ilen, uintptr_t ra);
+void QEMU_NORETURN tcg_s390_program_interrupt(CPUS390XState *env,
+                                              uint32_t code, uintptr_t ra);
 void QEMU_NORETURN tcg_s390_data_exception(CPUS390XState *env, uint32_t dxc,
                                            uintptr_t ra);
 void QEMU_NORETURN tcg_s390_vector_exception(CPUS390XState *env, uint32_t vxc,
diff --git a/target/s390x/excp_helper.c b/target/s390x/excp_helper.c
index 892f659d5a..681a9c59e1 100644
--- a/target/s390x/excp_helper.c
+++ b/target/s390x/excp_helper.c
@@ -34,15 +34,15 @@
 #include "hw/boards.h"
 #endif
 
-void QEMU_NORETURN tcg_s390_program_interrupt(CPUS390XState *env, uint32_t code,
-                                              int ilen, uintptr_t ra)
+void QEMU_NORETURN tcg_s390_program_interrupt(CPUS390XState *env,
+                                              uint32_t code, uintptr_t ra)
 {
     CPUState *cs = env_cpu(env);
 
     cpu_restore_state(cs, ra, true);
     qemu_log_mask(CPU_LOG_INT, "program interrupt at %#" PRIx64 "\n",
                   env->psw.addr);
-    trigger_pgm_exception(env, code, ilen);
+    trigger_pgm_exception(env, code, ILEN_UNWIND);
     cpu_loop_exit(cs);
 }
 
@@ -60,7 +60,7 @@ void QEMU_NORETURN tcg_s390_data_exception(CPUS390XState *env, uint32_t dxc,
     if (env->cregs[0] & CR0_AFP) {
         env->fpc = deposit32(env->fpc, 8, 8, dxc);
     }
-    tcg_s390_program_interrupt(env, PGM_DATA, ILEN_AUTO, ra);
+    tcg_s390_program_interrupt(env, PGM_DATA, ra);
 }
 
 void QEMU_NORETURN tcg_s390_vector_exception(CPUS390XState *env, uint32_t vxc,
diff --git a/target/s390x/interrupt.c b/target/s390x/interrupt.c
index 30a9fb8852..b798e2ecbe 100644
--- a/target/s390x/interrupt.c
+++ b/target/s390x/interrupt.c
@@ -40,7 +40,7 @@ void s390_program_interrupt(CPUS390XState *env, uint32_t code, int ilen,
     if (kvm_enabled()) {
         kvm_s390_program_interrupt(env_archcpu(env), code);
     } else if (tcg_enabled()) {
-        tcg_s390_program_interrupt(env, code, ilen, ra);
+        tcg_s390_program_interrupt(env, code, ra);
     } else {
         g_assert_not_reached();
     }
diff --git a/target/s390x/tcg-stub.c b/target/s390x/tcg-stub.c
index 32adb7276a..d22c898802 100644
--- a/target/s390x/tcg-stub.c
+++ b/target/s390x/tcg-stub.c
@@ -18,8 +18,8 @@
 void tcg_s390_tod_updated(CPUState *cs, run_on_cpu_data opaque)
 {
 }
-void QEMU_NORETURN tcg_s390_program_interrupt(CPUS390XState *env, uint32_t code,
-                                              int ilen, uintptr_t ra)
+void QEMU_NORETURN tcg_s390_program_interrupt(CPUS390XState *env,
+                                              uint32_t code, uintptr_t ra)
 {
     g_assert_not_reached();
 }
-- 
2.17.1



^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH v3 04/18] target/s390x: Remove ilen parameter from s390_program_interrupt
  2019-09-26 16:25 [PATCH v3 00/18] target/s390: Use tcg unwinding for ilen Richard Henderson
                   ` (2 preceding siblings ...)
  2019-09-26 16:26 ` [PATCH v3 03/18] target/s390x: Remove ilen parameter from tcg_s390_program_interrupt Richard Henderson
@ 2019-09-26 16:26 ` Richard Henderson
  2019-09-27 10:34   ` David Hildenbrand
  2019-09-26 16:26 ` [PATCH v3 05/18] target/s390x: Use tcg_s390_program_interrupt in TCG helpers Richard Henderson
                   ` (14 subsequent siblings)
  18 siblings, 1 reply; 49+ messages in thread
From: Richard Henderson @ 2019-09-26 16:26 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-s390x, david

This is no longer used, and many of the existing uses -- particularly
within hw/s390x -- seem questionable.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/s390x/cpu.h           |  3 +-
 hw/s390x/s390-pci-inst.c     | 58 ++++++++++++++++++------------------
 target/s390x/cc_helper.c     |  2 +-
 target/s390x/crypto_helper.c |  4 +--
 target/s390x/diag.c          | 14 ++++-----
 target/s390x/excp_helper.c   |  4 +--
 target/s390x/fpu_helper.c    |  6 ++--
 target/s390x/int_helper.c    | 14 ++++-----
 target/s390x/interrupt.c     |  3 +-
 target/s390x/ioinst.c        | 40 ++++++++++++-------------
 target/s390x/mem_helper.c    | 43 +++++++++++++-------------
 target/s390x/misc_helper.c   | 27 ++++++-----------
 12 files changed, 103 insertions(+), 115 deletions(-)

diff --git a/target/s390x/cpu.h b/target/s390x/cpu.h
index 080ebcd6bb..a5eab491cd 100644
--- a/target/s390x/cpu.h
+++ b/target/s390x/cpu.h
@@ -819,8 +819,7 @@ void s390_io_interrupt(uint16_t subchannel_id, uint16_t subchannel_nr,
 /* automatically detect the instruction length */
 #define ILEN_AUTO                   0xff
 #define RA_IGNORED                  0
-void s390_program_interrupt(CPUS390XState *env, uint32_t code, int ilen,
-                            uintptr_t ra);
+void s390_program_interrupt(CPUS390XState *env, uint32_t code, uintptr_t ra);
 /* service interrupts are floating therefore we must not pass an cpustate */
 void s390_sclp_extint(uint32_t parm);
 
diff --git a/hw/s390x/s390-pci-inst.c b/hw/s390x/s390-pci-inst.c
index 4b3bd4a804..92c7e45df5 100644
--- a/hw/s390x/s390-pci-inst.c
+++ b/hw/s390x/s390-pci-inst.c
@@ -157,7 +157,7 @@ int clp_service_call(S390CPU *cpu, uint8_t r2, uintptr_t ra)
     int i;
 
     if (env->psw.mask & PSW_MASK_PSTATE) {
-        s390_program_interrupt(env, PGM_PRIVILEGED, 4, ra);
+        s390_program_interrupt(env, PGM_PRIVILEGED, ra);
         return 0;
     }
 
@@ -168,7 +168,7 @@ int clp_service_call(S390CPU *cpu, uint8_t r2, uintptr_t ra)
     reqh = (ClpReqHdr *)buffer;
     req_len = lduw_p(&reqh->len);
     if (req_len < 16 || req_len > 8184 || (req_len % 8 != 0)) {
-        s390_program_interrupt(env, PGM_OPERAND, 4, ra);
+        s390_program_interrupt(env, PGM_OPERAND, ra);
         return 0;
     }
 
@@ -180,11 +180,11 @@ int clp_service_call(S390CPU *cpu, uint8_t r2, uintptr_t ra)
     resh = (ClpRspHdr *)(buffer + req_len);
     res_len = lduw_p(&resh->len);
     if (res_len < 8 || res_len > 8176 || (res_len % 8 != 0)) {
-        s390_program_interrupt(env, PGM_OPERAND, 4, ra);
+        s390_program_interrupt(env, PGM_OPERAND, ra);
         return 0;
     }
     if ((req_len + res_len) > 8192) {
-        s390_program_interrupt(env, PGM_OPERAND, 4, ra);
+        s390_program_interrupt(env, PGM_OPERAND, ra);
         return 0;
     }
 
@@ -390,12 +390,12 @@ int pcilg_service_call(S390CPU *cpu, uint8_t r1, uint8_t r2, uintptr_t ra)
     uint8_t pcias;
 
     if (env->psw.mask & PSW_MASK_PSTATE) {
-        s390_program_interrupt(env, PGM_PRIVILEGED, 4, ra);
+        s390_program_interrupt(env, PGM_PRIVILEGED, ra);
         return 0;
     }
 
     if (r2 & 0x1) {
-        s390_program_interrupt(env, PGM_SPECIFICATION, 4, ra);
+        s390_program_interrupt(env, PGM_SPECIFICATION, ra);
         return 0;
     }
 
@@ -429,25 +429,25 @@ int pcilg_service_call(S390CPU *cpu, uint8_t r1, uint8_t r2, uintptr_t ra)
     switch (pcias) {
     case ZPCI_IO_BAR_MIN...ZPCI_IO_BAR_MAX:
         if (!len || (len > (8 - (offset & 0x7)))) {
-            s390_program_interrupt(env, PGM_OPERAND, 4, ra);
+            s390_program_interrupt(env, PGM_OPERAND, ra);
             return 0;
         }
         result = zpci_read_bar(pbdev, pcias, offset, &data, len);
         if (result != MEMTX_OK) {
-            s390_program_interrupt(env, PGM_OPERAND, 4, ra);
+            s390_program_interrupt(env, PGM_OPERAND, ra);
             return 0;
         }
         break;
     case ZPCI_CONFIG_BAR:
         if (!len || (len > (4 - (offset & 0x3))) || len == 3) {
-            s390_program_interrupt(env, PGM_OPERAND, 4, ra);
+            s390_program_interrupt(env, PGM_OPERAND, ra);
             return 0;
         }
         data =  pci_host_config_read_common(
                    pbdev->pdev, offset, pci_config_size(pbdev->pdev), len);
 
         if (zpci_endian_swap(&data, len)) {
-            s390_program_interrupt(env, PGM_OPERAND, 4, ra);
+            s390_program_interrupt(env, PGM_OPERAND, ra);
             return 0;
         }
         break;
@@ -489,12 +489,12 @@ int pcistg_service_call(S390CPU *cpu, uint8_t r1, uint8_t r2, uintptr_t ra)
     uint8_t pcias;
 
     if (env->psw.mask & PSW_MASK_PSTATE) {
-        s390_program_interrupt(env, PGM_PRIVILEGED, 4, ra);
+        s390_program_interrupt(env, PGM_PRIVILEGED, ra);
         return 0;
     }
 
     if (r2 & 0x1) {
-        s390_program_interrupt(env, PGM_SPECIFICATION, 4, ra);
+        s390_program_interrupt(env, PGM_SPECIFICATION, ra);
         return 0;
     }
 
@@ -536,13 +536,13 @@ int pcistg_service_call(S390CPU *cpu, uint8_t r1, uint8_t r2, uintptr_t ra)
          * A length of 0 is invalid and length should not cross a double word
          */
         if (!len || (len > (8 - (offset & 0x7)))) {
-            s390_program_interrupt(env, PGM_OPERAND, 4, ra);
+            s390_program_interrupt(env, PGM_OPERAND, ra);
             return 0;
         }
 
         result = zpci_write_bar(pbdev, pcias, offset, data, len);
         if (result != MEMTX_OK) {
-            s390_program_interrupt(env, PGM_OPERAND, 4, ra);
+            s390_program_interrupt(env, PGM_OPERAND, ra);
             return 0;
         }
         break;
@@ -550,7 +550,7 @@ int pcistg_service_call(S390CPU *cpu, uint8_t r1, uint8_t r2, uintptr_t ra)
         /* ZPCI uses the pseudo BAR number 15 as configuration space */
         /* possible access lengths are 1,2,4 and must not cross a word */
         if (!len || (len > (4 - (offset & 0x3))) || len == 3) {
-            s390_program_interrupt(env, PGM_OPERAND, 4, ra);
+            s390_program_interrupt(env, PGM_OPERAND, ra);
             return 0;
         }
         /* len = 1,2,4 so we do not need to test */
@@ -622,12 +622,12 @@ int rpcit_service_call(S390CPU *cpu, uint8_t r1, uint8_t r2, uintptr_t ra)
     hwaddr start, end;
 
     if (env->psw.mask & PSW_MASK_PSTATE) {
-        s390_program_interrupt(env, PGM_PRIVILEGED, 4, ra);
+        s390_program_interrupt(env, PGM_PRIVILEGED, ra);
         return 0;
     }
 
     if (r2 & 0x1) {
-        s390_program_interrupt(env, PGM_SPECIFICATION, 4, ra);
+        s390_program_interrupt(env, PGM_SPECIFICATION, ra);
         return 0;
     }
 
@@ -709,7 +709,7 @@ int pcistb_service_call(S390CPU *cpu, uint8_t r1, uint8_t r3, uint64_t gaddr,
     uint8_t buffer[128];
 
     if (env->psw.mask & PSW_MASK_PSTATE) {
-        s390_program_interrupt(env, PGM_PRIVILEGED, 6, ra);
+        s390_program_interrupt(env, PGM_PRIVILEGED, ra);
         return 0;
     }
 
@@ -772,7 +772,7 @@ int pcistb_service_call(S390CPU *cpu, uint8_t r1, uint8_t r3, uint64_t gaddr,
 
     if (!memory_region_access_valid(mr, offset, len, true,
                                     MEMTXATTRS_UNSPECIFIED)) {
-        s390_program_interrupt(env, PGM_OPERAND, 6, ra);
+        s390_program_interrupt(env, PGM_OPERAND, ra);
         return 0;
     }
 
@@ -786,7 +786,7 @@ int pcistb_service_call(S390CPU *cpu, uint8_t r1, uint8_t r3, uint64_t gaddr,
                                               ldq_p(buffer + i * 8),
                                               MO_64, MEMTXATTRS_UNSPECIFIED);
         if (result != MEMTX_OK) {
-            s390_program_interrupt(env, PGM_OPERAND, 6, ra);
+            s390_program_interrupt(env, PGM_OPERAND, ra);
             return 0;
         }
     }
@@ -797,7 +797,7 @@ int pcistb_service_call(S390CPU *cpu, uint8_t r1, uint8_t r3, uint64_t gaddr,
     return 0;
 
 specification_error:
-    s390_program_interrupt(env, PGM_SPECIFICATION, 6, ra);
+    s390_program_interrupt(env, PGM_SPECIFICATION, ra);
     return 0;
 }
 
@@ -871,14 +871,14 @@ static int reg_ioat(CPUS390XState *env, S390PCIIOMMU *iommu, ZpciFib fib,
     pba &= ~0xfff;
     pal |= 0xfff;
     if (pba > pal || pba < ZPCI_SDMA_ADDR || pal > ZPCI_EDMA_ADDR) {
-        s390_program_interrupt(env, PGM_OPERAND, 6, ra);
+        s390_program_interrupt(env, PGM_OPERAND, ra);
         return -EINVAL;
     }
 
     /* currently we only support designation type 1 with translation */
     if (!(dt == ZPCI_IOTA_RTTO && t)) {
         error_report("unsupported ioat dt %d t %d", dt, t);
-        s390_program_interrupt(env, PGM_OPERAND, 6, ra);
+        s390_program_interrupt(env, PGM_OPERAND, ra);
         return -EINVAL;
     }
 
@@ -1003,7 +1003,7 @@ int mpcifc_service_call(S390CPU *cpu, uint8_t r1, uint64_t fiba, uint8_t ar,
     uint64_t cc = ZPCI_PCI_LS_OK;
 
     if (env->psw.mask & PSW_MASK_PSTATE) {
-        s390_program_interrupt(env, PGM_PRIVILEGED, 6, ra);
+        s390_program_interrupt(env, PGM_PRIVILEGED, ra);
         return 0;
     }
 
@@ -1012,7 +1012,7 @@ int mpcifc_service_call(S390CPU *cpu, uint8_t r1, uint64_t fiba, uint8_t ar,
     fh = env->regs[r1] >> 32;
 
     if (fiba & 0x7) {
-        s390_program_interrupt(env, PGM_SPECIFICATION, 6, ra);
+        s390_program_interrupt(env, PGM_SPECIFICATION, ra);
         return 0;
     }
 
@@ -1040,7 +1040,7 @@ int mpcifc_service_call(S390CPU *cpu, uint8_t r1, uint64_t fiba, uint8_t ar,
     }
 
     if (fib.fmt != 0) {
-        s390_program_interrupt(env, PGM_OPERAND, 6, ra);
+        s390_program_interrupt(env, PGM_OPERAND, ra);
         return 0;
     }
 
@@ -1151,7 +1151,7 @@ int mpcifc_service_call(S390CPU *cpu, uint8_t r1, uint64_t fiba, uint8_t ar,
         break;
     }
     default:
-        s390_program_interrupt(&cpu->env, PGM_OPERAND, 6, ra);
+        s390_program_interrupt(&cpu->env, PGM_OPERAND, ra);
         cc = ZPCI_PCI_LS_ERR;
     }
 
@@ -1171,7 +1171,7 @@ int stpcifc_service_call(S390CPU *cpu, uint8_t r1, uint64_t fiba, uint8_t ar,
     uint64_t cc = ZPCI_PCI_LS_OK;
 
     if (env->psw.mask & PSW_MASK_PSTATE) {
-        s390_program_interrupt(env, PGM_PRIVILEGED, 6, ra);
+        s390_program_interrupt(env, PGM_PRIVILEGED, ra);
         return 0;
     }
 
@@ -1185,7 +1185,7 @@ int stpcifc_service_call(S390CPU *cpu, uint8_t r1, uint64_t fiba, uint8_t ar,
     }
 
     if (fiba & 0x7) {
-        s390_program_interrupt(env, PGM_SPECIFICATION, 6, ra);
+        s390_program_interrupt(env, PGM_SPECIFICATION, ra);
         return 0;
     }
 
diff --git a/target/s390x/cc_helper.c b/target/s390x/cc_helper.c
index cf68792733..3cb00bcb09 100644
--- a/target/s390x/cc_helper.c
+++ b/target/s390x/cc_helper.c
@@ -588,7 +588,7 @@ void HELPER(sacf)(CPUS390XState *env, uint64_t a1)
         break;
     default:
         HELPER_LOG("unknown sacf mode: %" PRIx64 "\n", a1);
-        s390_program_interrupt(env, PGM_SPECIFICATION, 2, GETPC());
+        s390_program_interrupt(env, PGM_SPECIFICATION, GETPC());
         break;
     }
 }
diff --git a/target/s390x/crypto_helper.c b/target/s390x/crypto_helper.c
index 5c79790187..1f83987e9d 100644
--- a/target/s390x/crypto_helper.c
+++ b/target/s390x/crypto_helper.c
@@ -34,7 +34,7 @@ uint32_t HELPER(msa)(CPUS390XState *env, uint32_t r1, uint32_t r2, uint32_t r3,
     case S390_FEAT_TYPE_PCKMO:
     case S390_FEAT_TYPE_PCC:
         if (mod) {
-            s390_program_interrupt(env, PGM_SPECIFICATION, 4, ra);
+            s390_program_interrupt(env, PGM_SPECIFICATION, ra);
             return 0;
         }
         break;
@@ -42,7 +42,7 @@ uint32_t HELPER(msa)(CPUS390XState *env, uint32_t r1, uint32_t r2, uint32_t r3,
 
     s390_get_feat_block(type, subfunc);
     if (!test_be_bit(fc, subfunc)) {
-        s390_program_interrupt(env, PGM_SPECIFICATION, 4, ra);
+        s390_program_interrupt(env, PGM_SPECIFICATION, ra);
         return 0;
     }
 
diff --git a/target/s390x/diag.c b/target/s390x/diag.c
index 65eabf0461..53c2f81f2a 100644
--- a/target/s390x/diag.c
+++ b/target/s390x/diag.c
@@ -61,12 +61,12 @@ void handle_diag_308(CPUS390XState *env, uint64_t r1, uint64_t r3, uintptr_t ra)
     IplParameterBlock *iplb;
 
     if (env->psw.mask & PSW_MASK_PSTATE) {
-        s390_program_interrupt(env, PGM_PRIVILEGED, ILEN_AUTO, ra);
+        s390_program_interrupt(env, PGM_PRIVILEGED, ra);
         return;
     }
 
     if ((subcode & ~0x0ffffULL) || (subcode > 6)) {
-        s390_program_interrupt(env, PGM_SPECIFICATION, ILEN_AUTO, ra);
+        s390_program_interrupt(env, PGM_SPECIFICATION, ra);
         return;
     }
 
@@ -82,13 +82,13 @@ void handle_diag_308(CPUS390XState *env, uint64_t r1, uint64_t r3, uintptr_t ra)
         break;
     case 5:
         if ((r1 & 1) || (addr & 0x0fffULL)) {
-            s390_program_interrupt(env, PGM_SPECIFICATION, ILEN_AUTO, ra);
+            s390_program_interrupt(env, PGM_SPECIFICATION, ra);
             return;
         }
         if (!address_space_access_valid(&address_space_memory, addr,
                                         sizeof(IplParameterBlock), false,
                                         MEMTXATTRS_UNSPECIFIED)) {
-            s390_program_interrupt(env, PGM_ADDRESSING, ILEN_AUTO, ra);
+            s390_program_interrupt(env, PGM_ADDRESSING, ra);
             return;
         }
         iplb = g_new0(IplParameterBlock, 1);
@@ -112,13 +112,13 @@ out:
         return;
     case 6:
         if ((r1 & 1) || (addr & 0x0fffULL)) {
-            s390_program_interrupt(env, PGM_SPECIFICATION, ILEN_AUTO, ra);
+            s390_program_interrupt(env, PGM_SPECIFICATION, ra);
             return;
         }
         if (!address_space_access_valid(&address_space_memory, addr,
                                         sizeof(IplParameterBlock), true,
                                         MEMTXATTRS_UNSPECIFIED)) {
-            s390_program_interrupt(env, PGM_ADDRESSING, ILEN_AUTO, ra);
+            s390_program_interrupt(env, PGM_ADDRESSING, ra);
             return;
         }
         iplb = s390_ipl_get_iplb();
@@ -130,7 +130,7 @@ out:
         }
         return;
     default:
-        s390_program_interrupt(env, PGM_SPECIFICATION, ILEN_AUTO, ra);
+        s390_program_interrupt(env, PGM_SPECIFICATION, ra);
         break;
     }
 }
diff --git a/target/s390x/excp_helper.c b/target/s390x/excp_helper.c
index 681a9c59e1..089623a248 100644
--- a/target/s390x/excp_helper.c
+++ b/target/s390x/excp_helper.c
@@ -75,7 +75,7 @@ void QEMU_NORETURN tcg_s390_vector_exception(CPUS390XState *env, uint32_t vxc,
 
     /* Always store the VXC into the FPC, without AFP it is undefined */
     env->fpc = deposit32(env->fpc, 8, 8, vxc);
-    tcg_s390_program_interrupt(env, PGM_VECTOR_PROCESSING, ILEN_AUTO, ra);
+    tcg_s390_program_interrupt(env, PGM_VECTOR_PROCESSING, ra);
 }
 
 void HELPER(data_exception)(CPUS390XState *env, uint32_t dxc)
@@ -614,7 +614,7 @@ void s390x_cpu_do_unaligned_access(CPUState *cs, vaddr addr,
     S390CPU *cpu = S390_CPU(cs);
     CPUS390XState *env = &cpu->env;
 
-    s390_program_interrupt(env, PGM_SPECIFICATION, ILEN_AUTO, retaddr);
+    s390_program_interrupt(env, PGM_SPECIFICATION, retaddr);
 }
 
 #endif /* CONFIG_USER_ONLY */
diff --git a/target/s390x/fpu_helper.c b/target/s390x/fpu_helper.c
index 5faf973c6c..7228eb96e2 100644
--- a/target/s390x/fpu_helper.c
+++ b/target/s390x/fpu_helper.c
@@ -825,7 +825,7 @@ void HELPER(sfpc)(CPUS390XState *env, uint64_t fpc)
 {
     if (fpc_to_rnd[fpc & 0x7] == -1 || fpc & 0x03030088u ||
         (!s390_has_feat(S390_FEAT_FLOATING_POINT_EXT) && fpc & 0x4)) {
-        s390_program_interrupt(env, PGM_SPECIFICATION, ILEN_AUTO, GETPC());
+        s390_program_interrupt(env, PGM_SPECIFICATION, GETPC());
     }
 
     /* Install everything in the main FPC.  */
@@ -843,7 +843,7 @@ void HELPER(sfas)(CPUS390XState *env, uint64_t fpc)
 
     if (fpc_to_rnd[fpc & 0x7] == -1 || fpc & 0x03030088u ||
         (!s390_has_feat(S390_FEAT_FLOATING_POINT_EXT) && fpc & 0x4)) {
-        s390_program_interrupt(env, PGM_SPECIFICATION, ILEN_AUTO, GETPC());
+        s390_program_interrupt(env, PGM_SPECIFICATION, GETPC());
     }
 
     /*
@@ -880,7 +880,7 @@ void HELPER(sfas)(CPUS390XState *env, uint64_t fpc)
 void HELPER(srnm)(CPUS390XState *env, uint64_t rnd)
 {
     if (rnd > 0x7 || fpc_to_rnd[rnd & 0x7] == -1) {
-        s390_program_interrupt(env, PGM_SPECIFICATION, ILEN_AUTO, GETPC());
+        s390_program_interrupt(env, PGM_SPECIFICATION, GETPC());
     }
 
     env->fpc = deposit32(env->fpc, 0, 3, rnd);
diff --git a/target/s390x/int_helper.c b/target/s390x/int_helper.c
index d13cc49be6..1d29a1fc1f 100644
--- a/target/s390x/int_helper.c
+++ b/target/s390x/int_helper.c
@@ -39,7 +39,7 @@ int64_t HELPER(divs32)(CPUS390XState *env, int64_t a, int64_t b64)
     int64_t q;
 
     if (b == 0) {
-        s390_program_interrupt(env, PGM_FIXPT_DIVIDE, ILEN_AUTO, GETPC());
+        s390_program_interrupt(env, PGM_FIXPT_DIVIDE, GETPC());
     }
 
     ret = q = a / b;
@@ -47,7 +47,7 @@ int64_t HELPER(divs32)(CPUS390XState *env, int64_t a, int64_t b64)
 
     /* Catch non-representable quotient.  */
     if (ret != q) {
-        s390_program_interrupt(env, PGM_FIXPT_DIVIDE, ILEN_AUTO, GETPC());
+        s390_program_interrupt(env, PGM_FIXPT_DIVIDE, GETPC());
     }
 
     return ret;
@@ -60,7 +60,7 @@ uint64_t HELPER(divu32)(CPUS390XState *env, uint64_t a, uint64_t b64)
     uint64_t q;
 
     if (b == 0) {
-        s390_program_interrupt(env, PGM_FIXPT_DIVIDE, ILEN_AUTO, GETPC());
+        s390_program_interrupt(env, PGM_FIXPT_DIVIDE, GETPC());
     }
 
     ret = q = a / b;
@@ -68,7 +68,7 @@ uint64_t HELPER(divu32)(CPUS390XState *env, uint64_t a, uint64_t b64)
 
     /* Catch non-representable quotient.  */
     if (ret != q) {
-        s390_program_interrupt(env, PGM_FIXPT_DIVIDE, ILEN_AUTO, GETPC());
+        s390_program_interrupt(env, PGM_FIXPT_DIVIDE, GETPC());
     }
 
     return ret;
@@ -79,7 +79,7 @@ int64_t HELPER(divs64)(CPUS390XState *env, int64_t a, int64_t b)
 {
     /* Catch divide by zero, and non-representable quotient (MIN / -1).  */
     if (b == 0 || (b == -1 && a == (1ll << 63))) {
-        s390_program_interrupt(env, PGM_FIXPT_DIVIDE, ILEN_AUTO, GETPC());
+        s390_program_interrupt(env, PGM_FIXPT_DIVIDE, GETPC());
     }
     env->retxl = a % b;
     return a / b;
@@ -92,7 +92,7 @@ uint64_t HELPER(divu64)(CPUS390XState *env, uint64_t ah, uint64_t al,
     uint64_t ret;
     /* Signal divide by zero.  */
     if (b == 0) {
-        s390_program_interrupt(env, PGM_FIXPT_DIVIDE, ILEN_AUTO, GETPC());
+        s390_program_interrupt(env, PGM_FIXPT_DIVIDE, GETPC());
     }
     if (ah == 0) {
         /* 64 -> 64/64 case */
@@ -106,7 +106,7 @@ uint64_t HELPER(divu64)(CPUS390XState *env, uint64_t ah, uint64_t al,
         env->retxl = a % b;
         ret = q;
         if (ret != q) {
-            s390_program_interrupt(env, PGM_FIXPT_DIVIDE, ILEN_AUTO, GETPC());
+            s390_program_interrupt(env, PGM_FIXPT_DIVIDE, GETPC());
         }
 #else
         /* 32-bit hosts would need special wrapper functionality - just abort if
diff --git a/target/s390x/interrupt.c b/target/s390x/interrupt.c
index b798e2ecbe..2b71e03914 100644
--- a/target/s390x/interrupt.c
+++ b/target/s390x/interrupt.c
@@ -34,8 +34,7 @@ void trigger_pgm_exception(CPUS390XState *env, uint32_t code, uint32_t ilen)
     }
 }
 
-void s390_program_interrupt(CPUS390XState *env, uint32_t code, int ilen,
-                            uintptr_t ra)
+void s390_program_interrupt(CPUS390XState *env, uint32_t code, uintptr_t ra)
 {
     if (kvm_enabled()) {
         kvm_s390_program_interrupt(env_archcpu(env), code);
diff --git a/target/s390x/ioinst.c b/target/s390x/ioinst.c
index 83c164a168..c437a1d8c6 100644
--- a/target/s390x/ioinst.c
+++ b/target/s390x/ioinst.c
@@ -44,7 +44,7 @@ void ioinst_handle_xsch(S390CPU *cpu, uint64_t reg1, uintptr_t ra)
     SubchDev *sch;
 
     if (ioinst_disassemble_sch_ident(reg1, &m, &cssid, &ssid, &schid)) {
-        s390_program_interrupt(&cpu->env, PGM_OPERAND, 4, ra);
+        s390_program_interrupt(&cpu->env, PGM_OPERAND, ra);
         return;
     }
     trace_ioinst_sch_id("xsch", cssid, ssid, schid);
@@ -62,7 +62,7 @@ void ioinst_handle_csch(S390CPU *cpu, uint64_t reg1, uintptr_t ra)
     SubchDev *sch;
 
     if (ioinst_disassemble_sch_ident(reg1, &m, &cssid, &ssid, &schid)) {
-        s390_program_interrupt(&cpu->env, PGM_OPERAND, 4, ra);
+        s390_program_interrupt(&cpu->env, PGM_OPERAND, ra);
         return;
     }
     trace_ioinst_sch_id("csch", cssid, ssid, schid);
@@ -80,7 +80,7 @@ void ioinst_handle_hsch(S390CPU *cpu, uint64_t reg1, uintptr_t ra)
     SubchDev *sch;
 
     if (ioinst_disassemble_sch_ident(reg1, &m, &cssid, &ssid, &schid)) {
-        s390_program_interrupt(&cpu->env, PGM_OPERAND, 4, ra);
+        s390_program_interrupt(&cpu->env, PGM_OPERAND, ra);
         return;
     }
     trace_ioinst_sch_id("hsch", cssid, ssid, schid);
@@ -116,7 +116,7 @@ void ioinst_handle_msch(S390CPU *cpu, uint64_t reg1, uint32_t ipb, uintptr_t ra)
 
     addr = decode_basedisp_s(env, ipb, &ar);
     if (addr & 3) {
-        s390_program_interrupt(env, PGM_SPECIFICATION, 4, ra);
+        s390_program_interrupt(env, PGM_SPECIFICATION, ra);
         return;
     }
     if (s390_cpu_virt_mem_read(cpu, addr, ar, &schib, sizeof(schib))) {
@@ -125,7 +125,7 @@ void ioinst_handle_msch(S390CPU *cpu, uint64_t reg1, uint32_t ipb, uintptr_t ra)
     }
     if (ioinst_disassemble_sch_ident(reg1, &m, &cssid, &ssid, &schid) ||
         !ioinst_schib_valid(&schib)) {
-        s390_program_interrupt(env, PGM_OPERAND, 4, ra);
+        s390_program_interrupt(env, PGM_OPERAND, ra);
         return;
     }
     trace_ioinst_sch_id("msch", cssid, ssid, schid);
@@ -173,7 +173,7 @@ void ioinst_handle_ssch(S390CPU *cpu, uint64_t reg1, uint32_t ipb, uintptr_t ra)
 
     addr = decode_basedisp_s(env, ipb, &ar);
     if (addr & 3) {
-        s390_program_interrupt(env, PGM_SPECIFICATION, 4, ra);
+        s390_program_interrupt(env, PGM_SPECIFICATION, ra);
         return;
     }
     if (s390_cpu_virt_mem_read(cpu, addr, ar, &orig_orb, sizeof(orb))) {
@@ -183,7 +183,7 @@ void ioinst_handle_ssch(S390CPU *cpu, uint64_t reg1, uint32_t ipb, uintptr_t ra)
     copy_orb_from_guest(&orb, &orig_orb);
     if (ioinst_disassemble_sch_ident(reg1, &m, &cssid, &ssid, &schid) ||
         !ioinst_orb_valid(&orb)) {
-        s390_program_interrupt(env, PGM_OPERAND, 4, ra);
+        s390_program_interrupt(env, PGM_OPERAND, ra);
         return;
     }
     trace_ioinst_sch_id("ssch", cssid, ssid, schid);
@@ -205,7 +205,7 @@ void ioinst_handle_stcrw(S390CPU *cpu, uint32_t ipb, uintptr_t ra)
 
     addr = decode_basedisp_s(env, ipb, &ar);
     if (addr & 3) {
-        s390_program_interrupt(env, PGM_SPECIFICATION, 4, ra);
+        s390_program_interrupt(env, PGM_SPECIFICATION, ra);
         return;
     }
 
@@ -236,7 +236,7 @@ void ioinst_handle_stsch(S390CPU *cpu, uint64_t reg1, uint32_t ipb,
 
     addr = decode_basedisp_s(env, ipb, &ar);
     if (addr & 3) {
-        s390_program_interrupt(env, PGM_SPECIFICATION, 4, ra);
+        s390_program_interrupt(env, PGM_SPECIFICATION, ra);
         return;
     }
 
@@ -247,7 +247,7 @@ void ioinst_handle_stsch(S390CPU *cpu, uint64_t reg1, uint32_t ipb,
          * access execption if it is not) first.
          */
         if (!s390_cpu_virt_mem_check_write(cpu, addr, ar, sizeof(schib))) {
-            s390_program_interrupt(env, PGM_OPERAND, 4, ra);
+            s390_program_interrupt(env, PGM_OPERAND, ra);
         } else {
             s390_cpu_virt_mem_handle_exc(cpu, ra);
         }
@@ -299,13 +299,13 @@ int ioinst_handle_tsch(S390CPU *cpu, uint64_t reg1, uint32_t ipb, uintptr_t ra)
     uint8_t ar;
 
     if (ioinst_disassemble_sch_ident(reg1, &m, &cssid, &ssid, &schid)) {
-        s390_program_interrupt(env, PGM_OPERAND, 4, ra);
+        s390_program_interrupt(env, PGM_OPERAND, ra);
         return -EIO;
     }
     trace_ioinst_sch_id("tsch", cssid, ssid, schid);
     addr = decode_basedisp_s(env, ipb, &ar);
     if (addr & 3) {
-        s390_program_interrupt(env, PGM_SPECIFICATION, 4, ra);
+        s390_program_interrupt(env, PGM_SPECIFICATION, ra);
         return -EIO;
     }
 
@@ -613,7 +613,7 @@ void ioinst_handle_chsc(S390CPU *cpu, uint32_t ipb, uintptr_t ra)
     addr = env->regs[reg];
     /* Page boundary? */
     if (addr & 0xfff) {
-        s390_program_interrupt(env, PGM_SPECIFICATION, 4, ra);
+        s390_program_interrupt(env, PGM_SPECIFICATION, ra);
         return;
     }
     /*
@@ -629,7 +629,7 @@ void ioinst_handle_chsc(S390CPU *cpu, uint32_t ipb, uintptr_t ra)
     len = be16_to_cpu(req->len);
     /* Length field valid? */
     if ((len < 16) || (len > 4088) || (len & 7)) {
-        s390_program_interrupt(env, PGM_OPERAND, 4, ra);
+        s390_program_interrupt(env, PGM_OPERAND, ra);
         return;
     }
     memset((char *)req + len, 0, TARGET_PAGE_SIZE - len);
@@ -678,7 +678,7 @@ void ioinst_handle_schm(S390CPU *cpu, uint64_t reg1, uint64_t reg2,
     trace_ioinst("schm");
 
     if (SCHM_REG1_RES(reg1)) {
-        s390_program_interrupt(env, PGM_OPERAND, 4, ra);
+        s390_program_interrupt(env, PGM_OPERAND, ra);
         return;
     }
 
@@ -687,7 +687,7 @@ void ioinst_handle_schm(S390CPU *cpu, uint64_t reg1, uint64_t reg2,
     dct = SCHM_REG1_DCT(reg1);
 
     if (update && (reg2 & 0x000000000000001f)) {
-        s390_program_interrupt(env, PGM_OPERAND, 4, ra);
+        s390_program_interrupt(env, PGM_OPERAND, ra);
         return;
     }
 
@@ -700,7 +700,7 @@ void ioinst_handle_rsch(S390CPU *cpu, uint64_t reg1, uintptr_t ra)
     SubchDev *sch;
 
     if (ioinst_disassemble_sch_ident(reg1, &m, &cssid, &ssid, &schid)) {
-        s390_program_interrupt(&cpu->env, PGM_OPERAND, 4, ra);
+        s390_program_interrupt(&cpu->env, PGM_OPERAND, ra);
         return;
     }
     trace_ioinst_sch_id("rsch", cssid, ssid, schid);
@@ -724,7 +724,7 @@ void ioinst_handle_rchp(S390CPU *cpu, uint64_t reg1, uintptr_t ra)
     CPUS390XState *env = &cpu->env;
 
     if (RCHP_REG1_RES(reg1)) {
-        s390_program_interrupt(env, PGM_OPERAND, 4, ra);
+        s390_program_interrupt(env, PGM_OPERAND, ra);
         return;
     }
 
@@ -747,7 +747,7 @@ void ioinst_handle_rchp(S390CPU *cpu, uint64_t reg1, uintptr_t ra)
         break;
     default:
         /* Invalid channel subsystem. */
-        s390_program_interrupt(env, PGM_OPERAND, 4, ra);
+        s390_program_interrupt(env, PGM_OPERAND, ra);
         return;
     }
     setcc(cpu, cc);
@@ -758,6 +758,6 @@ void ioinst_handle_sal(S390CPU *cpu, uint64_t reg1, uintptr_t ra)
 {
     /* We do not provide address limit checking, so let's suppress it. */
     if (SAL_REG1_INVALID(reg1) || reg1 & 0x000000000000ffff) {
-        s390_program_interrupt(&cpu->env, PGM_OPERAND, 4, ra);
+        s390_program_interrupt(&cpu->env, PGM_OPERAND, ra);
     }
 }
diff --git a/target/s390x/mem_helper.c b/target/s390x/mem_helper.c
index 08c5cc6a99..77d2eb96d4 100644
--- a/target/s390x/mem_helper.c
+++ b/target/s390x/mem_helper.c
@@ -71,7 +71,7 @@ static inline void check_alignment(CPUS390XState *env, uint64_t v,
                                    int wordsize, uintptr_t ra)
 {
     if (v % wordsize) {
-        s390_program_interrupt(env, PGM_SPECIFICATION, 6, ra);
+        s390_program_interrupt(env, PGM_SPECIFICATION, ra);
     }
 }
 
@@ -730,7 +730,7 @@ void HELPER(srst)(CPUS390XState *env, uint32_t r1, uint32_t r2)
 
     /* Bits 32-55 must contain all 0.  */
     if (env->regs[0] & 0xffffff00u) {
-        s390_program_interrupt(env, PGM_SPECIFICATION, 6, ra);
+        s390_program_interrupt(env, PGM_SPECIFICATION, ra);
     }
 
     str = get_address(env, r2);
@@ -767,7 +767,7 @@ void HELPER(srstu)(CPUS390XState *env, uint32_t r1, uint32_t r2)
 
     /* Bits 32-47 of R0 must be zero.  */
     if (env->regs[0] & 0xffff0000u) {
-        s390_program_interrupt(env, PGM_SPECIFICATION, 6, ra);
+        s390_program_interrupt(env, PGM_SPECIFICATION, ra);
     }
 
     str = get_address(env, r2);
@@ -846,7 +846,7 @@ uint32_t HELPER(mvpg)(CPUS390XState *env, uint64_t r0, uint64_t r1, uint64_t r2)
     S390Access srca, desta;
 
     if ((f && s) || extract64(r0, 12, 4)) {
-        s390_program_interrupt(env, PGM_SPECIFICATION, ILEN_AUTO, GETPC());
+        s390_program_interrupt(env, PGM_SPECIFICATION, GETPC());
     }
 
     r1 = wrap_address(env, r1 & TARGET_PAGE_MASK);
@@ -879,7 +879,7 @@ uint32_t HELPER(mvst)(CPUS390XState *env, uint32_t r1, uint32_t r2)
     int i;
 
     if (env->regs[0] & 0xffffff00ull) {
-        s390_program_interrupt(env, PGM_SPECIFICATION, ILEN_AUTO, ra);
+        s390_program_interrupt(env, PGM_SPECIFICATION, ra);
     }
 
     /*
@@ -911,8 +911,7 @@ void HELPER(lam)(CPUS390XState *env, uint32_t r1, uint64_t a2, uint32_t r3)
     int i;
 
     if (a2 & 0x3) {
-        /* we either came here by lam or lamy, which have different lengths */
-        s390_program_interrupt(env, PGM_SPECIFICATION, ILEN_AUTO, ra);
+        s390_program_interrupt(env, PGM_SPECIFICATION, ra);
     }
 
     for (i = r1;; i = (i + 1) % 16) {
@@ -932,7 +931,7 @@ void HELPER(stam)(CPUS390XState *env, uint32_t r1, uint64_t a2, uint32_t r3)
     int i;
 
     if (a2 & 0x3) {
-        s390_program_interrupt(env, PGM_SPECIFICATION, 4, ra);
+        s390_program_interrupt(env, PGM_SPECIFICATION, ra);
     }
 
     for (i = r1;; i = (i + 1) % 16) {
@@ -1888,7 +1887,7 @@ static uint32_t do_csst(CPUS390XState *env, uint32_t r3, uint64_t a1,
     return cc;
 
  spec_exception:
-    s390_program_interrupt(env, PGM_SPECIFICATION, 6, ra);
+    s390_program_interrupt(env, PGM_SPECIFICATION, ra);
     g_assert_not_reached();
 }
 
@@ -1912,7 +1911,7 @@ void HELPER(lctlg)(CPUS390XState *env, uint32_t r1, uint64_t a2, uint32_t r3)
     uint32_t i;
 
     if (src & 0x7) {
-        s390_program_interrupt(env, PGM_SPECIFICATION, 6, ra);
+        s390_program_interrupt(env, PGM_SPECIFICATION, ra);
     }
 
     for (i = r1;; i = (i + 1) % 16) {
@@ -1945,7 +1944,7 @@ void HELPER(lctl)(CPUS390XState *env, uint32_t r1, uint64_t a2, uint32_t r3)
     uint32_t i;
 
     if (src & 0x3) {
-        s390_program_interrupt(env, PGM_SPECIFICATION, 4, ra);
+        s390_program_interrupt(env, PGM_SPECIFICATION, ra);
     }
 
     for (i = r1;; i = (i + 1) % 16) {
@@ -1976,7 +1975,7 @@ void HELPER(stctg)(CPUS390XState *env, uint32_t r1, uint64_t a2, uint32_t r3)
     uint32_t i;
 
     if (dest & 0x7) {
-        s390_program_interrupt(env, PGM_SPECIFICATION, 6, ra);
+        s390_program_interrupt(env, PGM_SPECIFICATION, ra);
     }
 
     for (i = r1;; i = (i + 1) % 16) {
@@ -1996,7 +1995,7 @@ void HELPER(stctl)(CPUS390XState *env, uint32_t r1, uint64_t a2, uint32_t r3)
     uint32_t i;
 
     if (dest & 0x3) {
-        s390_program_interrupt(env, PGM_SPECIFICATION, 4, ra);
+        s390_program_interrupt(env, PGM_SPECIFICATION, ra);
     }
 
     for (i = r1;; i = (i + 1) % 16) {
@@ -2168,7 +2167,7 @@ uint32_t HELPER(mvcs)(CPUS390XState *env, uint64_t l, uint64_t a1, uint64_t a2)
 
     if (!(env->psw.mask & PSW_MASK_DAT) || !(env->cregs[0] & CR0_SECONDARY) ||
         psw_as == AS_HOME || psw_as == AS_ACCREG) {
-        s390_program_interrupt(env, PGM_SPECIAL_OP, ILEN_AUTO, ra);
+        s390_program_interrupt(env, PGM_SPECIAL_OP, ra);
     }
 
     l = wrap_length32(env, l);
@@ -2199,7 +2198,7 @@ uint32_t HELPER(mvcp)(CPUS390XState *env, uint64_t l, uint64_t a1, uint64_t a2)
 
     if (!(env->psw.mask & PSW_MASK_DAT) || !(env->cregs[0] & CR0_SECONDARY) ||
         psw_as == AS_HOME || psw_as == AS_ACCREG) {
-        s390_program_interrupt(env, PGM_SPECIAL_OP, ILEN_AUTO, ra);
+        s390_program_interrupt(env, PGM_SPECIAL_OP, ra);
     }
 
     l = wrap_length32(env, l);
@@ -2226,7 +2225,7 @@ void HELPER(idte)(CPUS390XState *env, uint64_t r1, uint64_t r2, uint32_t m4)
     uint16_t entries, i, index = 0;
 
     if (r2 & 0xff000) {
-        s390_program_interrupt(env, PGM_SPECIFICATION, 4, ra);
+        s390_program_interrupt(env, PGM_SPECIFICATION, ra);
     }
 
     if (!(r2 & 0x800)) {
@@ -2370,7 +2369,7 @@ uint64_t HELPER(lra)(CPUS390XState *env, uint64_t addr)
 
     /* XXX incomplete - has more corner cases */
     if (!(env->psw.mask & PSW_MASK_64) && (addr >> 32)) {
-        s390_program_interrupt(env, PGM_SPECIAL_OP, 2, GETPC());
+        s390_program_interrupt(env, PGM_SPECIAL_OP, GETPC());
     }
 
     old_exc = cs->exception_index;
@@ -2539,7 +2538,7 @@ uint32_t HELPER(mvcos)(CPUS390XState *env, uint64_t dest, uint64_t src,
                __func__, dest, src, len);
 
     if (!(env->psw.mask & PSW_MASK_DAT)) {
-        s390_program_interrupt(env, PGM_SPECIAL_OP, 6, ra);
+        s390_program_interrupt(env, PGM_SPECIAL_OP, ra);
     }
 
     /* OAC (operand access control) for the first operand -> dest */
@@ -2570,14 +2569,14 @@ uint32_t HELPER(mvcos)(CPUS390XState *env, uint64_t dest, uint64_t src,
     }
 
     if (dest_a && dest_as == AS_HOME && (env->psw.mask & PSW_MASK_PSTATE)) {
-        s390_program_interrupt(env, PGM_SPECIAL_OP, 6, ra);
+        s390_program_interrupt(env, PGM_SPECIAL_OP, ra);
     }
     if (!(env->cregs[0] & CR0_SECONDARY) &&
         (dest_as == AS_SECONDARY || src_as == AS_SECONDARY)) {
-        s390_program_interrupt(env, PGM_SPECIAL_OP, 6, ra);
+        s390_program_interrupt(env, PGM_SPECIAL_OP, ra);
     }
     if (!psw_key_valid(env, dest_key) || !psw_key_valid(env, src_key)) {
-        s390_program_interrupt(env, PGM_PRIVILEGED, 6, ra);
+        s390_program_interrupt(env, PGM_PRIVILEGED, ra);
     }
 
     len = wrap_length32(env, len);
@@ -2591,7 +2590,7 @@ uint32_t HELPER(mvcos)(CPUS390XState *env, uint64_t dest, uint64_t src,
         (env->psw.mask & PSW_MASK_PSTATE)) {
         qemu_log_mask(LOG_UNIMP, "%s: AR-mode and PSTATE support missing\n",
                       __func__);
-        s390_program_interrupt(env, PGM_ADDRESSING, 6, ra);
+        s390_program_interrupt(env, PGM_ADDRESSING, ra);
     }
 
     /* FIXME: Access using correct keys and AR-mode */
diff --git a/target/s390x/misc_helper.c b/target/s390x/misc_helper.c
index 7530dcb8f3..9fbb37cfb9 100644
--- a/target/s390x/misc_helper.c
+++ b/target/s390x/misc_helper.c
@@ -106,7 +106,7 @@ uint32_t HELPER(servc)(CPUS390XState *env, uint64_t r1, uint64_t r2)
     int r = sclp_service_call(env, r1, r2);
     qemu_mutex_unlock_iothread();
     if (r < 0) {
-        s390_program_interrupt(env, -r, 4, GETPC());
+        s390_program_interrupt(env, -r, GETPC());
     }
     return r;
 }
@@ -143,7 +143,7 @@ void HELPER(diag)(CPUS390XState *env, uint32_t r1, uint32_t r3, uint32_t num)
     }
 
     if (r) {
-        s390_program_interrupt(env, PGM_SPECIFICATION, ILEN_AUTO, GETPC());
+        s390_program_interrupt(env, PGM_SPECIFICATION, GETPC());
     }
 }
 
@@ -222,7 +222,7 @@ void HELPER(sckpf)(CPUS390XState *env, uint64_t r0)
     uint32_t val = r0;
 
     if (val & 0xffff0000) {
-        s390_program_interrupt(env, PGM_SPECIFICATION, 2, GETPC());
+        s390_program_interrupt(env, PGM_SPECIFICATION, GETPC());
     }
     env->todpr = val;
 }
@@ -266,7 +266,7 @@ uint32_t HELPER(stsi)(CPUS390XState *env, uint64_t a0, uint64_t r0, uint64_t r1)
     }
 
     if ((r0 & STSI_R0_RESERVED_MASK) || (r1 & STSI_R1_RESERVED_MASK)) {
-        s390_program_interrupt(env, PGM_SPECIFICATION, 4, ra);
+        s390_program_interrupt(env, PGM_SPECIFICATION, ra);
     }
 
     if ((r0 & STSI_R0_FC_MASK) == STSI_R0_FC_CURRENT) {
@@ -276,7 +276,7 @@ uint32_t HELPER(stsi)(CPUS390XState *env, uint64_t a0, uint64_t r0, uint64_t r1)
     }
 
     if (a0 & ~TARGET_PAGE_MASK) {
-        s390_program_interrupt(env, PGM_SPECIFICATION, 4, ra);
+        s390_program_interrupt(env, PGM_SPECIFICATION, ra);
     }
 
     /* count the cpus and split them into configured and reserved ones */
@@ -509,7 +509,7 @@ uint32_t HELPER(tpi)(CPUS390XState *env, uint64_t addr)
     LowCore *lowcore;
 
     if (addr & 0x3) {
-        s390_program_interrupt(env, PGM_SPECIFICATION, 4, ra);
+        s390_program_interrupt(env, PGM_SPECIFICATION, ra);
     }
 
     qemu_mutex_lock_iothread();
@@ -573,17 +573,8 @@ void HELPER(chsc)(CPUS390XState *env, uint64_t inst)
 #ifndef CONFIG_USER_ONLY
 void HELPER(per_check_exception)(CPUS390XState *env)
 {
-    uint32_t ilen;
-
     if (env->per_perc_atmid) {
-        /*
-         * FIXME: ILEN_AUTO is most probably the right thing to use. ilen
-         * always has to match the instruction referenced in the PSW. E.g.
-         * if a PER interrupt is triggered via EXECUTE, we have to use ilen
-         * of EXECUTE, while per_address contains the target of EXECUTE.
-         */
-        ilen = get_ilen(cpu_ldub_code(env, env->per_address));
-        s390_program_interrupt(env, PGM_PER, ilen, GETPC());
+        s390_program_interrupt(env, PGM_PER, GETPC());
     }
 }
 
@@ -673,7 +664,7 @@ uint32_t HELPER(stfle)(CPUS390XState *env, uint64_t addr)
     int i;
 
     if (addr & 0x7) {
-        s390_program_interrupt(env, PGM_SPECIFICATION, 4, ra);
+        s390_program_interrupt(env, PGM_SPECIFICATION, ra);
     }
 
     prepare_stfl();
@@ -746,7 +737,7 @@ void HELPER(sic)(CPUS390XState *env, uint64_t r1, uint64_t r3)
     qemu_mutex_unlock_iothread();
     /* css_do_sic() may actually return a PGM_xxx value to inject */
     if (r) {
-        s390_program_interrupt(env, -r, 4, GETPC());
+        s390_program_interrupt(env, -r, GETPC());
     }
 }
 
-- 
2.17.1



^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH v3 05/18] target/s390x: Use tcg_s390_program_interrupt in TCG helpers
  2019-09-26 16:25 [PATCH v3 00/18] target/s390: Use tcg unwinding for ilen Richard Henderson
                   ` (3 preceding siblings ...)
  2019-09-26 16:26 ` [PATCH v3 04/18] target/s390x: Remove ilen parameter from s390_program_interrupt Richard Henderson
@ 2019-09-26 16:26 ` Richard Henderson
  2019-09-27 10:40   ` David Hildenbrand
  2019-09-26 16:26 ` [PATCH v3 06/18] target/s390x: Push trigger_pgm_exception lower in s390_cpu_tlb_fill Richard Henderson
                   ` (13 subsequent siblings)
  18 siblings, 1 reply; 49+ messages in thread
From: Richard Henderson @ 2019-09-26 16:26 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-s390x, david

Replace all uses of s390_program_interrupt within files
that are marked CONFIG_TCG.  These are necessarily tcg-only.

This lets each of these users benefit from the QEMU_NORETURN
attribute on tcg_s390_program_interrupt.

Acked-by: David Hildenbrand <david@redhat.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/s390x/cc_helper.c     |  4 ++--
 target/s390x/crypto_helper.c |  7 +++----
 target/s390x/excp_helper.c   |  2 +-
 target/s390x/fpu_helper.c    |  6 +++---
 target/s390x/int_helper.c    | 15 +++++++-------
 target/s390x/mem_helper.c    | 40 ++++++++++++++++++------------------
 target/s390x/misc_helper.c   | 18 ++++++++--------
 7 files changed, 46 insertions(+), 46 deletions(-)

diff --git a/target/s390x/cc_helper.c b/target/s390x/cc_helper.c
index 3cb00bcb09..44731e4a85 100644
--- a/target/s390x/cc_helper.c
+++ b/target/s390x/cc_helper.c
@@ -21,6 +21,7 @@
 #include "qemu/osdep.h"
 #include "cpu.h"
 #include "internal.h"
+#include "tcg_s390x.h"
 #include "exec/exec-all.h"
 #include "exec/helper-proto.h"
 #include "qemu/host-utils.h"
@@ -588,8 +589,7 @@ void HELPER(sacf)(CPUS390XState *env, uint64_t a1)
         break;
     default:
         HELPER_LOG("unknown sacf mode: %" PRIx64 "\n", a1);
-        s390_program_interrupt(env, PGM_SPECIFICATION, GETPC());
-        break;
+        tcg_s390_program_interrupt(env, PGM_SPECIFICATION, GETPC());
     }
 }
 #endif
diff --git a/target/s390x/crypto_helper.c b/target/s390x/crypto_helper.c
index 1f83987e9d..ff3fbc3950 100644
--- a/target/s390x/crypto_helper.c
+++ b/target/s390x/crypto_helper.c
@@ -13,6 +13,7 @@
 #include "qemu/osdep.h"
 #include "qemu/main-loop.h"
 #include "internal.h"
+#include "tcg_s390x.h"
 #include "exec/helper-proto.h"
 #include "exec/exec-all.h"
 #include "exec/cpu_ldst.h"
@@ -34,16 +35,14 @@ uint32_t HELPER(msa)(CPUS390XState *env, uint32_t r1, uint32_t r2, uint32_t r3,
     case S390_FEAT_TYPE_PCKMO:
     case S390_FEAT_TYPE_PCC:
         if (mod) {
-            s390_program_interrupt(env, PGM_SPECIFICATION, ra);
-            return 0;
+            tcg_s390_program_interrupt(env, PGM_SPECIFICATION, ra);
         }
         break;
     }
 
     s390_get_feat_block(type, subfunc);
     if (!test_be_bit(fc, subfunc)) {
-        s390_program_interrupt(env, PGM_SPECIFICATION, ra);
-        return 0;
+        tcg_s390_program_interrupt(env, PGM_SPECIFICATION, ra);
     }
 
     switch (fc) {
diff --git a/target/s390x/excp_helper.c b/target/s390x/excp_helper.c
index 089623a248..dbff772d34 100644
--- a/target/s390x/excp_helper.c
+++ b/target/s390x/excp_helper.c
@@ -614,7 +614,7 @@ void s390x_cpu_do_unaligned_access(CPUState *cs, vaddr addr,
     S390CPU *cpu = S390_CPU(cs);
     CPUS390XState *env = &cpu->env;
 
-    s390_program_interrupt(env, PGM_SPECIFICATION, retaddr);
+    tcg_s390_program_interrupt(env, PGM_SPECIFICATION, retaddr);
 }
 
 #endif /* CONFIG_USER_ONLY */
diff --git a/target/s390x/fpu_helper.c b/target/s390x/fpu_helper.c
index 7228eb96e2..8bb9f54fd0 100644
--- a/target/s390x/fpu_helper.c
+++ b/target/s390x/fpu_helper.c
@@ -825,7 +825,7 @@ void HELPER(sfpc)(CPUS390XState *env, uint64_t fpc)
 {
     if (fpc_to_rnd[fpc & 0x7] == -1 || fpc & 0x03030088u ||
         (!s390_has_feat(S390_FEAT_FLOATING_POINT_EXT) && fpc & 0x4)) {
-        s390_program_interrupt(env, PGM_SPECIFICATION, GETPC());
+        tcg_s390_program_interrupt(env, PGM_SPECIFICATION, GETPC());
     }
 
     /* Install everything in the main FPC.  */
@@ -843,7 +843,7 @@ void HELPER(sfas)(CPUS390XState *env, uint64_t fpc)
 
     if (fpc_to_rnd[fpc & 0x7] == -1 || fpc & 0x03030088u ||
         (!s390_has_feat(S390_FEAT_FLOATING_POINT_EXT) && fpc & 0x4)) {
-        s390_program_interrupt(env, PGM_SPECIFICATION, GETPC());
+        tcg_s390_program_interrupt(env, PGM_SPECIFICATION, GETPC());
     }
 
     /*
@@ -880,7 +880,7 @@ void HELPER(sfas)(CPUS390XState *env, uint64_t fpc)
 void HELPER(srnm)(CPUS390XState *env, uint64_t rnd)
 {
     if (rnd > 0x7 || fpc_to_rnd[rnd & 0x7] == -1) {
-        s390_program_interrupt(env, PGM_SPECIFICATION, GETPC());
+        tcg_s390_program_interrupt(env, PGM_SPECIFICATION, GETPC());
     }
 
     env->fpc = deposit32(env->fpc, 0, 3, rnd);
diff --git a/target/s390x/int_helper.c b/target/s390x/int_helper.c
index 1d29a1fc1f..658507dd6d 100644
--- a/target/s390x/int_helper.c
+++ b/target/s390x/int_helper.c
@@ -21,6 +21,7 @@
 #include "qemu/osdep.h"
 #include "cpu.h"
 #include "internal.h"
+#include "tcg_s390x.h"
 #include "exec/exec-all.h"
 #include "qemu/host-utils.h"
 #include "exec/helper-proto.h"
@@ -39,7 +40,7 @@ int64_t HELPER(divs32)(CPUS390XState *env, int64_t a, int64_t b64)
     int64_t q;
 
     if (b == 0) {
-        s390_program_interrupt(env, PGM_FIXPT_DIVIDE, GETPC());
+        tcg_s390_program_interrupt(env, PGM_FIXPT_DIVIDE, GETPC());
     }
 
     ret = q = a / b;
@@ -47,7 +48,7 @@ int64_t HELPER(divs32)(CPUS390XState *env, int64_t a, int64_t b64)
 
     /* Catch non-representable quotient.  */
     if (ret != q) {
-        s390_program_interrupt(env, PGM_FIXPT_DIVIDE, GETPC());
+        tcg_s390_program_interrupt(env, PGM_FIXPT_DIVIDE, GETPC());
     }
 
     return ret;
@@ -60,7 +61,7 @@ uint64_t HELPER(divu32)(CPUS390XState *env, uint64_t a, uint64_t b64)
     uint64_t q;
 
     if (b == 0) {
-        s390_program_interrupt(env, PGM_FIXPT_DIVIDE, GETPC());
+        tcg_s390_program_interrupt(env, PGM_FIXPT_DIVIDE, GETPC());
     }
 
     ret = q = a / b;
@@ -68,7 +69,7 @@ uint64_t HELPER(divu32)(CPUS390XState *env, uint64_t a, uint64_t b64)
 
     /* Catch non-representable quotient.  */
     if (ret != q) {
-        s390_program_interrupt(env, PGM_FIXPT_DIVIDE, GETPC());
+        tcg_s390_program_interrupt(env, PGM_FIXPT_DIVIDE, GETPC());
     }
 
     return ret;
@@ -79,7 +80,7 @@ int64_t HELPER(divs64)(CPUS390XState *env, int64_t a, int64_t b)
 {
     /* Catch divide by zero, and non-representable quotient (MIN / -1).  */
     if (b == 0 || (b == -1 && a == (1ll << 63))) {
-        s390_program_interrupt(env, PGM_FIXPT_DIVIDE, GETPC());
+        tcg_s390_program_interrupt(env, PGM_FIXPT_DIVIDE, GETPC());
     }
     env->retxl = a % b;
     return a / b;
@@ -92,7 +93,7 @@ uint64_t HELPER(divu64)(CPUS390XState *env, uint64_t ah, uint64_t al,
     uint64_t ret;
     /* Signal divide by zero.  */
     if (b == 0) {
-        s390_program_interrupt(env, PGM_FIXPT_DIVIDE, GETPC());
+        tcg_s390_program_interrupt(env, PGM_FIXPT_DIVIDE, GETPC());
     }
     if (ah == 0) {
         /* 64 -> 64/64 case */
@@ -106,7 +107,7 @@ uint64_t HELPER(divu64)(CPUS390XState *env, uint64_t ah, uint64_t al,
         env->retxl = a % b;
         ret = q;
         if (ret != q) {
-            s390_program_interrupt(env, PGM_FIXPT_DIVIDE, GETPC());
+            tcg_s390_program_interrupt(env, PGM_FIXPT_DIVIDE, GETPC());
         }
 #else
         /* 32-bit hosts would need special wrapper functionality - just abort if
diff --git a/target/s390x/mem_helper.c b/target/s390x/mem_helper.c
index 77d2eb96d4..7d2a652823 100644
--- a/target/s390x/mem_helper.c
+++ b/target/s390x/mem_helper.c
@@ -21,6 +21,7 @@
 #include "qemu/osdep.h"
 #include "cpu.h"
 #include "internal.h"
+#include "tcg_s390x.h"
 #include "exec/helper-proto.h"
 #include "exec/exec-all.h"
 #include "exec/cpu_ldst.h"
@@ -71,7 +72,7 @@ static inline void check_alignment(CPUS390XState *env, uint64_t v,
                                    int wordsize, uintptr_t ra)
 {
     if (v % wordsize) {
-        s390_program_interrupt(env, PGM_SPECIFICATION, ra);
+        tcg_s390_program_interrupt(env, PGM_SPECIFICATION, ra);
     }
 }
 
@@ -730,7 +731,7 @@ void HELPER(srst)(CPUS390XState *env, uint32_t r1, uint32_t r2)
 
     /* Bits 32-55 must contain all 0.  */
     if (env->regs[0] & 0xffffff00u) {
-        s390_program_interrupt(env, PGM_SPECIFICATION, ra);
+        tcg_s390_program_interrupt(env, PGM_SPECIFICATION, ra);
     }
 
     str = get_address(env, r2);
@@ -767,7 +768,7 @@ void HELPER(srstu)(CPUS390XState *env, uint32_t r1, uint32_t r2)
 
     /* Bits 32-47 of R0 must be zero.  */
     if (env->regs[0] & 0xffff0000u) {
-        s390_program_interrupt(env, PGM_SPECIFICATION, ra);
+        tcg_s390_program_interrupt(env, PGM_SPECIFICATION, ra);
     }
 
     str = get_address(env, r2);
@@ -846,7 +847,7 @@ uint32_t HELPER(mvpg)(CPUS390XState *env, uint64_t r0, uint64_t r1, uint64_t r2)
     S390Access srca, desta;
 
     if ((f && s) || extract64(r0, 12, 4)) {
-        s390_program_interrupt(env, PGM_SPECIFICATION, GETPC());
+        tcg_s390_program_interrupt(env, PGM_SPECIFICATION, GETPC());
     }
 
     r1 = wrap_address(env, r1 & TARGET_PAGE_MASK);
@@ -879,7 +880,7 @@ uint32_t HELPER(mvst)(CPUS390XState *env, uint32_t r1, uint32_t r2)
     int i;
 
     if (env->regs[0] & 0xffffff00ull) {
-        s390_program_interrupt(env, PGM_SPECIFICATION, ra);
+        tcg_s390_program_interrupt(env, PGM_SPECIFICATION, ra);
     }
 
     /*
@@ -911,7 +912,7 @@ void HELPER(lam)(CPUS390XState *env, uint32_t r1, uint64_t a2, uint32_t r3)
     int i;
 
     if (a2 & 0x3) {
-        s390_program_interrupt(env, PGM_SPECIFICATION, ra);
+        tcg_s390_program_interrupt(env, PGM_SPECIFICATION, ra);
     }
 
     for (i = r1;; i = (i + 1) % 16) {
@@ -931,7 +932,7 @@ void HELPER(stam)(CPUS390XState *env, uint32_t r1, uint64_t a2, uint32_t r3)
     int i;
 
     if (a2 & 0x3) {
-        s390_program_interrupt(env, PGM_SPECIFICATION, ra);
+        tcg_s390_program_interrupt(env, PGM_SPECIFICATION, ra);
     }
 
     for (i = r1;; i = (i + 1) % 16) {
@@ -1887,8 +1888,7 @@ static uint32_t do_csst(CPUS390XState *env, uint32_t r3, uint64_t a1,
     return cc;
 
  spec_exception:
-    s390_program_interrupt(env, PGM_SPECIFICATION, ra);
-    g_assert_not_reached();
+    tcg_s390_program_interrupt(env, PGM_SPECIFICATION, ra);
 }
 
 uint32_t HELPER(csst)(CPUS390XState *env, uint32_t r3, uint64_t a1, uint64_t a2)
@@ -1911,7 +1911,7 @@ void HELPER(lctlg)(CPUS390XState *env, uint32_t r1, uint64_t a2, uint32_t r3)
     uint32_t i;
 
     if (src & 0x7) {
-        s390_program_interrupt(env, PGM_SPECIFICATION, ra);
+        tcg_s390_program_interrupt(env, PGM_SPECIFICATION, ra);
     }
 
     for (i = r1;; i = (i + 1) % 16) {
@@ -1944,7 +1944,7 @@ void HELPER(lctl)(CPUS390XState *env, uint32_t r1, uint64_t a2, uint32_t r3)
     uint32_t i;
 
     if (src & 0x3) {
-        s390_program_interrupt(env, PGM_SPECIFICATION, ra);
+        tcg_s390_program_interrupt(env, PGM_SPECIFICATION, ra);
     }
 
     for (i = r1;; i = (i + 1) % 16) {
@@ -1975,7 +1975,7 @@ void HELPER(stctg)(CPUS390XState *env, uint32_t r1, uint64_t a2, uint32_t r3)
     uint32_t i;
 
     if (dest & 0x7) {
-        s390_program_interrupt(env, PGM_SPECIFICATION, ra);
+        tcg_s390_program_interrupt(env, PGM_SPECIFICATION, ra);
     }
 
     for (i = r1;; i = (i + 1) % 16) {
@@ -1995,7 +1995,7 @@ void HELPER(stctl)(CPUS390XState *env, uint32_t r1, uint64_t a2, uint32_t r3)
     uint32_t i;
 
     if (dest & 0x3) {
-        s390_program_interrupt(env, PGM_SPECIFICATION, ra);
+        tcg_s390_program_interrupt(env, PGM_SPECIFICATION, ra);
     }
 
     for (i = r1;; i = (i + 1) % 16) {
@@ -2225,7 +2225,7 @@ void HELPER(idte)(CPUS390XState *env, uint64_t r1, uint64_t r2, uint32_t m4)
     uint16_t entries, i, index = 0;
 
     if (r2 & 0xff000) {
-        s390_program_interrupt(env, PGM_SPECIFICATION, ra);
+        tcg_s390_program_interrupt(env, PGM_SPECIFICATION, ra);
     }
 
     if (!(r2 & 0x800)) {
@@ -2369,7 +2369,7 @@ uint64_t HELPER(lra)(CPUS390XState *env, uint64_t addr)
 
     /* XXX incomplete - has more corner cases */
     if (!(env->psw.mask & PSW_MASK_64) && (addr >> 32)) {
-        s390_program_interrupt(env, PGM_SPECIAL_OP, GETPC());
+        tcg_s390_program_interrupt(env, PGM_SPECIAL_OP, GETPC());
     }
 
     old_exc = cs->exception_index;
@@ -2538,7 +2538,7 @@ uint32_t HELPER(mvcos)(CPUS390XState *env, uint64_t dest, uint64_t src,
                __func__, dest, src, len);
 
     if (!(env->psw.mask & PSW_MASK_DAT)) {
-        s390_program_interrupt(env, PGM_SPECIAL_OP, ra);
+        tcg_s390_program_interrupt(env, PGM_SPECIAL_OP, ra);
     }
 
     /* OAC (operand access control) for the first operand -> dest */
@@ -2569,14 +2569,14 @@ uint32_t HELPER(mvcos)(CPUS390XState *env, uint64_t dest, uint64_t src,
     }
 
     if (dest_a && dest_as == AS_HOME && (env->psw.mask & PSW_MASK_PSTATE)) {
-        s390_program_interrupt(env, PGM_SPECIAL_OP, ra);
+        tcg_s390_program_interrupt(env, PGM_SPECIAL_OP, ra);
     }
     if (!(env->cregs[0] & CR0_SECONDARY) &&
         (dest_as == AS_SECONDARY || src_as == AS_SECONDARY)) {
-        s390_program_interrupt(env, PGM_SPECIAL_OP, ra);
+        tcg_s390_program_interrupt(env, PGM_SPECIAL_OP, ra);
     }
     if (!psw_key_valid(env, dest_key) || !psw_key_valid(env, src_key)) {
-        s390_program_interrupt(env, PGM_PRIVILEGED, ra);
+        tcg_s390_program_interrupt(env, PGM_PRIVILEGED, ra);
     }
 
     len = wrap_length32(env, len);
@@ -2590,7 +2590,7 @@ uint32_t HELPER(mvcos)(CPUS390XState *env, uint64_t dest, uint64_t src,
         (env->psw.mask & PSW_MASK_PSTATE)) {
         qemu_log_mask(LOG_UNIMP, "%s: AR-mode and PSTATE support missing\n",
                       __func__);
-        s390_program_interrupt(env, PGM_ADDRESSING, ra);
+        tcg_s390_program_interrupt(env, PGM_ADDRESSING, ra);
     }
 
     /* FIXME: Access using correct keys and AR-mode */
diff --git a/target/s390x/misc_helper.c b/target/s390x/misc_helper.c
index 9fbb37cfb9..bfb457fb63 100644
--- a/target/s390x/misc_helper.c
+++ b/target/s390x/misc_helper.c
@@ -106,7 +106,7 @@ uint32_t HELPER(servc)(CPUS390XState *env, uint64_t r1, uint64_t r2)
     int r = sclp_service_call(env, r1, r2);
     qemu_mutex_unlock_iothread();
     if (r < 0) {
-        s390_program_interrupt(env, -r, GETPC());
+        tcg_s390_program_interrupt(env, -r, GETPC());
     }
     return r;
 }
@@ -143,7 +143,7 @@ void HELPER(diag)(CPUS390XState *env, uint32_t r1, uint32_t r3, uint32_t num)
     }
 
     if (r) {
-        s390_program_interrupt(env, PGM_SPECIFICATION, GETPC());
+        tcg_s390_program_interrupt(env, PGM_SPECIFICATION, GETPC());
     }
 }
 
@@ -222,7 +222,7 @@ void HELPER(sckpf)(CPUS390XState *env, uint64_t r0)
     uint32_t val = r0;
 
     if (val & 0xffff0000) {
-        s390_program_interrupt(env, PGM_SPECIFICATION, GETPC());
+        tcg_s390_program_interrupt(env, PGM_SPECIFICATION, GETPC());
     }
     env->todpr = val;
 }
@@ -266,7 +266,7 @@ uint32_t HELPER(stsi)(CPUS390XState *env, uint64_t a0, uint64_t r0, uint64_t r1)
     }
 
     if ((r0 & STSI_R0_RESERVED_MASK) || (r1 & STSI_R1_RESERVED_MASK)) {
-        s390_program_interrupt(env, PGM_SPECIFICATION, ra);
+        tcg_s390_program_interrupt(env, PGM_SPECIFICATION, ra);
     }
 
     if ((r0 & STSI_R0_FC_MASK) == STSI_R0_FC_CURRENT) {
@@ -276,7 +276,7 @@ uint32_t HELPER(stsi)(CPUS390XState *env, uint64_t a0, uint64_t r0, uint64_t r1)
     }
 
     if (a0 & ~TARGET_PAGE_MASK) {
-        s390_program_interrupt(env, PGM_SPECIFICATION, ra);
+        tcg_s390_program_interrupt(env, PGM_SPECIFICATION, ra);
     }
 
     /* count the cpus and split them into configured and reserved ones */
@@ -509,7 +509,7 @@ uint32_t HELPER(tpi)(CPUS390XState *env, uint64_t addr)
     LowCore *lowcore;
 
     if (addr & 0x3) {
-        s390_program_interrupt(env, PGM_SPECIFICATION, ra);
+        tcg_s390_program_interrupt(env, PGM_SPECIFICATION, ra);
     }
 
     qemu_mutex_lock_iothread();
@@ -574,7 +574,7 @@ void HELPER(chsc)(CPUS390XState *env, uint64_t inst)
 void HELPER(per_check_exception)(CPUS390XState *env)
 {
     if (env->per_perc_atmid) {
-        s390_program_interrupt(env, PGM_PER, GETPC());
+        tcg_s390_program_interrupt(env, PGM_PER, GETPC());
     }
 }
 
@@ -664,7 +664,7 @@ uint32_t HELPER(stfle)(CPUS390XState *env, uint64_t addr)
     int i;
 
     if (addr & 0x7) {
-        s390_program_interrupt(env, PGM_SPECIFICATION, ra);
+        tcg_s390_program_interrupt(env, PGM_SPECIFICATION, ra);
     }
 
     prepare_stfl();
@@ -737,7 +737,7 @@ void HELPER(sic)(CPUS390XState *env, uint64_t r1, uint64_t r3)
     qemu_mutex_unlock_iothread();
     /* css_do_sic() may actually return a PGM_xxx value to inject */
     if (r) {
-        s390_program_interrupt(env, -r, GETPC());
+        tcg_s390_program_interrupt(env, -r, GETPC());
     }
 }
 
-- 
2.17.1



^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH v3 06/18] target/s390x: Push trigger_pgm_exception lower in s390_cpu_tlb_fill
  2019-09-26 16:25 [PATCH v3 00/18] target/s390: Use tcg unwinding for ilen Richard Henderson
                   ` (4 preceding siblings ...)
  2019-09-26 16:26 ` [PATCH v3 05/18] target/s390x: Use tcg_s390_program_interrupt in TCG helpers Richard Henderson
@ 2019-09-26 16:26 ` Richard Henderson
  2019-09-27 10:41   ` David Hildenbrand
  2019-09-26 16:26 ` [PATCH v3 07/18] target/s390x: Handle tec " Richard Henderson
                   ` (12 subsequent siblings)
  18 siblings, 1 reply; 49+ messages in thread
From: Richard Henderson @ 2019-09-26 16:26 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-s390x, david

Delay triggering an exception until the end, after we have
determined ultimate success or failure, and also taken into
account whether this is a non-faulting probe.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/s390x/excp_helper.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/target/s390x/excp_helper.c b/target/s390x/excp_helper.c
index dbff772d34..552098be5f 100644
--- a/target/s390x/excp_helper.c
+++ b/target/s390x/excp_helper.c
@@ -127,7 +127,7 @@ bool s390_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
     CPUS390XState *env = &cpu->env;
     target_ulong vaddr, raddr;
     uint64_t asc;
-    int prot, fail;
+    int prot, fail, excp;
 
     qemu_log_mask(CPU_LOG_MMU, "%s: addr 0x%" VADDR_PRIx " rw %d mmu_idx %d\n",
                   __func__, address, access_type, mmu_idx);
@@ -141,12 +141,14 @@ bool s390_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
             vaddr &= 0x7fffffff;
         }
         fail = mmu_translate(env, vaddr, access_type, asc, &raddr, &prot, true);
+        excp = 0; /* exception already raised */
     } else if (mmu_idx == MMU_REAL_IDX) {
         /* 31-Bit mode */
         if (!(env->psw.mask & PSW_MASK_64)) {
             vaddr &= 0x7fffffff;
         }
         fail = mmu_translate_real(env, vaddr, access_type, &raddr, &prot);
+        excp = 0; /* exception already raised */
     } else {
         g_assert_not_reached();
     }
@@ -159,7 +161,7 @@ bool s390_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
         qemu_log_mask(CPU_LOG_MMU,
                       "%s: raddr %" PRIx64 " > ram_size %" PRIx64 "\n",
                       __func__, (uint64_t)raddr, (uint64_t)ram_size);
-        trigger_pgm_exception(env, PGM_ADDRESSING, ILEN_AUTO);
+        excp = PGM_ADDRESSING;
         fail = 1;
     }
 
@@ -175,6 +177,9 @@ bool s390_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
         return false;
     }
 
+    if (excp) {
+        trigger_pgm_exception(env, excp, ILEN_AUTO);
+    }
     cpu_restore_state(cs, retaddr, true);
 
     /*
-- 
2.17.1



^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH v3 07/18] target/s390x: Handle tec in s390_cpu_tlb_fill
  2019-09-26 16:25 [PATCH v3 00/18] target/s390: Use tcg unwinding for ilen Richard Henderson
                   ` (5 preceding siblings ...)
  2019-09-26 16:26 ` [PATCH v3 06/18] target/s390x: Push trigger_pgm_exception lower in s390_cpu_tlb_fill Richard Henderson
@ 2019-09-26 16:26 ` Richard Henderson
  2019-09-27 10:42   ` David Hildenbrand
  2019-09-26 16:26 ` [PATCH v3 08/18] target/s390: Return exception from mmu_translate_real Richard Henderson
                   ` (11 subsequent siblings)
  18 siblings, 1 reply; 49+ messages in thread
From: Richard Henderson @ 2019-09-26 16:26 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-s390x, david

As a step toward moving all excption handling out of mmu_translate,
copy handling of the LowCore tec value from trigger_access_exception
into s390_cpu_tlb_fill.  So far this new plumbing isn't used.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/s390x/excp_helper.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/target/s390x/excp_helper.c b/target/s390x/excp_helper.c
index 552098be5f..ab2ed47fef 100644
--- a/target/s390x/excp_helper.c
+++ b/target/s390x/excp_helper.c
@@ -126,7 +126,7 @@ bool s390_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
     S390CPU *cpu = S390_CPU(cs);
     CPUS390XState *env = &cpu->env;
     target_ulong vaddr, raddr;
-    uint64_t asc;
+    uint64_t asc, tec;
     int prot, fail, excp;
 
     qemu_log_mask(CPU_LOG_MMU, "%s: addr 0x%" VADDR_PRIx " rw %d mmu_idx %d\n",
@@ -162,6 +162,7 @@ bool s390_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
                       "%s: raddr %" PRIx64 " > ram_size %" PRIx64 "\n",
                       __func__, (uint64_t)raddr, (uint64_t)ram_size);
         excp = PGM_ADDRESSING;
+        tec = 0; /* unused */
         fail = 1;
     }
 
@@ -178,6 +179,10 @@ bool s390_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
     }
 
     if (excp) {
+        if (excp != PGM_ADDRESSING) {
+            stq_phys(env_cpu(env)->as,
+                     env->psa + offsetof(LowCore, trans_exc_code), tec);
+        }
         trigger_pgm_exception(env, excp, ILEN_AUTO);
     }
     cpu_restore_state(cs, retaddr, true);
-- 
2.17.1



^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH v3 08/18] target/s390: Return exception from mmu_translate_real
  2019-09-26 16:25 [PATCH v3 00/18] target/s390: Use tcg unwinding for ilen Richard Henderson
                   ` (6 preceding siblings ...)
  2019-09-26 16:26 ` [PATCH v3 07/18] target/s390x: Handle tec " Richard Henderson
@ 2019-09-26 16:26 ` Richard Henderson
  2019-09-27 10:44   ` David Hildenbrand
  2019-09-26 16:26 ` [PATCH v3 09/18] target/s390x: Remove exc argument to mmu_translate_asce Richard Henderson
                   ` (10 subsequent siblings)
  18 siblings, 1 reply; 49+ messages in thread
From: Richard Henderson @ 2019-09-26 16:26 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-s390x, david

Do not raise the exception directly within mmu_translate_real,
but pass it back so that caller may do so.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/s390x/internal.h    | 2 +-
 target/s390x/excp_helper.c | 4 ++--
 target/s390x/mmu_helper.c  | 8 ++++----
 3 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/target/s390x/internal.h b/target/s390x/internal.h
index c243fa725b..c4388aaf23 100644
--- a/target/s390x/internal.h
+++ b/target/s390x/internal.h
@@ -362,7 +362,7 @@ void probe_write_access(CPUS390XState *env, uint64_t addr, uint64_t len,
 int mmu_translate(CPUS390XState *env, target_ulong vaddr, int rw, uint64_t asc,
                   target_ulong *raddr, int *flags, bool exc);
 int mmu_translate_real(CPUS390XState *env, target_ulong raddr, int rw,
-                       target_ulong *addr, int *flags);
+                       target_ulong *addr, int *flags, uint64_t *tec);
 
 
 /* misc_helper.c */
diff --git a/target/s390x/excp_helper.c b/target/s390x/excp_helper.c
index ab2ed47fef..906b87c071 100644
--- a/target/s390x/excp_helper.c
+++ b/target/s390x/excp_helper.c
@@ -147,8 +147,8 @@ bool s390_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
         if (!(env->psw.mask & PSW_MASK_64)) {
             vaddr &= 0x7fffffff;
         }
-        fail = mmu_translate_real(env, vaddr, access_type, &raddr, &prot);
-        excp = 0; /* exception already raised */
+        excp = mmu_translate_real(env, vaddr, access_type, &raddr, &prot, &tec);
+        fail = excp;
     } else {
         g_assert_not_reached();
     }
diff --git a/target/s390x/mmu_helper.c b/target/s390x/mmu_helper.c
index 3ef40a37a7..b783c62bd7 100644
--- a/target/s390x/mmu_helper.c
+++ b/target/s390x/mmu_helper.c
@@ -523,10 +523,10 @@ void s390_cpu_virt_mem_handle_exc(S390CPU *cpu, uintptr_t ra)
  * @param rw     0 = read, 1 = write, 2 = code fetch
  * @param addr   the translated address is stored to this pointer
  * @param flags  the PAGE_READ/WRITE/EXEC flags are stored to this pointer
- * @return       0 if the translation was successful, < 0 if a fault occurred
+ * @return       0 = success, != 0, the exception to raise
  */
 int mmu_translate_real(CPUS390XState *env, target_ulong raddr, int rw,
-                       target_ulong *addr, int *flags)
+                       target_ulong *addr, int *flags, uint64_t *tec)
 {
     const bool lowprot_enabled = env->cregs[0] & CR0_LOWPROT;
 
@@ -535,8 +535,8 @@ int mmu_translate_real(CPUS390XState *env, target_ulong raddr, int rw,
         /* see comment in mmu_translate() how this works */
         *flags |= PAGE_WRITE_INV;
         if (is_low_address(raddr) && rw == MMU_DATA_STORE) {
-            trigger_access_exception(env, PGM_PROTECTION, ILEN_AUTO, 0);
-            return -EACCES;
+            *tec = 0;
+            return PGM_PROTECTION;
         }
     }
 
-- 
2.17.1



^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH v3 09/18] target/s390x: Remove exc argument to mmu_translate_asce
  2019-09-26 16:25 [PATCH v3 00/18] target/s390: Use tcg unwinding for ilen Richard Henderson
                   ` (7 preceding siblings ...)
  2019-09-26 16:26 ` [PATCH v3 08/18] target/s390: Return exception from mmu_translate_real Richard Henderson
@ 2019-09-26 16:26 ` Richard Henderson
  2019-09-27 10:45   ` David Hildenbrand
  2019-09-26 16:26 ` [PATCH v3 10/18] target/s390: Return exception from mmu_translate Richard Henderson
                   ` (9 subsequent siblings)
  18 siblings, 1 reply; 49+ messages in thread
From: Richard Henderson @ 2019-09-26 16:26 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-s390x, david

Now that mmu_translate_asce returns the exception instead of
raising it, the argument is unused.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/s390x/mmu_helper.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/target/s390x/mmu_helper.c b/target/s390x/mmu_helper.c
index b783c62bd7..ed6570db62 100644
--- a/target/s390x/mmu_helper.c
+++ b/target/s390x/mmu_helper.c
@@ -113,7 +113,7 @@ static inline int read_table_entry(hwaddr gaddr, uint64_t *entry)
 
 static int mmu_translate_asce(CPUS390XState *env, target_ulong vaddr,
                               uint64_t asc, uint64_t asce, target_ulong *raddr,
-                              int *flags, int rw, bool exc)
+                              int *flags, int rw)
 {
     const bool edat1 = (env->cregs[0] & CR0_EDAT) &&
                        s390_has_feat(S390_FEAT_EDAT);
@@ -402,7 +402,7 @@ int mmu_translate(CPUS390XState *env, target_ulong vaddr, int rw, uint64_t asc,
     }
 
     /* perform the DAT translation */
-    r = mmu_translate_asce(env, vaddr, asc, asce, raddr, flags, rw, exc);
+    r = mmu_translate_asce(env, vaddr, asc, asce, raddr, flags, rw);
     if (unlikely(r)) {
         if (exc) {
             trigger_access_exception(env, r, ilen, tec);
-- 
2.17.1



^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH v3 10/18] target/s390: Return exception from mmu_translate
  2019-09-26 16:25 [PATCH v3 00/18] target/s390: Use tcg unwinding for ilen Richard Henderson
                   ` (8 preceding siblings ...)
  2019-09-26 16:26 ` [PATCH v3 09/18] target/s390x: Remove exc argument to mmu_translate_asce Richard Henderson
@ 2019-09-26 16:26 ` Richard Henderson
  2019-09-27 10:55   ` David Hildenbrand
  2019-09-26 16:26 ` [PATCH v3 11/18] target/s390: Return exception from translate_pages Richard Henderson
                   ` (8 subsequent siblings)
  18 siblings, 1 reply; 49+ messages in thread
From: Richard Henderson @ 2019-09-26 16:26 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-s390x, david

Do not raise the exception directly within mmu_translate,
but pass it back so that caller may do so.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/s390x/internal.h    |  2 +-
 target/s390x/excp_helper.c |  4 ++--
 target/s390x/mem_helper.c  | 13 ++++++++++---
 target/s390x/mmu_helper.c  | 36 ++++++++++++++----------------------
 4 files changed, 27 insertions(+), 28 deletions(-)

diff --git a/target/s390x/internal.h b/target/s390x/internal.h
index c4388aaf23..c993c3ef40 100644
--- a/target/s390x/internal.h
+++ b/target/s390x/internal.h
@@ -360,7 +360,7 @@ void probe_write_access(CPUS390XState *env, uint64_t addr, uint64_t len,
 
 /* mmu_helper.c */
 int mmu_translate(CPUS390XState *env, target_ulong vaddr, int rw, uint64_t asc,
-                  target_ulong *raddr, int *flags, bool exc);
+                  target_ulong *raddr, int *flags, uint64_t *tec);
 int mmu_translate_real(CPUS390XState *env, target_ulong raddr, int rw,
                        target_ulong *addr, int *flags, uint64_t *tec);
 
diff --git a/target/s390x/excp_helper.c b/target/s390x/excp_helper.c
index 906b87c071..6a0728b65f 100644
--- a/target/s390x/excp_helper.c
+++ b/target/s390x/excp_helper.c
@@ -140,8 +140,8 @@ bool s390_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
         if (!(env->psw.mask & PSW_MASK_64)) {
             vaddr &= 0x7fffffff;
         }
-        fail = mmu_translate(env, vaddr, access_type, asc, &raddr, &prot, true);
-        excp = 0; /* exception already raised */
+        excp = mmu_translate(env, vaddr, access_type, asc, &raddr, &prot, &tec);
+        fail = excp;
     } else if (mmu_idx == MMU_REAL_IDX) {
         /* 31-Bit mode */
         if (!(env->psw.mask & PSW_MASK_64)) {
diff --git a/target/s390x/mem_helper.c b/target/s390x/mem_helper.c
index 7d2a652823..e15aa296dd 100644
--- a/target/s390x/mem_helper.c
+++ b/target/s390x/mem_helper.c
@@ -2364,8 +2364,8 @@ uint64_t HELPER(lra)(CPUS390XState *env, uint64_t addr)
     CPUState *cs = env_cpu(env);
     uint32_t cc = 0;
     uint64_t asc = env->psw.mask & PSW_MASK_ASC;
-    uint64_t ret;
-    int old_exc, flags;
+    uint64_t ret, tec;
+    int old_exc, flags, exc;
 
     /* XXX incomplete - has more corner cases */
     if (!(env->psw.mask & PSW_MASK_64) && (addr >> 32)) {
@@ -2373,7 +2373,14 @@ uint64_t HELPER(lra)(CPUS390XState *env, uint64_t addr)
     }
 
     old_exc = cs->exception_index;
-    if (mmu_translate(env, addr, 0, asc, &ret, &flags, true)) {
+    exc = mmu_translate(env, addr, 0, asc, &ret, &flags, &tec);
+    if (exc) {
+        /*
+         * We don't care about ILEN or TEC, as we're not going to
+         * deliver the exception -- thus resetting exception_index below.
+         * TODO: clean this up.
+         */
+        trigger_pgm_exception(env, exc, ILEN_UNWIND);
         cc = 3;
     }
     if (cs->exception_index == EXCP_PGM) {
diff --git a/target/s390x/mmu_helper.c b/target/s390x/mmu_helper.c
index ed6570db62..a9219942b1 100644
--- a/target/s390x/mmu_helper.c
+++ b/target/s390x/mmu_helper.c
@@ -349,17 +349,15 @@ static void mmu_handle_skey(target_ulong addr, int rw, int *flags)
  * @return       0 if the translation was successful, -1 if a fault occurred
  */
 int mmu_translate(CPUS390XState *env, target_ulong vaddr, int rw, uint64_t asc,
-                  target_ulong *raddr, int *flags, bool exc)
+                  target_ulong *raddr, int *flags, uint64_t *tec)
 {
-    /* Code accesses have an undefined ilc, let's use 2 bytes. */
-    const int ilen = (rw == MMU_INST_FETCH) ? 2 : ILEN_AUTO;
-    uint64_t tec = (vaddr & TARGET_PAGE_MASK) | (asc >> 46) |
-                   (rw == MMU_DATA_STORE ? FS_WRITE : FS_READ);
     uint64_t asce;
     int r;
 
-
+    *tec = (vaddr & TARGET_PAGE_MASK) | (asc >> 46) |
+            (rw == MMU_DATA_STORE ? FS_WRITE : FS_READ);
     *flags = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
+
     if (is_low_address(vaddr & TARGET_PAGE_MASK) && lowprot_enabled(env, asc)) {
         /*
          * If any part of this page is currently protected, make sure the
@@ -371,10 +369,7 @@ int mmu_translate(CPUS390XState *env, target_ulong vaddr, int rw, uint64_t asc,
          */
         *flags |= PAGE_WRITE_INV;
         if (is_low_address(vaddr) && rw == MMU_DATA_STORE) {
-            if (exc) {
-                trigger_access_exception(env, PGM_PROTECTION, ILEN_AUTO, 0);
-            }
-            return -EACCES;
+            return PGM_PROTECTION;
         }
     }
 
@@ -404,20 +399,14 @@ int mmu_translate(CPUS390XState *env, target_ulong vaddr, int rw, uint64_t asc,
     /* perform the DAT translation */
     r = mmu_translate_asce(env, vaddr, asc, asce, raddr, flags, rw);
     if (unlikely(r)) {
-        if (exc) {
-            trigger_access_exception(env, r, ilen, tec);
-        }
-        return -1;
+        return r;
     }
 
     /* check for DAT protection */
     if (unlikely(rw == MMU_DATA_STORE && !(*flags & PAGE_WRITE))) {
-        if (exc) {
-            /* DAT sets bit 61 only */
-            tec |= 0x4;
-            trigger_access_exception(env, PGM_PROTECTION, ilen, tec);
-        }
-        return -1;
+        /* DAT sets bit 61 only */
+        *tec |= 0x4;
+        return PGM_PROTECTION;
     }
 
 nodat:
@@ -441,9 +430,12 @@ static int translate_pages(S390CPU *cpu, vaddr addr, int nr_pages,
     int ret, i, pflags;
 
     for (i = 0; i < nr_pages; i++) {
-        ret = mmu_translate(env, addr, is_write, asc, &pages[i], &pflags, true);
+        uint64_t tec;
+
+        ret = mmu_translate(env, addr, is_write, asc, &pages[i], &pflags, &tec);
         if (ret) {
-            return ret;
+            trigger_access_exception(env, ret, ILEN_AUTO, tec);
+            return -EFAULT;
         }
         if (!address_space_access_valid(&address_space_memory, pages[i],
                                         TARGET_PAGE_SIZE, is_write,
-- 
2.17.1



^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH v3 11/18] target/s390: Return exception from translate_pages
  2019-09-26 16:25 [PATCH v3 00/18] target/s390: Use tcg unwinding for ilen Richard Henderson
                   ` (9 preceding siblings ...)
  2019-09-26 16:26 ` [PATCH v3 10/18] target/s390: Return exception from mmu_translate Richard Henderson
@ 2019-09-26 16:26 ` Richard Henderson
  2019-09-27 10:56   ` David Hildenbrand
  2019-09-26 16:26 ` [PATCH v3 12/18] target/s390x: Remove fail variable from s390_cpu_tlb_fill Richard Henderson
                   ` (7 subsequent siblings)
  18 siblings, 1 reply; 49+ messages in thread
From: Richard Henderson @ 2019-09-26 16:26 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-s390x, david

Do not raise the exception directly within translate_pages,
but pass it back so that caller may do so.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/s390x/mmu_helper.c | 20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/target/s390x/mmu_helper.c b/target/s390x/mmu_helper.c
index a9219942b1..5ecd9ee87e 100644
--- a/target/s390x/mmu_helper.c
+++ b/target/s390x/mmu_helper.c
@@ -423,25 +423,22 @@ nodat:
  * the MEMOP interface.
  */
 static int translate_pages(S390CPU *cpu, vaddr addr, int nr_pages,
-                           target_ulong *pages, bool is_write)
+                           target_ulong *pages, bool is_write, uint64_t *tec)
 {
     uint64_t asc = cpu->env.psw.mask & PSW_MASK_ASC;
     CPUS390XState *env = &cpu->env;
     int ret, i, pflags;
 
     for (i = 0; i < nr_pages; i++) {
-        uint64_t tec;
-
-        ret = mmu_translate(env, addr, is_write, asc, &pages[i], &pflags, &tec);
+        ret = mmu_translate(env, addr, is_write, asc, &pages[i], &pflags, tec);
         if (ret) {
-            trigger_access_exception(env, ret, ILEN_AUTO, tec);
-            return -EFAULT;
+            return ret;
         }
         if (!address_space_access_valid(&address_space_memory, pages[i],
                                         TARGET_PAGE_SIZE, is_write,
                                         MEMTXATTRS_UNSPECIFIED)) {
-            trigger_access_exception(env, PGM_ADDRESSING, ILEN_AUTO, 0);
-            return -EFAULT;
+            *tec = 0; /* unused */
+            return PGM_ADDRESSING;
         }
         addr += TARGET_PAGE_SIZE;
     }
@@ -469,6 +466,7 @@ int s390_cpu_virt_mem_rw(S390CPU *cpu, vaddr laddr, uint8_t ar, void *hostbuf,
 {
     int currlen, nr_pages, i;
     target_ulong *pages;
+    uint64_t tec;
     int ret;
 
     if (kvm_enabled()) {
@@ -482,8 +480,10 @@ int s390_cpu_virt_mem_rw(S390CPU *cpu, vaddr laddr, uint8_t ar, void *hostbuf,
                + 1;
     pages = g_malloc(nr_pages * sizeof(*pages));
 
-    ret = translate_pages(cpu, laddr, nr_pages, pages, is_write);
-    if (ret == 0 && hostbuf != NULL) {
+    ret = translate_pages(cpu, laddr, nr_pages, pages, is_write, &tec);
+    if (ret) {
+        trigger_access_exception(&cpu->env, ret, ILEN_AUTO, tec);
+    } else if (hostbuf != NULL) {
         /* Copy data by stepping through the area page by page */
         for (i = 0; i < nr_pages; i++) {
             currlen = MIN(len, TARGET_PAGE_SIZE - (laddr % TARGET_PAGE_SIZE));
-- 
2.17.1



^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH v3 12/18] target/s390x: Remove fail variable from s390_cpu_tlb_fill
  2019-09-26 16:25 [PATCH v3 00/18] target/s390: Use tcg unwinding for ilen Richard Henderson
                   ` (10 preceding siblings ...)
  2019-09-26 16:26 ` [PATCH v3 11/18] target/s390: Return exception from translate_pages Richard Henderson
@ 2019-09-26 16:26 ` Richard Henderson
  2019-09-27 10:56   ` David Hildenbrand
  2019-09-26 16:26 ` [PATCH v3 13/18] target/s390x: Simplify helper_lra Richard Henderson
                   ` (6 subsequent siblings)
  18 siblings, 1 reply; 49+ messages in thread
From: Richard Henderson @ 2019-09-26 16:26 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-s390x, david

Now that excp always contains a real exception number, we can
use that instead of a separate fail variable.  This allows a
redundant test to be removed.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/s390x/excp_helper.c | 19 +++++++------------
 1 file changed, 7 insertions(+), 12 deletions(-)

diff --git a/target/s390x/excp_helper.c b/target/s390x/excp_helper.c
index 6a0728b65f..98a1ee8317 100644
--- a/target/s390x/excp_helper.c
+++ b/target/s390x/excp_helper.c
@@ -127,7 +127,7 @@ bool s390_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
     CPUS390XState *env = &cpu->env;
     target_ulong vaddr, raddr;
     uint64_t asc, tec;
-    int prot, fail, excp;
+    int prot, excp;
 
     qemu_log_mask(CPU_LOG_MMU, "%s: addr 0x%" VADDR_PRIx " rw %d mmu_idx %d\n",
                   __func__, address, access_type, mmu_idx);
@@ -141,20 +141,18 @@ bool s390_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
             vaddr &= 0x7fffffff;
         }
         excp = mmu_translate(env, vaddr, access_type, asc, &raddr, &prot, &tec);
-        fail = excp;
     } else if (mmu_idx == MMU_REAL_IDX) {
         /* 31-Bit mode */
         if (!(env->psw.mask & PSW_MASK_64)) {
             vaddr &= 0x7fffffff;
         }
         excp = mmu_translate_real(env, vaddr, access_type, &raddr, &prot, &tec);
-        fail = excp;
     } else {
         g_assert_not_reached();
     }
 
     /* check out of RAM access */
-    if (!fail &&
+    if (!excp &&
         !address_space_access_valid(&address_space_memory, raddr,
                                     TARGET_PAGE_SIZE, access_type,
                                     MEMTXATTRS_UNSPECIFIED)) {
@@ -163,10 +161,9 @@ bool s390_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
                       __func__, (uint64_t)raddr, (uint64_t)ram_size);
         excp = PGM_ADDRESSING;
         tec = 0; /* unused */
-        fail = 1;
     }
 
-    if (!fail) {
+    if (!excp) {
         qemu_log_mask(CPU_LOG_MMU,
                       "%s: set tlb %" PRIx64 " -> %" PRIx64 " (%x)\n",
                       __func__, (uint64_t)vaddr, (uint64_t)raddr, prot);
@@ -178,13 +175,11 @@ bool s390_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
         return false;
     }
 
-    if (excp) {
-        if (excp != PGM_ADDRESSING) {
-            stq_phys(env_cpu(env)->as,
-                     env->psa + offsetof(LowCore, trans_exc_code), tec);
-        }
-        trigger_pgm_exception(env, excp, ILEN_AUTO);
+    if (excp != PGM_ADDRESSING) {
+        stq_phys(env_cpu(env)->as,
+                 env->psa + offsetof(LowCore, trans_exc_code), tec);
     }
+    trigger_pgm_exception(env, excp, ILEN_AUTO);
     cpu_restore_state(cs, retaddr, true);
 
     /*
-- 
2.17.1



^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH v3 13/18] target/s390x: Simplify helper_lra
  2019-09-26 16:25 [PATCH v3 00/18] target/s390: Use tcg unwinding for ilen Richard Henderson
                   ` (11 preceding siblings ...)
  2019-09-26 16:26 ` [PATCH v3 12/18] target/s390x: Remove fail variable from s390_cpu_tlb_fill Richard Henderson
@ 2019-09-26 16:26 ` Richard Henderson
  2019-09-27 10:57   ` David Hildenbrand
  2019-09-26 16:26 ` [PATCH v3 14/18] target/s390x: Rely on unwinding in s390_cpu_tlb_fill Richard Henderson
                   ` (5 subsequent siblings)
  18 siblings, 1 reply; 49+ messages in thread
From: Richard Henderson @ 2019-09-26 16:26 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-s390x, david

We currently call trigger_pgm_exception to set cs->exception_index
and env->int_pgm_code and then read the values back and then
reset cs->exception_index so that the exception is not delivered.

Instead, use the exception type that we already have directly
without ever triggering an exception that must be suppressed.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/s390x/mem_helper.c | 17 +++--------------
 1 file changed, 3 insertions(+), 14 deletions(-)

diff --git a/target/s390x/mem_helper.c b/target/s390x/mem_helper.c
index e15aa296dd..4254548935 100644
--- a/target/s390x/mem_helper.c
+++ b/target/s390x/mem_helper.c
@@ -2361,34 +2361,23 @@ void HELPER(sturg)(CPUS390XState *env, uint64_t addr, uint64_t v1)
 /* load real address */
 uint64_t HELPER(lra)(CPUS390XState *env, uint64_t addr)
 {
-    CPUState *cs = env_cpu(env);
-    uint32_t cc = 0;
     uint64_t asc = env->psw.mask & PSW_MASK_ASC;
     uint64_t ret, tec;
-    int old_exc, flags, exc;
+    int flags, exc, cc;
 
     /* XXX incomplete - has more corner cases */
     if (!(env->psw.mask & PSW_MASK_64) && (addr >> 32)) {
         tcg_s390_program_interrupt(env, PGM_SPECIAL_OP, GETPC());
     }
 
-    old_exc = cs->exception_index;
     exc = mmu_translate(env, addr, 0, asc, &ret, &flags, &tec);
     if (exc) {
-        /*
-         * We don't care about ILEN or TEC, as we're not going to
-         * deliver the exception -- thus resetting exception_index below.
-         * TODO: clean this up.
-         */
-        trigger_pgm_exception(env, exc, ILEN_UNWIND);
         cc = 3;
-    }
-    if (cs->exception_index == EXCP_PGM) {
-        ret = env->int_pgm_code | 0x80000000;
+        ret = exc | 0x80000000;
     } else {
+        cc = 0;
         ret |= addr & ~TARGET_PAGE_MASK;
     }
-    cs->exception_index = old_exc;
 
     env->cc_op = cc;
     return ret;
-- 
2.17.1



^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH v3 14/18] target/s390x: Rely on unwinding in s390_cpu_tlb_fill
  2019-09-26 16:25 [PATCH v3 00/18] target/s390: Use tcg unwinding for ilen Richard Henderson
                   ` (12 preceding siblings ...)
  2019-09-26 16:26 ` [PATCH v3 13/18] target/s390x: Simplify helper_lra Richard Henderson
@ 2019-09-26 16:26 ` Richard Henderson
  2019-09-27 11:02   ` David Hildenbrand
  2019-09-26 16:26 ` [PATCH v3 15/18] target/s390x: Rely on unwinding in s390_cpu_virt_mem_rw Richard Henderson
                   ` (4 subsequent siblings)
  18 siblings, 1 reply; 49+ messages in thread
From: Richard Henderson @ 2019-09-26 16:26 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-s390x, david

We currently set ilen to AUTO, then overwrite that during
unwinding, then overwrite that for the code access case.

This can be simplified to setting ilen to our arbitrary
value for the (undefined) code access case, then rely on
unwinding to overwrite that with the correct value for
the data access case.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/s390x/excp_helper.c | 23 +++++++----------------
 1 file changed, 7 insertions(+), 16 deletions(-)

diff --git a/target/s390x/excp_helper.c b/target/s390x/excp_helper.c
index 98a1ee8317..8ce992e639 100644
--- a/target/s390x/excp_helper.c
+++ b/target/s390x/excp_helper.c
@@ -96,7 +96,7 @@ bool s390_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
 {
     S390CPU *cpu = S390_CPU(cs);
 
-    trigger_pgm_exception(&cpu->env, PGM_ADDRESSING, ILEN_AUTO);
+    trigger_pgm_exception(&cpu->env, PGM_ADDRESSING, ILEN_UNWIND);
     /* On real machines this value is dropped into LowMem.  Since this
        is userland, simply put this someplace that cpu_loop can find it.  */
     cpu->env.__excp_addr = address;
@@ -179,24 +179,15 @@ bool s390_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
         stq_phys(env_cpu(env)->as,
                  env->psa + offsetof(LowCore, trans_exc_code), tec);
     }
-    trigger_pgm_exception(env, excp, ILEN_AUTO);
-    cpu_restore_state(cs, retaddr, true);
 
     /*
-     * The ILC value for code accesses is undefined.  The important
-     * thing here is to *not* leave env->int_pgm_ilen set to ILEN_AUTO,
-     * which would cause do_program_interrupt to attempt to read from
-     * env->psw.addr again.  C.f. the condition in trigger_page_fault,
-     * but is not universally applied.
-     *
-     * ??? If we remove ILEN_AUTO, by moving the computation of ILEN
-     * into cpu_restore_state, then we may remove this entirely.
+     * For data accesses, ILEN will be filled in from the unwind info,
+     * within cpu_loop_exit_restore.  For code accesses, retaddr == 0,
+     * and so unwinding will not occur.  However, ILEN is also undefined
+     * for that case -- we choose to set ILEN = 2.
      */
-    if (access_type == MMU_INST_FETCH) {
-        env->int_pgm_ilen = 2;
-    }
-
-    cpu_loop_exit(cs);
+    trigger_pgm_exception(env, excp, 2);
+    cpu_loop_exit_restore(cs, retaddr);
 }
 
 static void do_program_interrupt(CPUS390XState *env)
-- 
2.17.1



^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH v3 15/18] target/s390x: Rely on unwinding in s390_cpu_virt_mem_rw
  2019-09-26 16:25 [PATCH v3 00/18] target/s390: Use tcg unwinding for ilen Richard Henderson
                   ` (13 preceding siblings ...)
  2019-09-26 16:26 ` [PATCH v3 14/18] target/s390x: Rely on unwinding in s390_cpu_tlb_fill Richard Henderson
@ 2019-09-26 16:26 ` Richard Henderson
  2019-09-27 11:04   ` David Hildenbrand
  2019-09-26 16:26 ` [PATCH v3 16/18] target/s390x: Remove ILEN_AUTO Richard Henderson
                   ` (3 subsequent siblings)
  18 siblings, 1 reply; 49+ messages in thread
From: Richard Henderson @ 2019-09-26 16:26 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-s390x, david

For TCG, we will always call s390_cpu_virt_mem_handle_exc,
which will go through the unwinder to set ILEN.  For KVM,
we do not go through do_program_interrupt, so this argument
is unused.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/s390x/mmu_helper.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/s390x/mmu_helper.c b/target/s390x/mmu_helper.c
index 5ecd9ee87e..bf7fddb056 100644
--- a/target/s390x/mmu_helper.c
+++ b/target/s390x/mmu_helper.c
@@ -482,7 +482,7 @@ int s390_cpu_virt_mem_rw(S390CPU *cpu, vaddr laddr, uint8_t ar, void *hostbuf,
 
     ret = translate_pages(cpu, laddr, nr_pages, pages, is_write, &tec);
     if (ret) {
-        trigger_access_exception(&cpu->env, ret, ILEN_AUTO, tec);
+        trigger_access_exception(&cpu->env, ret, ILEN_UNWIND, tec);
     } else if (hostbuf != NULL) {
         /* Copy data by stepping through the area page by page */
         for (i = 0; i < nr_pages; i++) {
-- 
2.17.1



^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH v3 16/18] target/s390x: Remove ILEN_AUTO
  2019-09-26 16:25 [PATCH v3 00/18] target/s390: Use tcg unwinding for ilen Richard Henderson
                   ` (14 preceding siblings ...)
  2019-09-26 16:26 ` [PATCH v3 15/18] target/s390x: Rely on unwinding in s390_cpu_virt_mem_rw Richard Henderson
@ 2019-09-26 16:26 ` Richard Henderson
  2019-09-27 11:04   ` David Hildenbrand
  2019-09-26 16:26 ` [PATCH v3 17/18] target/s390x: Remove ilen argument from trigger_access_exception Richard Henderson
                   ` (2 subsequent siblings)
  18 siblings, 1 reply; 49+ messages in thread
From: Richard Henderson @ 2019-09-26 16:26 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-s390x, david

This setting is no longer used.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/s390x/cpu.h         | 2 --
 target/s390x/excp_helper.c | 3 ---
 2 files changed, 5 deletions(-)

diff --git a/target/s390x/cpu.h b/target/s390x/cpu.h
index a5eab491cd..fc941c7d76 100644
--- a/target/s390x/cpu.h
+++ b/target/s390x/cpu.h
@@ -816,8 +816,6 @@ void s390_io_interrupt(uint16_t subchannel_id, uint16_t subchannel_nr,
                        uint32_t io_int_parm, uint32_t io_int_word);
 /* instruction length set by unwind info */
 #define ILEN_UNWIND                 0
-/* automatically detect the instruction length */
-#define ILEN_AUTO                   0xff
 #define RA_IGNORED                  0
 void s390_program_interrupt(CPUS390XState *env, uint32_t code, uintptr_t ra);
 /* service interrupts are floating therefore we must not pass an cpustate */
diff --git a/target/s390x/excp_helper.c b/target/s390x/excp_helper.c
index 8ce992e639..c252e9a7d8 100644
--- a/target/s390x/excp_helper.c
+++ b/target/s390x/excp_helper.c
@@ -196,9 +196,6 @@ static void do_program_interrupt(CPUS390XState *env)
     LowCore *lowcore;
     int ilen = env->int_pgm_ilen;
 
-    if (ilen == ILEN_AUTO) {
-        ilen = get_ilen(cpu_ldub_code(env, env->psw.addr));
-    }
     assert(ilen == 2 || ilen == 4 || ilen == 6);
 
     switch (env->int_pgm_code) {
-- 
2.17.1



^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH v3 17/18] target/s390x: Remove ilen argument from trigger_access_exception
  2019-09-26 16:25 [PATCH v3 00/18] target/s390: Use tcg unwinding for ilen Richard Henderson
                   ` (15 preceding siblings ...)
  2019-09-26 16:26 ` [PATCH v3 16/18] target/s390x: Remove ILEN_AUTO Richard Henderson
@ 2019-09-26 16:26 ` Richard Henderson
  2019-09-27 11:04   ` David Hildenbrand
  2019-09-26 16:26 ` [PATCH v3 18/18] target/s390x: Remove ilen argument from trigger_pgm_exception Richard Henderson
  2019-09-27  8:18 ` [PATCH v3 00/18] target/s390: Use tcg unwinding for ilen David Hildenbrand
  18 siblings, 1 reply; 49+ messages in thread
From: Richard Henderson @ 2019-09-26 16:26 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-s390x, david

The single caller passes ILEN_UNWIND; pass that along to
trigger_pgm_exception directly.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/s390x/mmu_helper.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/target/s390x/mmu_helper.c b/target/s390x/mmu_helper.c
index bf7fddb056..e6c3139c57 100644
--- a/target/s390x/mmu_helper.c
+++ b/target/s390x/mmu_helper.c
@@ -33,7 +33,7 @@
 #define FS_WRITE 0x400
 
 static void trigger_access_exception(CPUS390XState *env, uint32_t type,
-                                     uint32_t ilen, uint64_t tec)
+                                     uint64_t tec)
 {
     S390CPU *cpu = env_archcpu(env);
 
@@ -44,7 +44,7 @@ static void trigger_access_exception(CPUS390XState *env, uint32_t type,
         if (type != PGM_ADDRESSING) {
             stq_phys(cs->as, env->psa + offsetof(LowCore, trans_exc_code), tec);
         }
-        trigger_pgm_exception(env, type, ilen);
+        trigger_pgm_exception(env, type, ILEN_UNWIND);
     }
 }
 
@@ -482,7 +482,7 @@ int s390_cpu_virt_mem_rw(S390CPU *cpu, vaddr laddr, uint8_t ar, void *hostbuf,
 
     ret = translate_pages(cpu, laddr, nr_pages, pages, is_write, &tec);
     if (ret) {
-        trigger_access_exception(&cpu->env, ret, ILEN_UNWIND, tec);
+        trigger_access_exception(&cpu->env, ret, tec);
     } else if (hostbuf != NULL) {
         /* Copy data by stepping through the area page by page */
         for (i = 0; i < nr_pages; i++) {
-- 
2.17.1



^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH v3 18/18] target/s390x: Remove ilen argument from trigger_pgm_exception
  2019-09-26 16:25 [PATCH v3 00/18] target/s390: Use tcg unwinding for ilen Richard Henderson
                   ` (16 preceding siblings ...)
  2019-09-26 16:26 ` [PATCH v3 17/18] target/s390x: Remove ilen argument from trigger_access_exception Richard Henderson
@ 2019-09-26 16:26 ` Richard Henderson
  2019-09-27 11:05   ` David Hildenbrand
  2019-09-27  8:18 ` [PATCH v3 00/18] target/s390: Use tcg unwinding for ilen David Hildenbrand
  18 siblings, 1 reply; 49+ messages in thread
From: Richard Henderson @ 2019-09-26 16:26 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-s390x, david

All but one caller passes ILEN_UNWIND, which is not stored.
For the one use case in s390_cpu_tlb_fill, set int_pgm_ilen
directly, simply to avoid the assert within do_program_interrupt.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/s390x/internal.h    | 2 +-
 target/s390x/excp_helper.c | 7 ++++---
 target/s390x/interrupt.c   | 7 ++-----
 target/s390x/mmu_helper.c  | 2 +-
 4 files changed, 8 insertions(+), 10 deletions(-)

diff --git a/target/s390x/internal.h b/target/s390x/internal.h
index c993c3ef40..d37816104d 100644
--- a/target/s390x/internal.h
+++ b/target/s390x/internal.h
@@ -317,7 +317,7 @@ void cpu_unmap_lowcore(LowCore *lowcore);
 
 
 /* interrupt.c */
-void trigger_pgm_exception(CPUS390XState *env, uint32_t code, uint32_t ilen);
+void trigger_pgm_exception(CPUS390XState *env, uint32_t code);
 void cpu_inject_clock_comparator(S390CPU *cpu);
 void cpu_inject_cpu_timer(S390CPU *cpu);
 void cpu_inject_emergency_signal(S390CPU *cpu, uint16_t src_cpu_addr);
diff --git a/target/s390x/excp_helper.c b/target/s390x/excp_helper.c
index c252e9a7d8..e70c20d363 100644
--- a/target/s390x/excp_helper.c
+++ b/target/s390x/excp_helper.c
@@ -42,7 +42,7 @@ void QEMU_NORETURN tcg_s390_program_interrupt(CPUS390XState *env,
     cpu_restore_state(cs, ra, true);
     qemu_log_mask(CPU_LOG_INT, "program interrupt at %#" PRIx64 "\n",
                   env->psw.addr);
-    trigger_pgm_exception(env, code, ILEN_UNWIND);
+    trigger_pgm_exception(env, code);
     cpu_loop_exit(cs);
 }
 
@@ -96,7 +96,7 @@ bool s390_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
 {
     S390CPU *cpu = S390_CPU(cs);
 
-    trigger_pgm_exception(&cpu->env, PGM_ADDRESSING, ILEN_UNWIND);
+    trigger_pgm_exception(&cpu->env, PGM_ADDRESSING);
     /* On real machines this value is dropped into LowMem.  Since this
        is userland, simply put this someplace that cpu_loop can find it.  */
     cpu->env.__excp_addr = address;
@@ -186,7 +186,8 @@ bool s390_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
      * and so unwinding will not occur.  However, ILEN is also undefined
      * for that case -- we choose to set ILEN = 2.
      */
-    trigger_pgm_exception(env, excp, 2);
+    env->int_pgm_ilen = 2;
+    trigger_pgm_exception(env, excp);
     cpu_loop_exit_restore(cs, retaddr);
 }
 
diff --git a/target/s390x/interrupt.c b/target/s390x/interrupt.c
index 2b71e03914..4cdbbc8849 100644
--- a/target/s390x/interrupt.c
+++ b/target/s390x/interrupt.c
@@ -22,16 +22,13 @@
 #endif
 
 /* Ensure to exit the TB after this call! */
-void trigger_pgm_exception(CPUS390XState *env, uint32_t code, uint32_t ilen)
+void trigger_pgm_exception(CPUS390XState *env, uint32_t code)
 {
     CPUState *cs = env_cpu(env);
 
     cs->exception_index = EXCP_PGM;
     env->int_pgm_code = code;
-    /* If ILEN_UNWIND, int_pgm_ilen already has the correct value.  */
-    if (ilen != ILEN_UNWIND) {
-        env->int_pgm_ilen = ilen;
-    }
+    /* env->int_pgm_ilen is already set, or will be set during unwinding */
 }
 
 void s390_program_interrupt(CPUS390XState *env, uint32_t code, uintptr_t ra)
diff --git a/target/s390x/mmu_helper.c b/target/s390x/mmu_helper.c
index e6c3139c57..ba02d33e86 100644
--- a/target/s390x/mmu_helper.c
+++ b/target/s390x/mmu_helper.c
@@ -44,7 +44,7 @@ static void trigger_access_exception(CPUS390XState *env, uint32_t type,
         if (type != PGM_ADDRESSING) {
             stq_phys(cs->as, env->psa + offsetof(LowCore, trans_exc_code), tec);
         }
-        trigger_pgm_exception(env, type, ILEN_UNWIND);
+        trigger_pgm_exception(env, type);
     }
 }
 
-- 
2.17.1



^ permalink raw reply related	[flat|nested] 49+ messages in thread

* Re: [PATCH v3 00/18] target/s390: Use tcg unwinding for ilen
  2019-09-26 16:25 [PATCH v3 00/18] target/s390: Use tcg unwinding for ilen Richard Henderson
                   ` (17 preceding siblings ...)
  2019-09-26 16:26 ` [PATCH v3 18/18] target/s390x: Remove ilen argument from trigger_pgm_exception Richard Henderson
@ 2019-09-27  8:18 ` David Hildenbrand
  18 siblings, 0 replies; 49+ messages in thread
From: David Hildenbrand @ 2019-09-27  8:18 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: qemu-s390x

On 26.09.19 18:25, Richard Henderson wrote:
> David's cleanup of some of the mmu code reminded me of an old branch
> that I have laying around.  His new code allowed me to finish this
> idea up to completely transition away from ILEN_AUTO.
> 
> V1 was posted back in 2017:
>    https://lists.gnu.org/archive/html/qemu-devel/2017-07/msg07607.html
> V2 was posted back in April:
>    https://lists.gnu.org/archive/html/qemu-devel/2019-04/msg00063.html
> 
> Based-on: <20190925125236.4043-1-david@redhat.com> \
>   ("s390x/mmu: DAT translation rewrite")
> 

Right, that rings a bell :) I assume we can unwind in all cases except
on instruction fetches - I'm curious how it turned out and will try to
review as soon as time permits (most probably I'll start reviewing today).

-- 

Thanks,

David / dhildenb


^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH v3 01/18] target/s390x: Truncate 32-bit psw_addr before creating TB
  2019-09-26 16:25 ` [PATCH v3 01/18] target/s390x: Truncate 32-bit psw_addr before creating TB Richard Henderson
@ 2019-09-27 10:23   ` David Hildenbrand
  2019-09-27 18:24     ` Richard Henderson
  0 siblings, 1 reply; 49+ messages in thread
From: David Hildenbrand @ 2019-09-27 10:23 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: qemu-s390x

On 26.09.19 18:25, Richard Henderson wrote:
> If, somehow, the psw_addr is out of range, truncate early
> rather than after we get into gen_intermediate_code.
> 
> Reviewed-by: David Hildenbrand <david@redhat.com>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  target/s390x/cpu.h       | 26 +++++++++++++++++++-------
>  target/s390x/translate.c |  6 ------
>  2 files changed, 19 insertions(+), 13 deletions(-)
> 
> diff --git a/target/s390x/cpu.h b/target/s390x/cpu.h
> index e74a809257..ce20dafd23 100644
> --- a/target/s390x/cpu.h
> +++ b/target/s390x/cpu.h
> @@ -357,18 +357,30 @@ static inline int cpu_mmu_index(CPUS390XState *env, bool ifetch)
>  #endif
>  }
>  
> -static inline void cpu_get_tb_cpu_state(CPUS390XState* env, target_ulong *pc,
> -                                        target_ulong *cs_base, uint32_t *flags)
> +static inline void cpu_get_tb_cpu_state(CPUS390XState* env,
> +                                        target_ulong *p_pc,
> +                                        target_ulong *cs_base,
> +                                        uint32_t *p_flags)
>  {
> -    *pc = env->psw.addr;
> -    *cs_base = env->ex_value;
> -    *flags = (env->psw.mask >> FLAG_MASK_PSW_SHIFT) & FLAG_MASK_PSW;
> +    uint32_t flags;
> +    uint64_t pc;
> +
> +    flags = (env->psw.mask >> FLAG_MASK_PSW_SHIFT) & FLAG_MASK_PSW;
>      if (env->cregs[0] & CR0_AFP) {
> -        *flags |= FLAG_MASK_AFP;
> +        flags |= FLAG_MASK_AFP;
>      }
>      if (env->cregs[0] & CR0_VECTOR) {
> -        *flags |= FLAG_MASK_VECTOR;
> +        flags |= FLAG_MASK_VECTOR;
>      }
> +
> +    pc = env->psw.addr;
> +    if (!(flags & FLAG_MASK_64)) {
> +        pc &= 0x7fffffff;
> +    }

If you're fancy, you could also add 24-bit addressing mode wrapping.

Maybe unlikely(!(flags & FLAG_MASK_64)), but not sure how big the gain
will actually be.

-- 

Thanks,

David / dhildenb


^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH v3 02/18] target/s390x: Add ilen to unwind data
  2019-09-26 16:25 ` [PATCH v3 02/18] target/s390x: Add ilen to unwind data Richard Henderson
@ 2019-09-27 10:30   ` David Hildenbrand
  2019-09-27 16:02     ` Richard Henderson
  0 siblings, 1 reply; 49+ messages in thread
From: David Hildenbrand @ 2019-09-27 10:30 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: qemu-s390x, Richard Henderson

On 26.09.19 18:25, Richard Henderson wrote:
> From: Richard Henderson <rth@twiddle.net>
> 
> Use ILEN_UNWIND to signal that we have in fact that
> cpu_restore_state will have been called by the time
> we arrive in do_program_interrupt.
> 
> Signed-off-by: Richard Henderson <rth@twiddle.net>
> ---
>  target/s390x/cpu.h       |  4 +++-
>  target/s390x/interrupt.c |  5 ++++-
>  target/s390x/translate.c | 21 ++++++++++++++++++---
>  3 files changed, 25 insertions(+), 5 deletions(-)
> 
> diff --git a/target/s390x/cpu.h b/target/s390x/cpu.h
> index ce20dafd23..080ebcd6bb 100644
> --- a/target/s390x/cpu.h
> +++ b/target/s390x/cpu.h
> @@ -30,7 +30,7 @@
>  /* The z/Architecture has a strong memory model with some store-after-load re-ordering */
>  #define TCG_GUEST_DEFAULT_MO      (TCG_MO_ALL & ~TCG_MO_ST_LD)
>  
> -#define TARGET_INSN_START_EXTRA_WORDS 1
> +#define TARGET_INSN_START_EXTRA_WORDS 2
>  
>  #define MMU_MODE0_SUFFIX _primary
>  #define MMU_MODE1_SUFFIX _secondary
> @@ -814,6 +814,8 @@ int cpu_s390x_signal_handler(int host_signum, void *pinfo, void *puc);
>  void s390_crw_mchk(void);
>  void s390_io_interrupt(uint16_t subchannel_id, uint16_t subchannel_nr,
>                         uint32_t io_int_parm, uint32_t io_int_word);
> +/* instruction length set by unwind info */
> +#define ILEN_UNWIND                 0
>  /* automatically detect the instruction length */
>  #define ILEN_AUTO                   0xff
>  #define RA_IGNORED                  0
> diff --git a/target/s390x/interrupt.c b/target/s390x/interrupt.c
> index a841f7187d..30a9fb8852 100644
> --- a/target/s390x/interrupt.c
> +++ b/target/s390x/interrupt.c
> @@ -28,7 +28,10 @@ void trigger_pgm_exception(CPUS390XState *env, uint32_t code, uint32_t ilen)
>  
>      cs->exception_index = EXCP_PGM;
>      env->int_pgm_code = code;
> -    env->int_pgm_ilen = ilen;
> +    /* If ILEN_UNWIND, int_pgm_ilen already has the correct value.  */
> +    if (ilen != ILEN_UNWIND) {
> +        env->int_pgm_ilen = ilen;
> +    }
>  }
>  
>  void s390_program_interrupt(CPUS390XState *env, uint32_t code, int ilen,
> diff --git a/target/s390x/translate.c b/target/s390x/translate.c
> index e1c54ab03b..08f99454de 100644
> --- a/target/s390x/translate.c
> +++ b/target/s390x/translate.c
> @@ -6309,6 +6309,9 @@ static DisasJumpType translate_one(CPUS390XState *env, DisasContext *s)
>      /* Search for the insn in the table.  */
>      insn = extract_insn(env, s, &f);
>  
> +    /* Emit insn_start now that we know the ILEN.  */
> +    tcg_gen_insn_start(s->base.pc_next, s->cc_op, s->ilen);
> +
>      /* Not found means unimplemented/illegal opcode.  */
>      if (insn == NULL) {
>          qemu_log_mask(LOG_UNIMP, "unimplemented opcode 0x%02x%02x\n",
> @@ -6457,9 +6460,6 @@ static void s390x_tr_tb_start(DisasContextBase *db, CPUState *cs)
>  
>  static void s390x_tr_insn_start(DisasContextBase *dcbase, CPUState *cs)
>  {
> -    DisasContext *dc = container_of(dcbase, DisasContext, base);
> -
> -    tcg_gen_insn_start(dc->base.pc_next, dc->cc_op);
>  }
>  
>  static bool s390x_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cs,
> @@ -6467,6 +6467,12 @@ static bool s390x_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cs,
>  {
>      DisasContext *dc = container_of(dcbase, DisasContext, base);
>  
> +    /*
> +     * Emit an insn_start to accompany the breakpoint exception.
> +     * The ILEN value is a dummy, since we didn't actually read an insn.
> +     */
> +    tcg_gen_insn_start(dc->base.pc_next, dc->cc_op, 0);
> +
>      dc->base.is_jmp = DISAS_PC_STALE;
>      dc->do_debug = true;
>      /* The address covered by the breakpoint must be included in
> @@ -6561,8 +6567,17 @@ void restore_state_to_opc(CPUS390XState *env, TranslationBlock *tb,
>                            target_ulong *data)
>  {
>      int cc_op = data[1];
> +    int ilen = data[2];
> +
>      env->psw.addr = data[0];
> +
> +    /* Update the CC opcode if it is not already up-to-date.  */
>      if ((cc_op != CC_OP_DYNAMIC) && (cc_op != CC_OP_STATIC)) {
>          env->cc_op = cc_op;
>      }
> +
> +    /* Update ILEN, except for breakpoint, where we didn't load an insn.  */
> +    if (ilen) {
> +        env->int_pgm_ilen = ilen;
> +    }

I am not completely sure about breakpoint handling and which
implications we'll have when not setting int_pgm_ilen ...

>  }
> 

I wonder if that change can help to better handle exceptions during
EXECUTE, whereby we have to indicate the EXECUTE instruction and the
ilen of the EXECUTE instruction (so the pc and ilen of the original
EXECUTE function, not of the EXECUTE target).

I don't completely like the current interrupt handling when we have
"env->ex_value" in "s390_cpu_exec_interrupt()". I'd love to see that
check go, then we can reuse that function easily e.g., in MVC to test
and inject exceptions while processing such an interruptible instruction
- like MVC.

-- 

Thanks,

David / dhildenb


^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH v3 03/18] target/s390x: Remove ilen parameter from tcg_s390_program_interrupt
  2019-09-26 16:26 ` [PATCH v3 03/18] target/s390x: Remove ilen parameter from tcg_s390_program_interrupt Richard Henderson
@ 2019-09-27 10:31   ` David Hildenbrand
  0 siblings, 0 replies; 49+ messages in thread
From: David Hildenbrand @ 2019-09-27 10:31 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: qemu-s390x

On 26.09.19 18:26, Richard Henderson wrote:
> Since we begin the operation with an unwind, we have the proper
> value of ilen immediately available.
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  target/s390x/tcg_s390x.h   | 4 ++--
>  target/s390x/excp_helper.c | 8 ++++----
>  target/s390x/interrupt.c   | 2 +-
>  target/s390x/tcg-stub.c    | 4 ++--
>  4 files changed, 9 insertions(+), 9 deletions(-)
> 
> diff --git a/target/s390x/tcg_s390x.h b/target/s390x/tcg_s390x.h
> index 2813f9d48e..2f54ccb027 100644
> --- a/target/s390x/tcg_s390x.h
> +++ b/target/s390x/tcg_s390x.h
> @@ -14,8 +14,8 @@
>  #define TCG_S390X_H
>  
>  void tcg_s390_tod_updated(CPUState *cs, run_on_cpu_data opaque);
> -void QEMU_NORETURN tcg_s390_program_interrupt(CPUS390XState *env, uint32_t code,
> -                                              int ilen, uintptr_t ra);
> +void QEMU_NORETURN tcg_s390_program_interrupt(CPUS390XState *env,
> +                                              uint32_t code, uintptr_t ra);
>  void QEMU_NORETURN tcg_s390_data_exception(CPUS390XState *env, uint32_t dxc,
>                                             uintptr_t ra);
>  void QEMU_NORETURN tcg_s390_vector_exception(CPUS390XState *env, uint32_t vxc,
> diff --git a/target/s390x/excp_helper.c b/target/s390x/excp_helper.c
> index 892f659d5a..681a9c59e1 100644
> --- a/target/s390x/excp_helper.c
> +++ b/target/s390x/excp_helper.c
> @@ -34,15 +34,15 @@
>  #include "hw/boards.h"
>  #endif
>  
> -void QEMU_NORETURN tcg_s390_program_interrupt(CPUS390XState *env, uint32_t code,
> -                                              int ilen, uintptr_t ra)
> +void QEMU_NORETURN tcg_s390_program_interrupt(CPUS390XState *env,
> +                                              uint32_t code, uintptr_t ra)
>  {
>      CPUState *cs = env_cpu(env);
>  
>      cpu_restore_state(cs, ra, true);
>      qemu_log_mask(CPU_LOG_INT, "program interrupt at %#" PRIx64 "\n",
>                    env->psw.addr);
> -    trigger_pgm_exception(env, code, ilen);
> +    trigger_pgm_exception(env, code, ILEN_UNWIND);
>      cpu_loop_exit(cs);
>  }
>  
> @@ -60,7 +60,7 @@ void QEMU_NORETURN tcg_s390_data_exception(CPUS390XState *env, uint32_t dxc,
>      if (env->cregs[0] & CR0_AFP) {
>          env->fpc = deposit32(env->fpc, 8, 8, dxc);
>      }
> -    tcg_s390_program_interrupt(env, PGM_DATA, ILEN_AUTO, ra);
> +    tcg_s390_program_interrupt(env, PGM_DATA, ra);
>  }
>  
>  void QEMU_NORETURN tcg_s390_vector_exception(CPUS390XState *env, uint32_t vxc,
> diff --git a/target/s390x/interrupt.c b/target/s390x/interrupt.c
> index 30a9fb8852..b798e2ecbe 100644
> --- a/target/s390x/interrupt.c
> +++ b/target/s390x/interrupt.c
> @@ -40,7 +40,7 @@ void s390_program_interrupt(CPUS390XState *env, uint32_t code, int ilen,
>      if (kvm_enabled()) {
>          kvm_s390_program_interrupt(env_archcpu(env), code);
>      } else if (tcg_enabled()) {
> -        tcg_s390_program_interrupt(env, code, ilen, ra);
> +        tcg_s390_program_interrupt(env, code, ra);
>      } else {
>          g_assert_not_reached();
>      }
> diff --git a/target/s390x/tcg-stub.c b/target/s390x/tcg-stub.c
> index 32adb7276a..d22c898802 100644
> --- a/target/s390x/tcg-stub.c
> +++ b/target/s390x/tcg-stub.c
> @@ -18,8 +18,8 @@
>  void tcg_s390_tod_updated(CPUState *cs, run_on_cpu_data opaque)
>  {
>  }
> -void QEMU_NORETURN tcg_s390_program_interrupt(CPUS390XState *env, uint32_t code,
> -                                              int ilen, uintptr_t ra)
> +void QEMU_NORETURN tcg_s390_program_interrupt(CPUS390XState *env,
> +                                              uint32_t code, uintptr_t ra)
>  {
>      g_assert_not_reached();
>  }
> 

Reviewed-by: David Hildenbrand <david@redhat.com>

-- 

Thanks,

David / dhildenb


^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH v3 04/18] target/s390x: Remove ilen parameter from s390_program_interrupt
  2019-09-26 16:26 ` [PATCH v3 04/18] target/s390x: Remove ilen parameter from s390_program_interrupt Richard Henderson
@ 2019-09-27 10:34   ` David Hildenbrand
  0 siblings, 0 replies; 49+ messages in thread
From: David Hildenbrand @ 2019-09-27 10:34 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: qemu-s390x

On 26.09.19 18:26, Richard Henderson wrote:
> This is no longer used, and many of the existing uses -- particularly
> within hw/s390x -- seem questionable.
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  target/s390x/cpu.h           |  3 +-
>  hw/s390x/s390-pci-inst.c     | 58 ++++++++++++++++++------------------
>  target/s390x/cc_helper.c     |  2 +-
>  target/s390x/crypto_helper.c |  4 +--
>  target/s390x/diag.c          | 14 ++++-----
>  target/s390x/excp_helper.c   |  4 +--
>  target/s390x/fpu_helper.c    |  6 ++--
>  target/s390x/int_helper.c    | 14 ++++-----
>  target/s390x/interrupt.c     |  3 +-
>  target/s390x/ioinst.c        | 40 ++++++++++++-------------
>  target/s390x/mem_helper.c    | 43 +++++++++++++-------------
>  target/s390x/misc_helper.c   | 27 ++++++-----------
>  12 files changed, 103 insertions(+), 115 deletions(-)
> 
> diff --git a/target/s390x/cpu.h b/target/s390x/cpu.h
> index 080ebcd6bb..a5eab491cd 100644
> --- a/target/s390x/cpu.h
> +++ b/target/s390x/cpu.h
> @@ -819,8 +819,7 @@ void s390_io_interrupt(uint16_t subchannel_id, uint16_t subchannel_nr,
>  /* automatically detect the instruction length */
>  #define ILEN_AUTO                   0xff
>  #define RA_IGNORED                  0
> -void s390_program_interrupt(CPUS390XState *env, uint32_t code, int ilen,
> -                            uintptr_t ra);
> +void s390_program_interrupt(CPUS390XState *env, uint32_t code, uintptr_t ra);
>  /* service interrupts are floating therefore we must not pass an cpustate */
>  void s390_sclp_extint(uint32_t parm);
>  
> diff --git a/hw/s390x/s390-pci-inst.c b/hw/s390x/s390-pci-inst.c
> index 4b3bd4a804..92c7e45df5 100644
> --- a/hw/s390x/s390-pci-inst.c
> +++ b/hw/s390x/s390-pci-inst.c
> @@ -157,7 +157,7 @@ int clp_service_call(S390CPU *cpu, uint8_t r2, uintptr_t ra)
>      int i;
>  
>      if (env->psw.mask & PSW_MASK_PSTATE) {
> -        s390_program_interrupt(env, PGM_PRIVILEGED, 4, ra);
> +        s390_program_interrupt(env, PGM_PRIVILEGED, ra);
>          return 0;
>      }
>  
> @@ -168,7 +168,7 @@ int clp_service_call(S390CPU *cpu, uint8_t r2, uintptr_t ra)
>      reqh = (ClpReqHdr *)buffer;
>      req_len = lduw_p(&reqh->len);
>      if (req_len < 16 || req_len > 8184 || (req_len % 8 != 0)) {
> -        s390_program_interrupt(env, PGM_OPERAND, 4, ra);
> +        s390_program_interrupt(env, PGM_OPERAND, ra);
>          return 0;
>      }
>  
> @@ -180,11 +180,11 @@ int clp_service_call(S390CPU *cpu, uint8_t r2, uintptr_t ra)
>      resh = (ClpRspHdr *)(buffer + req_len);
>      res_len = lduw_p(&resh->len);
>      if (res_len < 8 || res_len > 8176 || (res_len % 8 != 0)) {
> -        s390_program_interrupt(env, PGM_OPERAND, 4, ra);
> +        s390_program_interrupt(env, PGM_OPERAND, ra);
>          return 0;
>      }
>      if ((req_len + res_len) > 8192) {
> -        s390_program_interrupt(env, PGM_OPERAND, 4, ra);
> +        s390_program_interrupt(env, PGM_OPERAND, ra);
>          return 0;
>      }
>  
> @@ -390,12 +390,12 @@ int pcilg_service_call(S390CPU *cpu, uint8_t r1, uint8_t r2, uintptr_t ra)
>      uint8_t pcias;
>  
>      if (env->psw.mask & PSW_MASK_PSTATE) {
> -        s390_program_interrupt(env, PGM_PRIVILEGED, 4, ra);
> +        s390_program_interrupt(env, PGM_PRIVILEGED, ra);
>          return 0;
>      }
>  
>      if (r2 & 0x1) {
> -        s390_program_interrupt(env, PGM_SPECIFICATION, 4, ra);
> +        s390_program_interrupt(env, PGM_SPECIFICATION, ra);
>          return 0;
>      }
>  
> @@ -429,25 +429,25 @@ int pcilg_service_call(S390CPU *cpu, uint8_t r1, uint8_t r2, uintptr_t ra)
>      switch (pcias) {
>      case ZPCI_IO_BAR_MIN...ZPCI_IO_BAR_MAX:
>          if (!len || (len > (8 - (offset & 0x7)))) {
> -            s390_program_interrupt(env, PGM_OPERAND, 4, ra);
> +            s390_program_interrupt(env, PGM_OPERAND, ra);
>              return 0;
>          }
>          result = zpci_read_bar(pbdev, pcias, offset, &data, len);
>          if (result != MEMTX_OK) {
> -            s390_program_interrupt(env, PGM_OPERAND, 4, ra);
> +            s390_program_interrupt(env, PGM_OPERAND, ra);
>              return 0;
>          }
>          break;
>      case ZPCI_CONFIG_BAR:
>          if (!len || (len > (4 - (offset & 0x3))) || len == 3) {
> -            s390_program_interrupt(env, PGM_OPERAND, 4, ra);
> +            s390_program_interrupt(env, PGM_OPERAND, ra);
>              return 0;
>          }
>          data =  pci_host_config_read_common(
>                     pbdev->pdev, offset, pci_config_size(pbdev->pdev), len);
>  
>          if (zpci_endian_swap(&data, len)) {
> -            s390_program_interrupt(env, PGM_OPERAND, 4, ra);
> +            s390_program_interrupt(env, PGM_OPERAND, ra);
>              return 0;
>          }
>          break;
> @@ -489,12 +489,12 @@ int pcistg_service_call(S390CPU *cpu, uint8_t r1, uint8_t r2, uintptr_t ra)
>      uint8_t pcias;
>  
>      if (env->psw.mask & PSW_MASK_PSTATE) {
> -        s390_program_interrupt(env, PGM_PRIVILEGED, 4, ra);
> +        s390_program_interrupt(env, PGM_PRIVILEGED, ra);
>          return 0;
>      }
>  
>      if (r2 & 0x1) {
> -        s390_program_interrupt(env, PGM_SPECIFICATION, 4, ra);
> +        s390_program_interrupt(env, PGM_SPECIFICATION, ra);
>          return 0;
>      }
>  
> @@ -536,13 +536,13 @@ int pcistg_service_call(S390CPU *cpu, uint8_t r1, uint8_t r2, uintptr_t ra)
>           * A length of 0 is invalid and length should not cross a double word
>           */
>          if (!len || (len > (8 - (offset & 0x7)))) {
> -            s390_program_interrupt(env, PGM_OPERAND, 4, ra);
> +            s390_program_interrupt(env, PGM_OPERAND, ra);
>              return 0;
>          }
>  
>          result = zpci_write_bar(pbdev, pcias, offset, data, len);
>          if (result != MEMTX_OK) {
> -            s390_program_interrupt(env, PGM_OPERAND, 4, ra);
> +            s390_program_interrupt(env, PGM_OPERAND, ra);
>              return 0;
>          }
>          break;
> @@ -550,7 +550,7 @@ int pcistg_service_call(S390CPU *cpu, uint8_t r1, uint8_t r2, uintptr_t ra)
>          /* ZPCI uses the pseudo BAR number 15 as configuration space */
>          /* possible access lengths are 1,2,4 and must not cross a word */
>          if (!len || (len > (4 - (offset & 0x3))) || len == 3) {
> -            s390_program_interrupt(env, PGM_OPERAND, 4, ra);
> +            s390_program_interrupt(env, PGM_OPERAND, ra);
>              return 0;
>          }
>          /* len = 1,2,4 so we do not need to test */
> @@ -622,12 +622,12 @@ int rpcit_service_call(S390CPU *cpu, uint8_t r1, uint8_t r2, uintptr_t ra)
>      hwaddr start, end;
>  
>      if (env->psw.mask & PSW_MASK_PSTATE) {
> -        s390_program_interrupt(env, PGM_PRIVILEGED, 4, ra);
> +        s390_program_interrupt(env, PGM_PRIVILEGED, ra);
>          return 0;
>      }
>  
>      if (r2 & 0x1) {
> -        s390_program_interrupt(env, PGM_SPECIFICATION, 4, ra);
> +        s390_program_interrupt(env, PGM_SPECIFICATION, ra);
>          return 0;
>      }
>  
> @@ -709,7 +709,7 @@ int pcistb_service_call(S390CPU *cpu, uint8_t r1, uint8_t r3, uint64_t gaddr,
>      uint8_t buffer[128];
>  
>      if (env->psw.mask & PSW_MASK_PSTATE) {
> -        s390_program_interrupt(env, PGM_PRIVILEGED, 6, ra);
> +        s390_program_interrupt(env, PGM_PRIVILEGED, ra);
>          return 0;
>      }
>  
> @@ -772,7 +772,7 @@ int pcistb_service_call(S390CPU *cpu, uint8_t r1, uint8_t r3, uint64_t gaddr,
>  
>      if (!memory_region_access_valid(mr, offset, len, true,
>                                      MEMTXATTRS_UNSPECIFIED)) {
> -        s390_program_interrupt(env, PGM_OPERAND, 6, ra);
> +        s390_program_interrupt(env, PGM_OPERAND, ra);
>          return 0;
>      }
>  
> @@ -786,7 +786,7 @@ int pcistb_service_call(S390CPU *cpu, uint8_t r1, uint8_t r3, uint64_t gaddr,
>                                                ldq_p(buffer + i * 8),
>                                                MO_64, MEMTXATTRS_UNSPECIFIED);
>          if (result != MEMTX_OK) {
> -            s390_program_interrupt(env, PGM_OPERAND, 6, ra);
> +            s390_program_interrupt(env, PGM_OPERAND, ra);
>              return 0;
>          }
>      }
> @@ -797,7 +797,7 @@ int pcistb_service_call(S390CPU *cpu, uint8_t r1, uint8_t r3, uint64_t gaddr,
>      return 0;
>  
>  specification_error:
> -    s390_program_interrupt(env, PGM_SPECIFICATION, 6, ra);
> +    s390_program_interrupt(env, PGM_SPECIFICATION, ra);
>      return 0;
>  }
>  
> @@ -871,14 +871,14 @@ static int reg_ioat(CPUS390XState *env, S390PCIIOMMU *iommu, ZpciFib fib,
>      pba &= ~0xfff;
>      pal |= 0xfff;
>      if (pba > pal || pba < ZPCI_SDMA_ADDR || pal > ZPCI_EDMA_ADDR) {
> -        s390_program_interrupt(env, PGM_OPERAND, 6, ra);
> +        s390_program_interrupt(env, PGM_OPERAND, ra);
>          return -EINVAL;
>      }
>  
>      /* currently we only support designation type 1 with translation */
>      if (!(dt == ZPCI_IOTA_RTTO && t)) {
>          error_report("unsupported ioat dt %d t %d", dt, t);
> -        s390_program_interrupt(env, PGM_OPERAND, 6, ra);
> +        s390_program_interrupt(env, PGM_OPERAND, ra);
>          return -EINVAL;
>      }
>  
> @@ -1003,7 +1003,7 @@ int mpcifc_service_call(S390CPU *cpu, uint8_t r1, uint64_t fiba, uint8_t ar,
>      uint64_t cc = ZPCI_PCI_LS_OK;
>  
>      if (env->psw.mask & PSW_MASK_PSTATE) {
> -        s390_program_interrupt(env, PGM_PRIVILEGED, 6, ra);
> +        s390_program_interrupt(env, PGM_PRIVILEGED, ra);
>          return 0;
>      }
>  
> @@ -1012,7 +1012,7 @@ int mpcifc_service_call(S390CPU *cpu, uint8_t r1, uint64_t fiba, uint8_t ar,
>      fh = env->regs[r1] >> 32;
>  
>      if (fiba & 0x7) {
> -        s390_program_interrupt(env, PGM_SPECIFICATION, 6, ra);
> +        s390_program_interrupt(env, PGM_SPECIFICATION, ra);
>          return 0;
>      }
>  
> @@ -1040,7 +1040,7 @@ int mpcifc_service_call(S390CPU *cpu, uint8_t r1, uint64_t fiba, uint8_t ar,
>      }
>  
>      if (fib.fmt != 0) {
> -        s390_program_interrupt(env, PGM_OPERAND, 6, ra);
> +        s390_program_interrupt(env, PGM_OPERAND, ra);
>          return 0;
>      }
>  
> @@ -1151,7 +1151,7 @@ int mpcifc_service_call(S390CPU *cpu, uint8_t r1, uint64_t fiba, uint8_t ar,
>          break;
>      }
>      default:
> -        s390_program_interrupt(&cpu->env, PGM_OPERAND, 6, ra);
> +        s390_program_interrupt(&cpu->env, PGM_OPERAND, ra);
>          cc = ZPCI_PCI_LS_ERR;
>      }
>  
> @@ -1171,7 +1171,7 @@ int stpcifc_service_call(S390CPU *cpu, uint8_t r1, uint64_t fiba, uint8_t ar,
>      uint64_t cc = ZPCI_PCI_LS_OK;
>  
>      if (env->psw.mask & PSW_MASK_PSTATE) {
> -        s390_program_interrupt(env, PGM_PRIVILEGED, 6, ra);
> +        s390_program_interrupt(env, PGM_PRIVILEGED, ra);
>          return 0;
>      }
>  
> @@ -1185,7 +1185,7 @@ int stpcifc_service_call(S390CPU *cpu, uint8_t r1, uint64_t fiba, uint8_t ar,
>      }
>  
>      if (fiba & 0x7) {
> -        s390_program_interrupt(env, PGM_SPECIFICATION, 6, ra);
> +        s390_program_interrupt(env, PGM_SPECIFICATION, ra);
>          return 0;
>      }
>  
> diff --git a/target/s390x/cc_helper.c b/target/s390x/cc_helper.c
> index cf68792733..3cb00bcb09 100644
> --- a/target/s390x/cc_helper.c
> +++ b/target/s390x/cc_helper.c
> @@ -588,7 +588,7 @@ void HELPER(sacf)(CPUS390XState *env, uint64_t a1)
>          break;
>      default:
>          HELPER_LOG("unknown sacf mode: %" PRIx64 "\n", a1);
> -        s390_program_interrupt(env, PGM_SPECIFICATION, 2, GETPC());
> +        s390_program_interrupt(env, PGM_SPECIFICATION, GETPC());
>          break;
>      }
>  }
> diff --git a/target/s390x/crypto_helper.c b/target/s390x/crypto_helper.c
> index 5c79790187..1f83987e9d 100644
> --- a/target/s390x/crypto_helper.c
> +++ b/target/s390x/crypto_helper.c
> @@ -34,7 +34,7 @@ uint32_t HELPER(msa)(CPUS390XState *env, uint32_t r1, uint32_t r2, uint32_t r3,
>      case S390_FEAT_TYPE_PCKMO:
>      case S390_FEAT_TYPE_PCC:
>          if (mod) {
> -            s390_program_interrupt(env, PGM_SPECIFICATION, 4, ra);
> +            s390_program_interrupt(env, PGM_SPECIFICATION, ra);
>              return 0;
>          }
>          break;
> @@ -42,7 +42,7 @@ uint32_t HELPER(msa)(CPUS390XState *env, uint32_t r1, uint32_t r2, uint32_t r3,
>  
>      s390_get_feat_block(type, subfunc);
>      if (!test_be_bit(fc, subfunc)) {
> -        s390_program_interrupt(env, PGM_SPECIFICATION, 4, ra);
> +        s390_program_interrupt(env, PGM_SPECIFICATION, ra);
>          return 0;
>      }
>  
> diff --git a/target/s390x/diag.c b/target/s390x/diag.c
> index 65eabf0461..53c2f81f2a 100644
> --- a/target/s390x/diag.c
> +++ b/target/s390x/diag.c
> @@ -61,12 +61,12 @@ void handle_diag_308(CPUS390XState *env, uint64_t r1, uint64_t r3, uintptr_t ra)
>      IplParameterBlock *iplb;
>  
>      if (env->psw.mask & PSW_MASK_PSTATE) {
> -        s390_program_interrupt(env, PGM_PRIVILEGED, ILEN_AUTO, ra);
> +        s390_program_interrupt(env, PGM_PRIVILEGED, ra);
>          return;
>      }
>  
>      if ((subcode & ~0x0ffffULL) || (subcode > 6)) {
> -        s390_program_interrupt(env, PGM_SPECIFICATION, ILEN_AUTO, ra);
> +        s390_program_interrupt(env, PGM_SPECIFICATION, ra);
>          return;
>      }
>  
> @@ -82,13 +82,13 @@ void handle_diag_308(CPUS390XState *env, uint64_t r1, uint64_t r3, uintptr_t ra)
>          break;
>      case 5:
>          if ((r1 & 1) || (addr & 0x0fffULL)) {
> -            s390_program_interrupt(env, PGM_SPECIFICATION, ILEN_AUTO, ra);
> +            s390_program_interrupt(env, PGM_SPECIFICATION, ra);
>              return;
>          }
>          if (!address_space_access_valid(&address_space_memory, addr,
>                                          sizeof(IplParameterBlock), false,
>                                          MEMTXATTRS_UNSPECIFIED)) {
> -            s390_program_interrupt(env, PGM_ADDRESSING, ILEN_AUTO, ra);
> +            s390_program_interrupt(env, PGM_ADDRESSING, ra);
>              return;
>          }
>          iplb = g_new0(IplParameterBlock, 1);
> @@ -112,13 +112,13 @@ out:
>          return;
>      case 6:
>          if ((r1 & 1) || (addr & 0x0fffULL)) {
> -            s390_program_interrupt(env, PGM_SPECIFICATION, ILEN_AUTO, ra);
> +            s390_program_interrupt(env, PGM_SPECIFICATION, ra);
>              return;
>          }
>          if (!address_space_access_valid(&address_space_memory, addr,
>                                          sizeof(IplParameterBlock), true,
>                                          MEMTXATTRS_UNSPECIFIED)) {
> -            s390_program_interrupt(env, PGM_ADDRESSING, ILEN_AUTO, ra);
> +            s390_program_interrupt(env, PGM_ADDRESSING, ra);
>              return;
>          }
>          iplb = s390_ipl_get_iplb();
> @@ -130,7 +130,7 @@ out:
>          }
>          return;
>      default:
> -        s390_program_interrupt(env, PGM_SPECIFICATION, ILEN_AUTO, ra);
> +        s390_program_interrupt(env, PGM_SPECIFICATION, ra);
>          break;
>      }
>  }
> diff --git a/target/s390x/excp_helper.c b/target/s390x/excp_helper.c
> index 681a9c59e1..089623a248 100644
> --- a/target/s390x/excp_helper.c
> +++ b/target/s390x/excp_helper.c
> @@ -75,7 +75,7 @@ void QEMU_NORETURN tcg_s390_vector_exception(CPUS390XState *env, uint32_t vxc,
>  
>      /* Always store the VXC into the FPC, without AFP it is undefined */
>      env->fpc = deposit32(env->fpc, 8, 8, vxc);
> -    tcg_s390_program_interrupt(env, PGM_VECTOR_PROCESSING, ILEN_AUTO, ra);
> +    tcg_s390_program_interrupt(env, PGM_VECTOR_PROCESSING, ra);
>  }
>  
>  void HELPER(data_exception)(CPUS390XState *env, uint32_t dxc)
> @@ -614,7 +614,7 @@ void s390x_cpu_do_unaligned_access(CPUState *cs, vaddr addr,
>      S390CPU *cpu = S390_CPU(cs);
>      CPUS390XState *env = &cpu->env;
>  
> -    s390_program_interrupt(env, PGM_SPECIFICATION, ILEN_AUTO, retaddr);
> +    s390_program_interrupt(env, PGM_SPECIFICATION, retaddr);
>  }
>  
>  #endif /* CONFIG_USER_ONLY */
> diff --git a/target/s390x/fpu_helper.c b/target/s390x/fpu_helper.c
> index 5faf973c6c..7228eb96e2 100644
> --- a/target/s390x/fpu_helper.c
> +++ b/target/s390x/fpu_helper.c
> @@ -825,7 +825,7 @@ void HELPER(sfpc)(CPUS390XState *env, uint64_t fpc)
>  {
>      if (fpc_to_rnd[fpc & 0x7] == -1 || fpc & 0x03030088u ||
>          (!s390_has_feat(S390_FEAT_FLOATING_POINT_EXT) && fpc & 0x4)) {
> -        s390_program_interrupt(env, PGM_SPECIFICATION, ILEN_AUTO, GETPC());
> +        s390_program_interrupt(env, PGM_SPECIFICATION, GETPC());
>      }
>  
>      /* Install everything in the main FPC.  */
> @@ -843,7 +843,7 @@ void HELPER(sfas)(CPUS390XState *env, uint64_t fpc)
>  
>      if (fpc_to_rnd[fpc & 0x7] == -1 || fpc & 0x03030088u ||
>          (!s390_has_feat(S390_FEAT_FLOATING_POINT_EXT) && fpc & 0x4)) {
> -        s390_program_interrupt(env, PGM_SPECIFICATION, ILEN_AUTO, GETPC());
> +        s390_program_interrupt(env, PGM_SPECIFICATION, GETPC());
>      }
>  
>      /*
> @@ -880,7 +880,7 @@ void HELPER(sfas)(CPUS390XState *env, uint64_t fpc)
>  void HELPER(srnm)(CPUS390XState *env, uint64_t rnd)
>  {
>      if (rnd > 0x7 || fpc_to_rnd[rnd & 0x7] == -1) {
> -        s390_program_interrupt(env, PGM_SPECIFICATION, ILEN_AUTO, GETPC());
> +        s390_program_interrupt(env, PGM_SPECIFICATION, GETPC());
>      }
>  
>      env->fpc = deposit32(env->fpc, 0, 3, rnd);
> diff --git a/target/s390x/int_helper.c b/target/s390x/int_helper.c
> index d13cc49be6..1d29a1fc1f 100644
> --- a/target/s390x/int_helper.c
> +++ b/target/s390x/int_helper.c
> @@ -39,7 +39,7 @@ int64_t HELPER(divs32)(CPUS390XState *env, int64_t a, int64_t b64)
>      int64_t q;
>  
>      if (b == 0) {
> -        s390_program_interrupt(env, PGM_FIXPT_DIVIDE, ILEN_AUTO, GETPC());
> +        s390_program_interrupt(env, PGM_FIXPT_DIVIDE, GETPC());
>      }
>  
>      ret = q = a / b;
> @@ -47,7 +47,7 @@ int64_t HELPER(divs32)(CPUS390XState *env, int64_t a, int64_t b64)
>  
>      /* Catch non-representable quotient.  */
>      if (ret != q) {
> -        s390_program_interrupt(env, PGM_FIXPT_DIVIDE, ILEN_AUTO, GETPC());
> +        s390_program_interrupt(env, PGM_FIXPT_DIVIDE, GETPC());
>      }
>  
>      return ret;
> @@ -60,7 +60,7 @@ uint64_t HELPER(divu32)(CPUS390XState *env, uint64_t a, uint64_t b64)
>      uint64_t q;
>  
>      if (b == 0) {
> -        s390_program_interrupt(env, PGM_FIXPT_DIVIDE, ILEN_AUTO, GETPC());
> +        s390_program_interrupt(env, PGM_FIXPT_DIVIDE, GETPC());
>      }
>  
>      ret = q = a / b;
> @@ -68,7 +68,7 @@ uint64_t HELPER(divu32)(CPUS390XState *env, uint64_t a, uint64_t b64)
>  
>      /* Catch non-representable quotient.  */
>      if (ret != q) {
> -        s390_program_interrupt(env, PGM_FIXPT_DIVIDE, ILEN_AUTO, GETPC());
> +        s390_program_interrupt(env, PGM_FIXPT_DIVIDE, GETPC());
>      }
>  
>      return ret;
> @@ -79,7 +79,7 @@ int64_t HELPER(divs64)(CPUS390XState *env, int64_t a, int64_t b)
>  {
>      /* Catch divide by zero, and non-representable quotient (MIN / -1).  */
>      if (b == 0 || (b == -1 && a == (1ll << 63))) {
> -        s390_program_interrupt(env, PGM_FIXPT_DIVIDE, ILEN_AUTO, GETPC());
> +        s390_program_interrupt(env, PGM_FIXPT_DIVIDE, GETPC());
>      }
>      env->retxl = a % b;
>      return a / b;
> @@ -92,7 +92,7 @@ uint64_t HELPER(divu64)(CPUS390XState *env, uint64_t ah, uint64_t al,
>      uint64_t ret;
>      /* Signal divide by zero.  */
>      if (b == 0) {
> -        s390_program_interrupt(env, PGM_FIXPT_DIVIDE, ILEN_AUTO, GETPC());
> +        s390_program_interrupt(env, PGM_FIXPT_DIVIDE, GETPC());
>      }
>      if (ah == 0) {
>          /* 64 -> 64/64 case */
> @@ -106,7 +106,7 @@ uint64_t HELPER(divu64)(CPUS390XState *env, uint64_t ah, uint64_t al,
>          env->retxl = a % b;
>          ret = q;
>          if (ret != q) {
> -            s390_program_interrupt(env, PGM_FIXPT_DIVIDE, ILEN_AUTO, GETPC());
> +            s390_program_interrupt(env, PGM_FIXPT_DIVIDE, GETPC());
>          }
>  #else
>          /* 32-bit hosts would need special wrapper functionality - just abort if
> diff --git a/target/s390x/interrupt.c b/target/s390x/interrupt.c
> index b798e2ecbe..2b71e03914 100644
> --- a/target/s390x/interrupt.c
> +++ b/target/s390x/interrupt.c
> @@ -34,8 +34,7 @@ void trigger_pgm_exception(CPUS390XState *env, uint32_t code, uint32_t ilen)
>      }
>  }
>  
> -void s390_program_interrupt(CPUS390XState *env, uint32_t code, int ilen,
> -                            uintptr_t ra)
> +void s390_program_interrupt(CPUS390XState *env, uint32_t code, uintptr_t ra)
>  {
>      if (kvm_enabled()) {
>          kvm_s390_program_interrupt(env_archcpu(env), code);
> diff --git a/target/s390x/ioinst.c b/target/s390x/ioinst.c
> index 83c164a168..c437a1d8c6 100644
> --- a/target/s390x/ioinst.c
> +++ b/target/s390x/ioinst.c
> @@ -44,7 +44,7 @@ void ioinst_handle_xsch(S390CPU *cpu, uint64_t reg1, uintptr_t ra)
>      SubchDev *sch;
>  
>      if (ioinst_disassemble_sch_ident(reg1, &m, &cssid, &ssid, &schid)) {
> -        s390_program_interrupt(&cpu->env, PGM_OPERAND, 4, ra);
> +        s390_program_interrupt(&cpu->env, PGM_OPERAND, ra);
>          return;
>      }
>      trace_ioinst_sch_id("xsch", cssid, ssid, schid);
> @@ -62,7 +62,7 @@ void ioinst_handle_csch(S390CPU *cpu, uint64_t reg1, uintptr_t ra)
>      SubchDev *sch;
>  
>      if (ioinst_disassemble_sch_ident(reg1, &m, &cssid, &ssid, &schid)) {
> -        s390_program_interrupt(&cpu->env, PGM_OPERAND, 4, ra);
> +        s390_program_interrupt(&cpu->env, PGM_OPERAND, ra);
>          return;
>      }
>      trace_ioinst_sch_id("csch", cssid, ssid, schid);
> @@ -80,7 +80,7 @@ void ioinst_handle_hsch(S390CPU *cpu, uint64_t reg1, uintptr_t ra)
>      SubchDev *sch;
>  
>      if (ioinst_disassemble_sch_ident(reg1, &m, &cssid, &ssid, &schid)) {
> -        s390_program_interrupt(&cpu->env, PGM_OPERAND, 4, ra);
> +        s390_program_interrupt(&cpu->env, PGM_OPERAND, ra);
>          return;
>      }
>      trace_ioinst_sch_id("hsch", cssid, ssid, schid);
> @@ -116,7 +116,7 @@ void ioinst_handle_msch(S390CPU *cpu, uint64_t reg1, uint32_t ipb, uintptr_t ra)
>  
>      addr = decode_basedisp_s(env, ipb, &ar);
>      if (addr & 3) {
> -        s390_program_interrupt(env, PGM_SPECIFICATION, 4, ra);
> +        s390_program_interrupt(env, PGM_SPECIFICATION, ra);
>          return;
>      }
>      if (s390_cpu_virt_mem_read(cpu, addr, ar, &schib, sizeof(schib))) {
> @@ -125,7 +125,7 @@ void ioinst_handle_msch(S390CPU *cpu, uint64_t reg1, uint32_t ipb, uintptr_t ra)
>      }
>      if (ioinst_disassemble_sch_ident(reg1, &m, &cssid, &ssid, &schid) ||
>          !ioinst_schib_valid(&schib)) {
> -        s390_program_interrupt(env, PGM_OPERAND, 4, ra);
> +        s390_program_interrupt(env, PGM_OPERAND, ra);
>          return;
>      }
>      trace_ioinst_sch_id("msch", cssid, ssid, schid);
> @@ -173,7 +173,7 @@ void ioinst_handle_ssch(S390CPU *cpu, uint64_t reg1, uint32_t ipb, uintptr_t ra)
>  
>      addr = decode_basedisp_s(env, ipb, &ar);
>      if (addr & 3) {
> -        s390_program_interrupt(env, PGM_SPECIFICATION, 4, ra);
> +        s390_program_interrupt(env, PGM_SPECIFICATION, ra);
>          return;
>      }
>      if (s390_cpu_virt_mem_read(cpu, addr, ar, &orig_orb, sizeof(orb))) {
> @@ -183,7 +183,7 @@ void ioinst_handle_ssch(S390CPU *cpu, uint64_t reg1, uint32_t ipb, uintptr_t ra)
>      copy_orb_from_guest(&orb, &orig_orb);
>      if (ioinst_disassemble_sch_ident(reg1, &m, &cssid, &ssid, &schid) ||
>          !ioinst_orb_valid(&orb)) {
> -        s390_program_interrupt(env, PGM_OPERAND, 4, ra);
> +        s390_program_interrupt(env, PGM_OPERAND, ra);
>          return;
>      }
>      trace_ioinst_sch_id("ssch", cssid, ssid, schid);
> @@ -205,7 +205,7 @@ void ioinst_handle_stcrw(S390CPU *cpu, uint32_t ipb, uintptr_t ra)
>  
>      addr = decode_basedisp_s(env, ipb, &ar);
>      if (addr & 3) {
> -        s390_program_interrupt(env, PGM_SPECIFICATION, 4, ra);
> +        s390_program_interrupt(env, PGM_SPECIFICATION, ra);
>          return;
>      }
>  
> @@ -236,7 +236,7 @@ void ioinst_handle_stsch(S390CPU *cpu, uint64_t reg1, uint32_t ipb,
>  
>      addr = decode_basedisp_s(env, ipb, &ar);
>      if (addr & 3) {
> -        s390_program_interrupt(env, PGM_SPECIFICATION, 4, ra);
> +        s390_program_interrupt(env, PGM_SPECIFICATION, ra);
>          return;
>      }
>  
> @@ -247,7 +247,7 @@ void ioinst_handle_stsch(S390CPU *cpu, uint64_t reg1, uint32_t ipb,
>           * access execption if it is not) first.
>           */
>          if (!s390_cpu_virt_mem_check_write(cpu, addr, ar, sizeof(schib))) {
> -            s390_program_interrupt(env, PGM_OPERAND, 4, ra);
> +            s390_program_interrupt(env, PGM_OPERAND, ra);
>          } else {
>              s390_cpu_virt_mem_handle_exc(cpu, ra);
>          }
> @@ -299,13 +299,13 @@ int ioinst_handle_tsch(S390CPU *cpu, uint64_t reg1, uint32_t ipb, uintptr_t ra)
>      uint8_t ar;
>  
>      if (ioinst_disassemble_sch_ident(reg1, &m, &cssid, &ssid, &schid)) {
> -        s390_program_interrupt(env, PGM_OPERAND, 4, ra);
> +        s390_program_interrupt(env, PGM_OPERAND, ra);
>          return -EIO;
>      }
>      trace_ioinst_sch_id("tsch", cssid, ssid, schid);
>      addr = decode_basedisp_s(env, ipb, &ar);
>      if (addr & 3) {
> -        s390_program_interrupt(env, PGM_SPECIFICATION, 4, ra);
> +        s390_program_interrupt(env, PGM_SPECIFICATION, ra);
>          return -EIO;
>      }
>  
> @@ -613,7 +613,7 @@ void ioinst_handle_chsc(S390CPU *cpu, uint32_t ipb, uintptr_t ra)
>      addr = env->regs[reg];
>      /* Page boundary? */
>      if (addr & 0xfff) {
> -        s390_program_interrupt(env, PGM_SPECIFICATION, 4, ra);
> +        s390_program_interrupt(env, PGM_SPECIFICATION, ra);
>          return;
>      }
>      /*
> @@ -629,7 +629,7 @@ void ioinst_handle_chsc(S390CPU *cpu, uint32_t ipb, uintptr_t ra)
>      len = be16_to_cpu(req->len);
>      /* Length field valid? */
>      if ((len < 16) || (len > 4088) || (len & 7)) {
> -        s390_program_interrupt(env, PGM_OPERAND, 4, ra);
> +        s390_program_interrupt(env, PGM_OPERAND, ra);
>          return;
>      }
>      memset((char *)req + len, 0, TARGET_PAGE_SIZE - len);
> @@ -678,7 +678,7 @@ void ioinst_handle_schm(S390CPU *cpu, uint64_t reg1, uint64_t reg2,
>      trace_ioinst("schm");
>  
>      if (SCHM_REG1_RES(reg1)) {
> -        s390_program_interrupt(env, PGM_OPERAND, 4, ra);
> +        s390_program_interrupt(env, PGM_OPERAND, ra);
>          return;
>      }
>  
> @@ -687,7 +687,7 @@ void ioinst_handle_schm(S390CPU *cpu, uint64_t reg1, uint64_t reg2,
>      dct = SCHM_REG1_DCT(reg1);
>  
>      if (update && (reg2 & 0x000000000000001f)) {
> -        s390_program_interrupt(env, PGM_OPERAND, 4, ra);
> +        s390_program_interrupt(env, PGM_OPERAND, ra);
>          return;
>      }
>  
> @@ -700,7 +700,7 @@ void ioinst_handle_rsch(S390CPU *cpu, uint64_t reg1, uintptr_t ra)
>      SubchDev *sch;
>  
>      if (ioinst_disassemble_sch_ident(reg1, &m, &cssid, &ssid, &schid)) {
> -        s390_program_interrupt(&cpu->env, PGM_OPERAND, 4, ra);
> +        s390_program_interrupt(&cpu->env, PGM_OPERAND, ra);
>          return;
>      }
>      trace_ioinst_sch_id("rsch", cssid, ssid, schid);
> @@ -724,7 +724,7 @@ void ioinst_handle_rchp(S390CPU *cpu, uint64_t reg1, uintptr_t ra)
>      CPUS390XState *env = &cpu->env;
>  
>      if (RCHP_REG1_RES(reg1)) {
> -        s390_program_interrupt(env, PGM_OPERAND, 4, ra);
> +        s390_program_interrupt(env, PGM_OPERAND, ra);
>          return;
>      }
>  
> @@ -747,7 +747,7 @@ void ioinst_handle_rchp(S390CPU *cpu, uint64_t reg1, uintptr_t ra)
>          break;
>      default:
>          /* Invalid channel subsystem. */
> -        s390_program_interrupt(env, PGM_OPERAND, 4, ra);
> +        s390_program_interrupt(env, PGM_OPERAND, ra);
>          return;
>      }
>      setcc(cpu, cc);
> @@ -758,6 +758,6 @@ void ioinst_handle_sal(S390CPU *cpu, uint64_t reg1, uintptr_t ra)
>  {
>      /* We do not provide address limit checking, so let's suppress it. */
>      if (SAL_REG1_INVALID(reg1) || reg1 & 0x000000000000ffff) {
> -        s390_program_interrupt(&cpu->env, PGM_OPERAND, 4, ra);
> +        s390_program_interrupt(&cpu->env, PGM_OPERAND, ra);
>      }
>  }
> diff --git a/target/s390x/mem_helper.c b/target/s390x/mem_helper.c
> index 08c5cc6a99..77d2eb96d4 100644
> --- a/target/s390x/mem_helper.c
> +++ b/target/s390x/mem_helper.c
> @@ -71,7 +71,7 @@ static inline void check_alignment(CPUS390XState *env, uint64_t v,
>                                     int wordsize, uintptr_t ra)
>  {
>      if (v % wordsize) {
> -        s390_program_interrupt(env, PGM_SPECIFICATION, 6, ra);
> +        s390_program_interrupt(env, PGM_SPECIFICATION, ra);
>      }
>  }
>  
> @@ -730,7 +730,7 @@ void HELPER(srst)(CPUS390XState *env, uint32_t r1, uint32_t r2)
>  
>      /* Bits 32-55 must contain all 0.  */
>      if (env->regs[0] & 0xffffff00u) {
> -        s390_program_interrupt(env, PGM_SPECIFICATION, 6, ra);
> +        s390_program_interrupt(env, PGM_SPECIFICATION, ra);
>      }
>  
>      str = get_address(env, r2);
> @@ -767,7 +767,7 @@ void HELPER(srstu)(CPUS390XState *env, uint32_t r1, uint32_t r2)
>  
>      /* Bits 32-47 of R0 must be zero.  */
>      if (env->regs[0] & 0xffff0000u) {
> -        s390_program_interrupt(env, PGM_SPECIFICATION, 6, ra);
> +        s390_program_interrupt(env, PGM_SPECIFICATION, ra);
>      }
>  
>      str = get_address(env, r2);
> @@ -846,7 +846,7 @@ uint32_t HELPER(mvpg)(CPUS390XState *env, uint64_t r0, uint64_t r1, uint64_t r2)
>      S390Access srca, desta;
>  
>      if ((f && s) || extract64(r0, 12, 4)) {
> -        s390_program_interrupt(env, PGM_SPECIFICATION, ILEN_AUTO, GETPC());
> +        s390_program_interrupt(env, PGM_SPECIFICATION, GETPC());
>      }
>  
>      r1 = wrap_address(env, r1 & TARGET_PAGE_MASK);
> @@ -879,7 +879,7 @@ uint32_t HELPER(mvst)(CPUS390XState *env, uint32_t r1, uint32_t r2)
>      int i;
>  
>      if (env->regs[0] & 0xffffff00ull) {
> -        s390_program_interrupt(env, PGM_SPECIFICATION, ILEN_AUTO, ra);
> +        s390_program_interrupt(env, PGM_SPECIFICATION, ra);
>      }
>  
>      /*
> @@ -911,8 +911,7 @@ void HELPER(lam)(CPUS390XState *env, uint32_t r1, uint64_t a2, uint32_t r3)
>      int i;
>  
>      if (a2 & 0x3) {
> -        /* we either came here by lam or lamy, which have different lengths */
> -        s390_program_interrupt(env, PGM_SPECIFICATION, ILEN_AUTO, ra);
> +        s390_program_interrupt(env, PGM_SPECIFICATION, ra);
>      }
>  
>      for (i = r1;; i = (i + 1) % 16) {
> @@ -932,7 +931,7 @@ void HELPER(stam)(CPUS390XState *env, uint32_t r1, uint64_t a2, uint32_t r3)
>      int i;
>  
>      if (a2 & 0x3) {
> -        s390_program_interrupt(env, PGM_SPECIFICATION, 4, ra);
> +        s390_program_interrupt(env, PGM_SPECIFICATION, ra);
>      }
>  
>      for (i = r1;; i = (i + 1) % 16) {
> @@ -1888,7 +1887,7 @@ static uint32_t do_csst(CPUS390XState *env, uint32_t r3, uint64_t a1,
>      return cc;
>  
>   spec_exception:
> -    s390_program_interrupt(env, PGM_SPECIFICATION, 6, ra);
> +    s390_program_interrupt(env, PGM_SPECIFICATION, ra);
>      g_assert_not_reached();
>  }
>  
> @@ -1912,7 +1911,7 @@ void HELPER(lctlg)(CPUS390XState *env, uint32_t r1, uint64_t a2, uint32_t r3)
>      uint32_t i;
>  
>      if (src & 0x7) {
> -        s390_program_interrupt(env, PGM_SPECIFICATION, 6, ra);
> +        s390_program_interrupt(env, PGM_SPECIFICATION, ra);
>      }
>  
>      for (i = r1;; i = (i + 1) % 16) {
> @@ -1945,7 +1944,7 @@ void HELPER(lctl)(CPUS390XState *env, uint32_t r1, uint64_t a2, uint32_t r3)
>      uint32_t i;
>  
>      if (src & 0x3) {
> -        s390_program_interrupt(env, PGM_SPECIFICATION, 4, ra);
> +        s390_program_interrupt(env, PGM_SPECIFICATION, ra);
>      }
>  
>      for (i = r1;; i = (i + 1) % 16) {
> @@ -1976,7 +1975,7 @@ void HELPER(stctg)(CPUS390XState *env, uint32_t r1, uint64_t a2, uint32_t r3)
>      uint32_t i;
>  
>      if (dest & 0x7) {
> -        s390_program_interrupt(env, PGM_SPECIFICATION, 6, ra);
> +        s390_program_interrupt(env, PGM_SPECIFICATION, ra);
>      }
>  
>      for (i = r1;; i = (i + 1) % 16) {
> @@ -1996,7 +1995,7 @@ void HELPER(stctl)(CPUS390XState *env, uint32_t r1, uint64_t a2, uint32_t r3)
>      uint32_t i;
>  
>      if (dest & 0x3) {
> -        s390_program_interrupt(env, PGM_SPECIFICATION, 4, ra);
> +        s390_program_interrupt(env, PGM_SPECIFICATION, ra);
>      }
>  
>      for (i = r1;; i = (i + 1) % 16) {
> @@ -2168,7 +2167,7 @@ uint32_t HELPER(mvcs)(CPUS390XState *env, uint64_t l, uint64_t a1, uint64_t a2)
>  
>      if (!(env->psw.mask & PSW_MASK_DAT) || !(env->cregs[0] & CR0_SECONDARY) ||
>          psw_as == AS_HOME || psw_as == AS_ACCREG) {
> -        s390_program_interrupt(env, PGM_SPECIAL_OP, ILEN_AUTO, ra);
> +        s390_program_interrupt(env, PGM_SPECIAL_OP, ra);
>      }
>  
>      l = wrap_length32(env, l);
> @@ -2199,7 +2198,7 @@ uint32_t HELPER(mvcp)(CPUS390XState *env, uint64_t l, uint64_t a1, uint64_t a2)
>  
>      if (!(env->psw.mask & PSW_MASK_DAT) || !(env->cregs[0] & CR0_SECONDARY) ||
>          psw_as == AS_HOME || psw_as == AS_ACCREG) {
> -        s390_program_interrupt(env, PGM_SPECIAL_OP, ILEN_AUTO, ra);
> +        s390_program_interrupt(env, PGM_SPECIAL_OP, ra);
>      }
>  
>      l = wrap_length32(env, l);
> @@ -2226,7 +2225,7 @@ void HELPER(idte)(CPUS390XState *env, uint64_t r1, uint64_t r2, uint32_t m4)
>      uint16_t entries, i, index = 0;
>  
>      if (r2 & 0xff000) {
> -        s390_program_interrupt(env, PGM_SPECIFICATION, 4, ra);
> +        s390_program_interrupt(env, PGM_SPECIFICATION, ra);
>      }
>  
>      if (!(r2 & 0x800)) {
> @@ -2370,7 +2369,7 @@ uint64_t HELPER(lra)(CPUS390XState *env, uint64_t addr)
>  
>      /* XXX incomplete - has more corner cases */
>      if (!(env->psw.mask & PSW_MASK_64) && (addr >> 32)) {
> -        s390_program_interrupt(env, PGM_SPECIAL_OP, 2, GETPC());
> +        s390_program_interrupt(env, PGM_SPECIAL_OP, GETPC());
>      }
>  
>      old_exc = cs->exception_index;
> @@ -2539,7 +2538,7 @@ uint32_t HELPER(mvcos)(CPUS390XState *env, uint64_t dest, uint64_t src,
>                 __func__, dest, src, len);
>  
>      if (!(env->psw.mask & PSW_MASK_DAT)) {
> -        s390_program_interrupt(env, PGM_SPECIAL_OP, 6, ra);
> +        s390_program_interrupt(env, PGM_SPECIAL_OP, ra);
>      }
>  
>      /* OAC (operand access control) for the first operand -> dest */
> @@ -2570,14 +2569,14 @@ uint32_t HELPER(mvcos)(CPUS390XState *env, uint64_t dest, uint64_t src,
>      }
>  
>      if (dest_a && dest_as == AS_HOME && (env->psw.mask & PSW_MASK_PSTATE)) {
> -        s390_program_interrupt(env, PGM_SPECIAL_OP, 6, ra);
> +        s390_program_interrupt(env, PGM_SPECIAL_OP, ra);
>      }
>      if (!(env->cregs[0] & CR0_SECONDARY) &&
>          (dest_as == AS_SECONDARY || src_as == AS_SECONDARY)) {
> -        s390_program_interrupt(env, PGM_SPECIAL_OP, 6, ra);
> +        s390_program_interrupt(env, PGM_SPECIAL_OP, ra);
>      }
>      if (!psw_key_valid(env, dest_key) || !psw_key_valid(env, src_key)) {
> -        s390_program_interrupt(env, PGM_PRIVILEGED, 6, ra);
> +        s390_program_interrupt(env, PGM_PRIVILEGED, ra);
>      }
>  
>      len = wrap_length32(env, len);
> @@ -2591,7 +2590,7 @@ uint32_t HELPER(mvcos)(CPUS390XState *env, uint64_t dest, uint64_t src,
>          (env->psw.mask & PSW_MASK_PSTATE)) {
>          qemu_log_mask(LOG_UNIMP, "%s: AR-mode and PSTATE support missing\n",
>                        __func__);
> -        s390_program_interrupt(env, PGM_ADDRESSING, 6, ra);
> +        s390_program_interrupt(env, PGM_ADDRESSING, ra);
>      }
>  
>      /* FIXME: Access using correct keys and AR-mode */
> diff --git a/target/s390x/misc_helper.c b/target/s390x/misc_helper.c
> index 7530dcb8f3..9fbb37cfb9 100644
> --- a/target/s390x/misc_helper.c
> +++ b/target/s390x/misc_helper.c
> @@ -106,7 +106,7 @@ uint32_t HELPER(servc)(CPUS390XState *env, uint64_t r1, uint64_t r2)
>      int r = sclp_service_call(env, r1, r2);
>      qemu_mutex_unlock_iothread();
>      if (r < 0) {
> -        s390_program_interrupt(env, -r, 4, GETPC());
> +        s390_program_interrupt(env, -r, GETPC());
>      }
>      return r;
>  }
> @@ -143,7 +143,7 @@ void HELPER(diag)(CPUS390XState *env, uint32_t r1, uint32_t r3, uint32_t num)
>      }
>  
>      if (r) {
> -        s390_program_interrupt(env, PGM_SPECIFICATION, ILEN_AUTO, GETPC());
> +        s390_program_interrupt(env, PGM_SPECIFICATION, GETPC());
>      }
>  }
>  
> @@ -222,7 +222,7 @@ void HELPER(sckpf)(CPUS390XState *env, uint64_t r0)
>      uint32_t val = r0;
>  
>      if (val & 0xffff0000) {
> -        s390_program_interrupt(env, PGM_SPECIFICATION, 2, GETPC());
> +        s390_program_interrupt(env, PGM_SPECIFICATION, GETPC());
>      }
>      env->todpr = val;
>  }
> @@ -266,7 +266,7 @@ uint32_t HELPER(stsi)(CPUS390XState *env, uint64_t a0, uint64_t r0, uint64_t r1)
>      }
>  
>      if ((r0 & STSI_R0_RESERVED_MASK) || (r1 & STSI_R1_RESERVED_MASK)) {
> -        s390_program_interrupt(env, PGM_SPECIFICATION, 4, ra);
> +        s390_program_interrupt(env, PGM_SPECIFICATION, ra);
>      }
>  
>      if ((r0 & STSI_R0_FC_MASK) == STSI_R0_FC_CURRENT) {
> @@ -276,7 +276,7 @@ uint32_t HELPER(stsi)(CPUS390XState *env, uint64_t a0, uint64_t r0, uint64_t r1)
>      }
>  
>      if (a0 & ~TARGET_PAGE_MASK) {
> -        s390_program_interrupt(env, PGM_SPECIFICATION, 4, ra);
> +        s390_program_interrupt(env, PGM_SPECIFICATION, ra);
>      }
>  
>      /* count the cpus and split them into configured and reserved ones */
> @@ -509,7 +509,7 @@ uint32_t HELPER(tpi)(CPUS390XState *env, uint64_t addr)
>      LowCore *lowcore;
>  
>      if (addr & 0x3) {
> -        s390_program_interrupt(env, PGM_SPECIFICATION, 4, ra);
> +        s390_program_interrupt(env, PGM_SPECIFICATION, ra);
>      }
>  
>      qemu_mutex_lock_iothread();
> @@ -573,17 +573,8 @@ void HELPER(chsc)(CPUS390XState *env, uint64_t inst)
>  #ifndef CONFIG_USER_ONLY
>  void HELPER(per_check_exception)(CPUS390XState *env)
>  {
> -    uint32_t ilen;
> -
>      if (env->per_perc_atmid) {
> -        /*
> -         * FIXME: ILEN_AUTO is most probably the right thing to use. ilen
> -         * always has to match the instruction referenced in the PSW. E.g.
> -         * if a PER interrupt is triggered via EXECUTE, we have to use ilen
> -         * of EXECUTE, while per_address contains the target of EXECUTE.
> -         */
> -        ilen = get_ilen(cpu_ldub_code(env, env->per_address));
> -        s390_program_interrupt(env, PGM_PER, ilen, GETPC());
> +        s390_program_interrupt(env, PGM_PER, GETPC());
>      }
>  }
>  
> @@ -673,7 +664,7 @@ uint32_t HELPER(stfle)(CPUS390XState *env, uint64_t addr)
>      int i;
>  
>      if (addr & 0x7) {
> -        s390_program_interrupt(env, PGM_SPECIFICATION, 4, ra);
> +        s390_program_interrupt(env, PGM_SPECIFICATION, ra);
>      }
>  
>      prepare_stfl();
> @@ -746,7 +737,7 @@ void HELPER(sic)(CPUS390XState *env, uint64_t r1, uint64_t r3)
>      qemu_mutex_unlock_iothread();
>      /* css_do_sic() may actually return a PGM_xxx value to inject */
>      if (r) {
> -        s390_program_interrupt(env, -r, 4, GETPC());
> +        s390_program_interrupt(env, -r, GETPC());
>      }
>  }
>  
> 

Very nice, I think especially when these functions are called via
EXECUTE, stuff would be broken already.


Reviewed-by: David Hildenbrand <david@redhat.com>

-- 

Thanks,

David / dhildenb


^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH v3 05/18] target/s390x: Use tcg_s390_program_interrupt in TCG helpers
  2019-09-26 16:26 ` [PATCH v3 05/18] target/s390x: Use tcg_s390_program_interrupt in TCG helpers Richard Henderson
@ 2019-09-27 10:40   ` David Hildenbrand
  0 siblings, 0 replies; 49+ messages in thread
From: David Hildenbrand @ 2019-09-27 10:40 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: qemu-s390x

On 26.09.19 18:26, Richard Henderson wrote:
> Replace all uses of s390_program_interrupt within files
> that are marked CONFIG_TCG.  These are necessarily tcg-only.
> 
> This lets each of these users benefit from the QEMU_NORETURN
> attribute on tcg_s390_program_interrupt.
> 
> Acked-by: David Hildenbrand <david@redhat.com>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  target/s390x/cc_helper.c     |  4 ++--
>  target/s390x/crypto_helper.c |  7 +++----
>  target/s390x/excp_helper.c   |  2 +-
>  target/s390x/fpu_helper.c    |  6 +++---
>  target/s390x/int_helper.c    | 15 +++++++-------
>  target/s390x/mem_helper.c    | 40 ++++++++++++++++++------------------
>  target/s390x/misc_helper.c   | 18 ++++++++--------
>  7 files changed, 46 insertions(+), 46 deletions(-)
> 
> diff --git a/target/s390x/cc_helper.c b/target/s390x/cc_helper.c
> index 3cb00bcb09..44731e4a85 100644
> --- a/target/s390x/cc_helper.c
> +++ b/target/s390x/cc_helper.c
> @@ -21,6 +21,7 @@
>  #include "qemu/osdep.h"
>  #include "cpu.h"
>  #include "internal.h"
> +#include "tcg_s390x.h"
>  #include "exec/exec-all.h"
>  #include "exec/helper-proto.h"
>  #include "qemu/host-utils.h"
> @@ -588,8 +589,7 @@ void HELPER(sacf)(CPUS390XState *env, uint64_t a1)
>          break;
>      default:
>          HELPER_LOG("unknown sacf mode: %" PRIx64 "\n", a1);
> -        s390_program_interrupt(env, PGM_SPECIFICATION, GETPC());
> -        break;
> +        tcg_s390_program_interrupt(env, PGM_SPECIFICATION, GETPC());
>      }
>  }
>  #endif
> diff --git a/target/s390x/crypto_helper.c b/target/s390x/crypto_helper.c
> index 1f83987e9d..ff3fbc3950 100644
> --- a/target/s390x/crypto_helper.c
> +++ b/target/s390x/crypto_helper.c
> @@ -13,6 +13,7 @@
>  #include "qemu/osdep.h"
>  #include "qemu/main-loop.h"
>  #include "internal.h"
> +#include "tcg_s390x.h"
>  #include "exec/helper-proto.h"
>  #include "exec/exec-all.h"
>  #include "exec/cpu_ldst.h"
> @@ -34,16 +35,14 @@ uint32_t HELPER(msa)(CPUS390XState *env, uint32_t r1, uint32_t r2, uint32_t r3,
>      case S390_FEAT_TYPE_PCKMO:
>      case S390_FEAT_TYPE_PCC:
>          if (mod) {
> -            s390_program_interrupt(env, PGM_SPECIFICATION, ra);
> -            return 0;
> +            tcg_s390_program_interrupt(env, PGM_SPECIFICATION, ra);
>          }
>          break;
>      }
>  
>      s390_get_feat_block(type, subfunc);
>      if (!test_be_bit(fc, subfunc)) {
> -        s390_program_interrupt(env, PGM_SPECIFICATION, ra);
> -        return 0;
> +        tcg_s390_program_interrupt(env, PGM_SPECIFICATION, ra);
>      }
>  
>      switch (fc) {
> diff --git a/target/s390x/excp_helper.c b/target/s390x/excp_helper.c
> index 089623a248..dbff772d34 100644
> --- a/target/s390x/excp_helper.c
> +++ b/target/s390x/excp_helper.c
> @@ -614,7 +614,7 @@ void s390x_cpu_do_unaligned_access(CPUState *cs, vaddr addr,
>      S390CPU *cpu = S390_CPU(cs);
>      CPUS390XState *env = &cpu->env;
>  
> -    s390_program_interrupt(env, PGM_SPECIFICATION, retaddr);
> +    tcg_s390_program_interrupt(env, PGM_SPECIFICATION, retaddr);
>  }
>  
>  #endif /* CONFIG_USER_ONLY */
> diff --git a/target/s390x/fpu_helper.c b/target/s390x/fpu_helper.c
> index 7228eb96e2..8bb9f54fd0 100644
> --- a/target/s390x/fpu_helper.c
> +++ b/target/s390x/fpu_helper.c
> @@ -825,7 +825,7 @@ void HELPER(sfpc)(CPUS390XState *env, uint64_t fpc)
>  {
>      if (fpc_to_rnd[fpc & 0x7] == -1 || fpc & 0x03030088u ||
>          (!s390_has_feat(S390_FEAT_FLOATING_POINT_EXT) && fpc & 0x4)) {
> -        s390_program_interrupt(env, PGM_SPECIFICATION, GETPC());
> +        tcg_s390_program_interrupt(env, PGM_SPECIFICATION, GETPC());
>      }
>  
>      /* Install everything in the main FPC.  */
> @@ -843,7 +843,7 @@ void HELPER(sfas)(CPUS390XState *env, uint64_t fpc)
>  
>      if (fpc_to_rnd[fpc & 0x7] == -1 || fpc & 0x03030088u ||
>          (!s390_has_feat(S390_FEAT_FLOATING_POINT_EXT) && fpc & 0x4)) {
> -        s390_program_interrupt(env, PGM_SPECIFICATION, GETPC());
> +        tcg_s390_program_interrupt(env, PGM_SPECIFICATION, GETPC());
>      }
>  
>      /*
> @@ -880,7 +880,7 @@ void HELPER(sfas)(CPUS390XState *env, uint64_t fpc)
>  void HELPER(srnm)(CPUS390XState *env, uint64_t rnd)
>  {
>      if (rnd > 0x7 || fpc_to_rnd[rnd & 0x7] == -1) {
> -        s390_program_interrupt(env, PGM_SPECIFICATION, GETPC());
> +        tcg_s390_program_interrupt(env, PGM_SPECIFICATION, GETPC());
>      }
>  
>      env->fpc = deposit32(env->fpc, 0, 3, rnd);
> diff --git a/target/s390x/int_helper.c b/target/s390x/int_helper.c
> index 1d29a1fc1f..658507dd6d 100644
> --- a/target/s390x/int_helper.c
> +++ b/target/s390x/int_helper.c
> @@ -21,6 +21,7 @@
>  #include "qemu/osdep.h"
>  #include "cpu.h"
>  #include "internal.h"
> +#include "tcg_s390x.h"
>  #include "exec/exec-all.h"
>  #include "qemu/host-utils.h"
>  #include "exec/helper-proto.h"
> @@ -39,7 +40,7 @@ int64_t HELPER(divs32)(CPUS390XState *env, int64_t a, int64_t b64)
>      int64_t q;
>  
>      if (b == 0) {
> -        s390_program_interrupt(env, PGM_FIXPT_DIVIDE, GETPC());
> +        tcg_s390_program_interrupt(env, PGM_FIXPT_DIVIDE, GETPC());
>      }
>  
>      ret = q = a / b;
> @@ -47,7 +48,7 @@ int64_t HELPER(divs32)(CPUS390XState *env, int64_t a, int64_t b64)
>  
>      /* Catch non-representable quotient.  */
>      if (ret != q) {
> -        s390_program_interrupt(env, PGM_FIXPT_DIVIDE, GETPC());
> +        tcg_s390_program_interrupt(env, PGM_FIXPT_DIVIDE, GETPC());
>      }
>  
>      return ret;
> @@ -60,7 +61,7 @@ uint64_t HELPER(divu32)(CPUS390XState *env, uint64_t a, uint64_t b64)
>      uint64_t q;
>  
>      if (b == 0) {
> -        s390_program_interrupt(env, PGM_FIXPT_DIVIDE, GETPC());
> +        tcg_s390_program_interrupt(env, PGM_FIXPT_DIVIDE, GETPC());
>      }
>  
>      ret = q = a / b;
> @@ -68,7 +69,7 @@ uint64_t HELPER(divu32)(CPUS390XState *env, uint64_t a, uint64_t b64)
>  
>      /* Catch non-representable quotient.  */
>      if (ret != q) {
> -        s390_program_interrupt(env, PGM_FIXPT_DIVIDE, GETPC());
> +        tcg_s390_program_interrupt(env, PGM_FIXPT_DIVIDE, GETPC());
>      }
>  
>      return ret;
> @@ -79,7 +80,7 @@ int64_t HELPER(divs64)(CPUS390XState *env, int64_t a, int64_t b)
>  {
>      /* Catch divide by zero, and non-representable quotient (MIN / -1).  */
>      if (b == 0 || (b == -1 && a == (1ll << 63))) {
> -        s390_program_interrupt(env, PGM_FIXPT_DIVIDE, GETPC());
> +        tcg_s390_program_interrupt(env, PGM_FIXPT_DIVIDE, GETPC());
>      }
>      env->retxl = a % b;
>      return a / b;
> @@ -92,7 +93,7 @@ uint64_t HELPER(divu64)(CPUS390XState *env, uint64_t ah, uint64_t al,
>      uint64_t ret;
>      /* Signal divide by zero.  */
>      if (b == 0) {
> -        s390_program_interrupt(env, PGM_FIXPT_DIVIDE, GETPC());
> +        tcg_s390_program_interrupt(env, PGM_FIXPT_DIVIDE, GETPC());
>      }
>      if (ah == 0) {
>          /* 64 -> 64/64 case */
> @@ -106,7 +107,7 @@ uint64_t HELPER(divu64)(CPUS390XState *env, uint64_t ah, uint64_t al,
>          env->retxl = a % b;
>          ret = q;
>          if (ret != q) {
> -            s390_program_interrupt(env, PGM_FIXPT_DIVIDE, GETPC());
> +            tcg_s390_program_interrupt(env, PGM_FIXPT_DIVIDE, GETPC());
>          }
>  #else
>          /* 32-bit hosts would need special wrapper functionality - just abort if
> diff --git a/target/s390x/mem_helper.c b/target/s390x/mem_helper.c
> index 77d2eb96d4..7d2a652823 100644
> --- a/target/s390x/mem_helper.c
> +++ b/target/s390x/mem_helper.c
> @@ -21,6 +21,7 @@
>  #include "qemu/osdep.h"
>  #include "cpu.h"
>  #include "internal.h"
> +#include "tcg_s390x.h"
>  #include "exec/helper-proto.h"
>  #include "exec/exec-all.h"
>  #include "exec/cpu_ldst.h"
> @@ -71,7 +72,7 @@ static inline void check_alignment(CPUS390XState *env, uint64_t v,
>                                     int wordsize, uintptr_t ra)
>  {
>      if (v % wordsize) {
> -        s390_program_interrupt(env, PGM_SPECIFICATION, ra);
> +        tcg_s390_program_interrupt(env, PGM_SPECIFICATION, ra);
>      }
>  }
>  
> @@ -730,7 +731,7 @@ void HELPER(srst)(CPUS390XState *env, uint32_t r1, uint32_t r2)
>  
>      /* Bits 32-55 must contain all 0.  */
>      if (env->regs[0] & 0xffffff00u) {
> -        s390_program_interrupt(env, PGM_SPECIFICATION, ra);
> +        tcg_s390_program_interrupt(env, PGM_SPECIFICATION, ra);
>      }
>  
>      str = get_address(env, r2);
> @@ -767,7 +768,7 @@ void HELPER(srstu)(CPUS390XState *env, uint32_t r1, uint32_t r2)
>  
>      /* Bits 32-47 of R0 must be zero.  */
>      if (env->regs[0] & 0xffff0000u) {
> -        s390_program_interrupt(env, PGM_SPECIFICATION, ra);
> +        tcg_s390_program_interrupt(env, PGM_SPECIFICATION, ra);
>      }
>  
>      str = get_address(env, r2);
> @@ -846,7 +847,7 @@ uint32_t HELPER(mvpg)(CPUS390XState *env, uint64_t r0, uint64_t r1, uint64_t r2)
>      S390Access srca, desta;
>  
>      if ((f && s) || extract64(r0, 12, 4)) {
> -        s390_program_interrupt(env, PGM_SPECIFICATION, GETPC());
> +        tcg_s390_program_interrupt(env, PGM_SPECIFICATION, GETPC());
>      }
>  
>      r1 = wrap_address(env, r1 & TARGET_PAGE_MASK);
> @@ -879,7 +880,7 @@ uint32_t HELPER(mvst)(CPUS390XState *env, uint32_t r1, uint32_t r2)
>      int i;
>  
>      if (env->regs[0] & 0xffffff00ull) {
> -        s390_program_interrupt(env, PGM_SPECIFICATION, ra);
> +        tcg_s390_program_interrupt(env, PGM_SPECIFICATION, ra);
>      }
>  
>      /*
> @@ -911,7 +912,7 @@ void HELPER(lam)(CPUS390XState *env, uint32_t r1, uint64_t a2, uint32_t r3)
>      int i;
>  
>      if (a2 & 0x3) {
> -        s390_program_interrupt(env, PGM_SPECIFICATION, ra);
> +        tcg_s390_program_interrupt(env, PGM_SPECIFICATION, ra);
>      }
>  
>      for (i = r1;; i = (i + 1) % 16) {
> @@ -931,7 +932,7 @@ void HELPER(stam)(CPUS390XState *env, uint32_t r1, uint64_t a2, uint32_t r3)
>      int i;
>  
>      if (a2 & 0x3) {
> -        s390_program_interrupt(env, PGM_SPECIFICATION, ra);
> +        tcg_s390_program_interrupt(env, PGM_SPECIFICATION, ra);
>      }
>  
>      for (i = r1;; i = (i + 1) % 16) {
> @@ -1887,8 +1888,7 @@ static uint32_t do_csst(CPUS390XState *env, uint32_t r3, uint64_t a1,
>      return cc;
>  
>   spec_exception:
> -    s390_program_interrupt(env, PGM_SPECIFICATION, ra);
> -    g_assert_not_reached();
> +    tcg_s390_program_interrupt(env, PGM_SPECIFICATION, ra);
>  }
>  
>  uint32_t HELPER(csst)(CPUS390XState *env, uint32_t r3, uint64_t a1, uint64_t a2)
> @@ -1911,7 +1911,7 @@ void HELPER(lctlg)(CPUS390XState *env, uint32_t r1, uint64_t a2, uint32_t r3)
>      uint32_t i;
>  
>      if (src & 0x7) {
> -        s390_program_interrupt(env, PGM_SPECIFICATION, ra);
> +        tcg_s390_program_interrupt(env, PGM_SPECIFICATION, ra);
>      }
>  
>      for (i = r1;; i = (i + 1) % 16) {
> @@ -1944,7 +1944,7 @@ void HELPER(lctl)(CPUS390XState *env, uint32_t r1, uint64_t a2, uint32_t r3)
>      uint32_t i;
>  
>      if (src & 0x3) {
> -        s390_program_interrupt(env, PGM_SPECIFICATION, ra);
> +        tcg_s390_program_interrupt(env, PGM_SPECIFICATION, ra);
>      }
>  
>      for (i = r1;; i = (i + 1) % 16) {
> @@ -1975,7 +1975,7 @@ void HELPER(stctg)(CPUS390XState *env, uint32_t r1, uint64_t a2, uint32_t r3)
>      uint32_t i;
>  
>      if (dest & 0x7) {
> -        s390_program_interrupt(env, PGM_SPECIFICATION, ra);
> +        tcg_s390_program_interrupt(env, PGM_SPECIFICATION, ra);
>      }
>  
>      for (i = r1;; i = (i + 1) % 16) {
> @@ -1995,7 +1995,7 @@ void HELPER(stctl)(CPUS390XState *env, uint32_t r1, uint64_t a2, uint32_t r3)
>      uint32_t i;
>  
>      if (dest & 0x3) {
> -        s390_program_interrupt(env, PGM_SPECIFICATION, ra);
> +        tcg_s390_program_interrupt(env, PGM_SPECIFICATION, ra);
>      }
>  
>      for (i = r1;; i = (i + 1) % 16) {
> @@ -2225,7 +2225,7 @@ void HELPER(idte)(CPUS390XState *env, uint64_t r1, uint64_t r2, uint32_t m4)
>      uint16_t entries, i, index = 0;
>  
>      if (r2 & 0xff000) {
> -        s390_program_interrupt(env, PGM_SPECIFICATION, ra);
> +        tcg_s390_program_interrupt(env, PGM_SPECIFICATION, ra);
>      }
>  
>      if (!(r2 & 0x800)) {
> @@ -2369,7 +2369,7 @@ uint64_t HELPER(lra)(CPUS390XState *env, uint64_t addr)
>  
>      /* XXX incomplete - has more corner cases */
>      if (!(env->psw.mask & PSW_MASK_64) && (addr >> 32)) {
> -        s390_program_interrupt(env, PGM_SPECIAL_OP, GETPC());
> +        tcg_s390_program_interrupt(env, PGM_SPECIAL_OP, GETPC());
>      }
>  
>      old_exc = cs->exception_index;
> @@ -2538,7 +2538,7 @@ uint32_t HELPER(mvcos)(CPUS390XState *env, uint64_t dest, uint64_t src,
>                 __func__, dest, src, len);
>  
>      if (!(env->psw.mask & PSW_MASK_DAT)) {
> -        s390_program_interrupt(env, PGM_SPECIAL_OP, ra);
> +        tcg_s390_program_interrupt(env, PGM_SPECIAL_OP, ra);
>      }
>  
>      /* OAC (operand access control) for the first operand -> dest */
> @@ -2569,14 +2569,14 @@ uint32_t HELPER(mvcos)(CPUS390XState *env, uint64_t dest, uint64_t src,
>      }
>  
>      if (dest_a && dest_as == AS_HOME && (env->psw.mask & PSW_MASK_PSTATE)) {
> -        s390_program_interrupt(env, PGM_SPECIAL_OP, ra);
> +        tcg_s390_program_interrupt(env, PGM_SPECIAL_OP, ra);
>      }
>      if (!(env->cregs[0] & CR0_SECONDARY) &&
>          (dest_as == AS_SECONDARY || src_as == AS_SECONDARY)) {
> -        s390_program_interrupt(env, PGM_SPECIAL_OP, ra);
> +        tcg_s390_program_interrupt(env, PGM_SPECIAL_OP, ra);
>      }
>      if (!psw_key_valid(env, dest_key) || !psw_key_valid(env, src_key)) {
> -        s390_program_interrupt(env, PGM_PRIVILEGED, ra);
> +        tcg_s390_program_interrupt(env, PGM_PRIVILEGED, ra);
>      }
>  
>      len = wrap_length32(env, len);
> @@ -2590,7 +2590,7 @@ uint32_t HELPER(mvcos)(CPUS390XState *env, uint64_t dest, uint64_t src,
>          (env->psw.mask & PSW_MASK_PSTATE)) {
>          qemu_log_mask(LOG_UNIMP, "%s: AR-mode and PSTATE support missing\n",
>                        __func__);
> -        s390_program_interrupt(env, PGM_ADDRESSING, ra);
> +        tcg_s390_program_interrupt(env, PGM_ADDRESSING, ra);
>      }
>  
>      /* FIXME: Access using correct keys and AR-mode */
> diff --git a/target/s390x/misc_helper.c b/target/s390x/misc_helper.c
> index 9fbb37cfb9..bfb457fb63 100644
> --- a/target/s390x/misc_helper.c
> +++ b/target/s390x/misc_helper.c
> @@ -106,7 +106,7 @@ uint32_t HELPER(servc)(CPUS390XState *env, uint64_t r1, uint64_t r2)
>      int r = sclp_service_call(env, r1, r2);
>      qemu_mutex_unlock_iothread();
>      if (r < 0) {
> -        s390_program_interrupt(env, -r, GETPC());
> +        tcg_s390_program_interrupt(env, -r, GETPC());
>      }
>      return r;
>  }
> @@ -143,7 +143,7 @@ void HELPER(diag)(CPUS390XState *env, uint32_t r1, uint32_t r3, uint32_t num)
>      }
>  
>      if (r) {
> -        s390_program_interrupt(env, PGM_SPECIFICATION, GETPC());
> +        tcg_s390_program_interrupt(env, PGM_SPECIFICATION, GETPC());
>      }
>  }
>  
> @@ -222,7 +222,7 @@ void HELPER(sckpf)(CPUS390XState *env, uint64_t r0)
>      uint32_t val = r0;
>  
>      if (val & 0xffff0000) {
> -        s390_program_interrupt(env, PGM_SPECIFICATION, GETPC());
> +        tcg_s390_program_interrupt(env, PGM_SPECIFICATION, GETPC());
>      }
>      env->todpr = val;
>  }
> @@ -266,7 +266,7 @@ uint32_t HELPER(stsi)(CPUS390XState *env, uint64_t a0, uint64_t r0, uint64_t r1)
>      }
>  
>      if ((r0 & STSI_R0_RESERVED_MASK) || (r1 & STSI_R1_RESERVED_MASK)) {
> -        s390_program_interrupt(env, PGM_SPECIFICATION, ra);
> +        tcg_s390_program_interrupt(env, PGM_SPECIFICATION, ra);
>      }
>  
>      if ((r0 & STSI_R0_FC_MASK) == STSI_R0_FC_CURRENT) {
> @@ -276,7 +276,7 @@ uint32_t HELPER(stsi)(CPUS390XState *env, uint64_t a0, uint64_t r0, uint64_t r1)
>      }
>  
>      if (a0 & ~TARGET_PAGE_MASK) {
> -        s390_program_interrupt(env, PGM_SPECIFICATION, ra);
> +        tcg_s390_program_interrupt(env, PGM_SPECIFICATION, ra);
>      }
>  
>      /* count the cpus and split them into configured and reserved ones */
> @@ -509,7 +509,7 @@ uint32_t HELPER(tpi)(CPUS390XState *env, uint64_t addr)
>      LowCore *lowcore;
>  
>      if (addr & 0x3) {
> -        s390_program_interrupt(env, PGM_SPECIFICATION, ra);
> +        tcg_s390_program_interrupt(env, PGM_SPECIFICATION, ra);
>      }
>  
>      qemu_mutex_lock_iothread();
> @@ -574,7 +574,7 @@ void HELPER(chsc)(CPUS390XState *env, uint64_t inst)
>  void HELPER(per_check_exception)(CPUS390XState *env)
>  {
>      if (env->per_perc_atmid) {
> -        s390_program_interrupt(env, PGM_PER, GETPC());
> +        tcg_s390_program_interrupt(env, PGM_PER, GETPC());
>      }
>  }
>  
> @@ -664,7 +664,7 @@ uint32_t HELPER(stfle)(CPUS390XState *env, uint64_t addr)
>      int i;
>  
>      if (addr & 0x7) {
> -        s390_program_interrupt(env, PGM_SPECIFICATION, ra);
> +        tcg_s390_program_interrupt(env, PGM_SPECIFICATION, ra);
>      }
>  
>      prepare_stfl();
> @@ -737,7 +737,7 @@ void HELPER(sic)(CPUS390XState *env, uint64_t r1, uint64_t r3)
>      qemu_mutex_unlock_iothread();
>      /* css_do_sic() may actually return a PGM_xxx value to inject */
>      if (r) {
> -        s390_program_interrupt(env, -r, GETPC());
> +        tcg_s390_program_interrupt(env, -r, GETPC());
>      }
>  }
>  
> 

Acked-by: David Hildenbrand <david@redhat.com>

-- 

Thanks,

David / dhildenb


^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH v3 06/18] target/s390x: Push trigger_pgm_exception lower in s390_cpu_tlb_fill
  2019-09-26 16:26 ` [PATCH v3 06/18] target/s390x: Push trigger_pgm_exception lower in s390_cpu_tlb_fill Richard Henderson
@ 2019-09-27 10:41   ` David Hildenbrand
  0 siblings, 0 replies; 49+ messages in thread
From: David Hildenbrand @ 2019-09-27 10:41 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: qemu-s390x

On 26.09.19 18:26, Richard Henderson wrote:
> Delay triggering an exception until the end, after we have
> determined ultimate success or failure, and also taken into
> account whether this is a non-faulting probe.
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  target/s390x/excp_helper.c | 9 +++++++--
>  1 file changed, 7 insertions(+), 2 deletions(-)
> 
> diff --git a/target/s390x/excp_helper.c b/target/s390x/excp_helper.c
> index dbff772d34..552098be5f 100644
> --- a/target/s390x/excp_helper.c
> +++ b/target/s390x/excp_helper.c
> @@ -127,7 +127,7 @@ bool s390_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
>      CPUS390XState *env = &cpu->env;
>      target_ulong vaddr, raddr;
>      uint64_t asc;
> -    int prot, fail;
> +    int prot, fail, excp;
>  
>      qemu_log_mask(CPU_LOG_MMU, "%s: addr 0x%" VADDR_PRIx " rw %d mmu_idx %d\n",
>                    __func__, address, access_type, mmu_idx);
> @@ -141,12 +141,14 @@ bool s390_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
>              vaddr &= 0x7fffffff;
>          }
>          fail = mmu_translate(env, vaddr, access_type, asc, &raddr, &prot, true);
> +        excp = 0; /* exception already raised */
>      } else if (mmu_idx == MMU_REAL_IDX) {
>          /* 31-Bit mode */
>          if (!(env->psw.mask & PSW_MASK_64)) {
>              vaddr &= 0x7fffffff;
>          }
>          fail = mmu_translate_real(env, vaddr, access_type, &raddr, &prot);
> +        excp = 0; /* exception already raised */
>      } else {
>          g_assert_not_reached();
>      }
> @@ -159,7 +161,7 @@ bool s390_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
>          qemu_log_mask(CPU_LOG_MMU,
>                        "%s: raddr %" PRIx64 " > ram_size %" PRIx64 "\n",
>                        __func__, (uint64_t)raddr, (uint64_t)ram_size);
> -        trigger_pgm_exception(env, PGM_ADDRESSING, ILEN_AUTO);
> +        excp = PGM_ADDRESSING;
>          fail = 1;
>      }
>  
> @@ -175,6 +177,9 @@ bool s390_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
>          return false;
>      }
>  
> +    if (excp) {
> +        trigger_pgm_exception(env, excp, ILEN_AUTO);
> +    }
>      cpu_restore_state(cs, retaddr, true);
>  
>      /*
> 

Depends on what's going to follow next, but the change itself

Reviewed-by: David Hildenbrand <david@redhat.com>

-- 

Thanks,

David / dhildenb


^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH v3 07/18] target/s390x: Handle tec in s390_cpu_tlb_fill
  2019-09-26 16:26 ` [PATCH v3 07/18] target/s390x: Handle tec " Richard Henderson
@ 2019-09-27 10:42   ` David Hildenbrand
  0 siblings, 0 replies; 49+ messages in thread
From: David Hildenbrand @ 2019-09-27 10:42 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: qemu-s390x

On 26.09.19 18:26, Richard Henderson wrote:
> As a step toward moving all excption handling out of mmu_translate,
> copy handling of the LowCore tec value from trigger_access_exception
> into s390_cpu_tlb_fill.  So far this new plumbing isn't used.
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  target/s390x/excp_helper.c | 7 ++++++-
>  1 file changed, 6 insertions(+), 1 deletion(-)
> 
> diff --git a/target/s390x/excp_helper.c b/target/s390x/excp_helper.c
> index 552098be5f..ab2ed47fef 100644
> --- a/target/s390x/excp_helper.c
> +++ b/target/s390x/excp_helper.c
> @@ -126,7 +126,7 @@ bool s390_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
>      S390CPU *cpu = S390_CPU(cs);
>      CPUS390XState *env = &cpu->env;
>      target_ulong vaddr, raddr;
> -    uint64_t asc;
> +    uint64_t asc, tec;
>      int prot, fail, excp;
>  
>      qemu_log_mask(CPU_LOG_MMU, "%s: addr 0x%" VADDR_PRIx " rw %d mmu_idx %d\n",
> @@ -162,6 +162,7 @@ bool s390_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
>                        "%s: raddr %" PRIx64 " > ram_size %" PRIx64 "\n",
>                        __func__, (uint64_t)raddr, (uint64_t)ram_size);
>          excp = PGM_ADDRESSING;
> +        tec = 0; /* unused */
>          fail = 1;
>      }
>  
> @@ -178,6 +179,10 @@ bool s390_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
>      }
>  
>      if (excp) {
> +        if (excp != PGM_ADDRESSING) {
> +            stq_phys(env_cpu(env)->as,
> +                     env->psa + offsetof(LowCore, trans_exc_code), tec);
> +        }
>          trigger_pgm_exception(env, excp, ILEN_AUTO);
>      }
>      cpu_restore_state(cs, retaddr, true);
> 

Again, depends on what's going to follow next, but I have a rough idea
already :)

Reviewed-by: David Hildenbrand <david@redhat.com>

-- 

Thanks,

David / dhildenb


^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH v3 08/18] target/s390: Return exception from mmu_translate_real
  2019-09-26 16:26 ` [PATCH v3 08/18] target/s390: Return exception from mmu_translate_real Richard Henderson
@ 2019-09-27 10:44   ` David Hildenbrand
  2019-09-27 12:47     ` David Hildenbrand
  2019-09-27 16:08     ` Richard Henderson
  0 siblings, 2 replies; 49+ messages in thread
From: David Hildenbrand @ 2019-09-27 10:44 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: qemu-s390x

On 26.09.19 18:26, Richard Henderson wrote:
> Do not raise the exception directly within mmu_translate_real,
> but pass it back so that caller may do so.
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  target/s390x/internal.h    | 2 +-
>  target/s390x/excp_helper.c | 4 ++--
>  target/s390x/mmu_helper.c  | 8 ++++----
>  3 files changed, 7 insertions(+), 7 deletions(-)
> 
> diff --git a/target/s390x/internal.h b/target/s390x/internal.h
> index c243fa725b..c4388aaf23 100644
> --- a/target/s390x/internal.h
> +++ b/target/s390x/internal.h
> @@ -362,7 +362,7 @@ void probe_write_access(CPUS390XState *env, uint64_t addr, uint64_t len,
>  int mmu_translate(CPUS390XState *env, target_ulong vaddr, int rw, uint64_t asc,
>                    target_ulong *raddr, int *flags, bool exc);
>  int mmu_translate_real(CPUS390XState *env, target_ulong raddr, int rw,
> -                       target_ulong *addr, int *flags);
> +                       target_ulong *addr, int *flags, uint64_t *tec);
>  
>  
>  /* misc_helper.c */
> diff --git a/target/s390x/excp_helper.c b/target/s390x/excp_helper.c
> index ab2ed47fef..906b87c071 100644
> --- a/target/s390x/excp_helper.c
> +++ b/target/s390x/excp_helper.c
> @@ -147,8 +147,8 @@ bool s390_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
>          if (!(env->psw.mask & PSW_MASK_64)) {
>              vaddr &= 0x7fffffff;
>          }
> -        fail = mmu_translate_real(env, vaddr, access_type, &raddr, &prot);
> -        excp = 0; /* exception already raised */
> +        excp = mmu_translate_real(env, vaddr, access_type, &raddr, &prot, &tec);
> +        fail = excp;
>      } else {
>          g_assert_not_reached();
>      }
> diff --git a/target/s390x/mmu_helper.c b/target/s390x/mmu_helper.c
> index 3ef40a37a7..b783c62bd7 100644
> --- a/target/s390x/mmu_helper.c
> +++ b/target/s390x/mmu_helper.c
> @@ -523,10 +523,10 @@ void s390_cpu_virt_mem_handle_exc(S390CPU *cpu, uintptr_t ra)
>   * @param rw     0 = read, 1 = write, 2 = code fetch
>   * @param addr   the translated address is stored to this pointer
>   * @param flags  the PAGE_READ/WRITE/EXEC flags are stored to this pointer
> - * @return       0 if the translation was successful, < 0 if a fault occurred
> + * @return       0 = success, != 0, the exception to raise
>   */
>  int mmu_translate_real(CPUS390XState *env, target_ulong raddr, int rw,
> -                       target_ulong *addr, int *flags)
> +                       target_ulong *addr, int *flags, uint64_t *tec)
>  {
>      const bool lowprot_enabled = env->cregs[0] & CR0_LOWPROT;
>  
> @@ -535,8 +535,8 @@ int mmu_translate_real(CPUS390XState *env, target_ulong raddr, int rw,
>          /* see comment in mmu_translate() how this works */
>          *flags |= PAGE_WRITE_INV;
>          if (is_low_address(raddr) && rw == MMU_DATA_STORE) {
> -            trigger_access_exception(env, PGM_PROTECTION, ILEN_AUTO, 0);
> -            return -EACCES;
> +            *tec = 0;
> +            return PGM_PROTECTION;
>          }
>      }
>  
> 

Note that

[PATCH v1 2/5] s390x/mmu: Implement ESOP-2 and
access-exception-fetch/store-indication facility

also messes with the tec (which is okay), but also with the ILEN on
instruction fetches.

Apart from that

Reviewed-by: David Hildenbrand <david@redhat.com>

-- 

Thanks,

David / dhildenb


^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH v3 09/18] target/s390x: Remove exc argument to mmu_translate_asce
  2019-09-26 16:26 ` [PATCH v3 09/18] target/s390x: Remove exc argument to mmu_translate_asce Richard Henderson
@ 2019-09-27 10:45   ` David Hildenbrand
  0 siblings, 0 replies; 49+ messages in thread
From: David Hildenbrand @ 2019-09-27 10:45 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: qemu-s390x

On 26.09.19 18:26, Richard Henderson wrote:
> Now that mmu_translate_asce returns the exception instead of
> raising it, the argument is unused.
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  target/s390x/mmu_helper.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/target/s390x/mmu_helper.c b/target/s390x/mmu_helper.c
> index b783c62bd7..ed6570db62 100644
> --- a/target/s390x/mmu_helper.c
> +++ b/target/s390x/mmu_helper.c
> @@ -113,7 +113,7 @@ static inline int read_table_entry(hwaddr gaddr, uint64_t *entry)
>  
>  static int mmu_translate_asce(CPUS390XState *env, target_ulong vaddr,
>                                uint64_t asc, uint64_t asce, target_ulong *raddr,
> -                              int *flags, int rw, bool exc)
> +                              int *flags, int rw)
>  {
>      const bool edat1 = (env->cregs[0] & CR0_EDAT) &&
>                         s390_has_feat(S390_FEAT_EDAT);
> @@ -402,7 +402,7 @@ int mmu_translate(CPUS390XState *env, target_ulong vaddr, int rw, uint64_t asc,
>      }
>  
>      /* perform the DAT translation */
> -    r = mmu_translate_asce(env, vaddr, asc, asce, raddr, flags, rw, exc);
> +    r = mmu_translate_asce(env, vaddr, asc, asce, raddr, flags, rw);
>      if (unlikely(r)) {
>          if (exc) {
>              trigger_access_exception(env, r, ilen, tec);
> 

Very nice, I missed that

Reviewed-by: David Hildenbrand <david@redhat.com>

-- 

Thanks,

David / dhildenb


^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH v3 10/18] target/s390: Return exception from mmu_translate
  2019-09-26 16:26 ` [PATCH v3 10/18] target/s390: Return exception from mmu_translate Richard Henderson
@ 2019-09-27 10:55   ` David Hildenbrand
  0 siblings, 0 replies; 49+ messages in thread
From: David Hildenbrand @ 2019-09-27 10:55 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: qemu-s390x

On 26.09.19 18:26, Richard Henderson wrote:
> Do not raise the exception directly within mmu_translate,
> but pass it back so that caller may do so.
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  target/s390x/internal.h    |  2 +-
>  target/s390x/excp_helper.c |  4 ++--
>  target/s390x/mem_helper.c  | 13 ++++++++++---
>  target/s390x/mmu_helper.c  | 36 ++++++++++++++----------------------
>  4 files changed, 27 insertions(+), 28 deletions(-)
> 
> diff --git a/target/s390x/internal.h b/target/s390x/internal.h
> index c4388aaf23..c993c3ef40 100644
> --- a/target/s390x/internal.h
> +++ b/target/s390x/internal.h
> @@ -360,7 +360,7 @@ void probe_write_access(CPUS390XState *env, uint64_t addr, uint64_t len,
>  
>  /* mmu_helper.c */
>  int mmu_translate(CPUS390XState *env, target_ulong vaddr, int rw, uint64_t asc,
> -                  target_ulong *raddr, int *flags, bool exc);
> +                  target_ulong *raddr, int *flags, uint64_t *tec);
>  int mmu_translate_real(CPUS390XState *env, target_ulong raddr, int rw,
>                         target_ulong *addr, int *flags, uint64_t *tec);
>  
> diff --git a/target/s390x/excp_helper.c b/target/s390x/excp_helper.c
> index 906b87c071..6a0728b65f 100644
> --- a/target/s390x/excp_helper.c
> +++ b/target/s390x/excp_helper.c
> @@ -140,8 +140,8 @@ bool s390_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
>          if (!(env->psw.mask & PSW_MASK_64)) {
>              vaddr &= 0x7fffffff;
>          }
> -        fail = mmu_translate(env, vaddr, access_type, asc, &raddr, &prot, true);
> -        excp = 0; /* exception already raised */
> +        excp = mmu_translate(env, vaddr, access_type, asc, &raddr, &prot, &tec);
> +        fail = excp;

... so what about instruction fetches? I assume this works as designed
as we set  env->int_pgm_ilen = 2 in s390_cpu_tlb_fill() in case of
MMU_INST_FETCH. But the comment indicates that "we may remove this
entirely".

Can you paint me the big picture? :)


>      } else if (mmu_idx == MMU_REAL_IDX) {
>          /* 31-Bit mode */
>          if (!(env->psw.mask & PSW_MASK_64)) {
> diff --git a/target/s390x/mem_helper.c b/target/s390x/mem_helper.c
> index 7d2a652823..e15aa296dd 100644
> --- a/target/s390x/mem_helper.c
> +++ b/target/s390x/mem_helper.c
> @@ -2364,8 +2364,8 @@ uint64_t HELPER(lra)(CPUS390XState *env, uint64_t addr)
>      CPUState *cs = env_cpu(env);
>      uint32_t cc = 0;
>      uint64_t asc = env->psw.mask & PSW_MASK_ASC;
> -    uint64_t ret;
> -    int old_exc, flags;
> +    uint64_t ret, tec;
> +    int old_exc, flags, exc;
>  
>      /* XXX incomplete - has more corner cases */
>      if (!(env->psw.mask & PSW_MASK_64) && (addr >> 32)) {
> @@ -2373,7 +2373,14 @@ uint64_t HELPER(lra)(CPUS390XState *env, uint64_t addr)
>      }
>  
>      old_exc = cs->exception_index;
> -    if (mmu_translate(env, addr, 0, asc, &ret, &flags, true)) {
> +    exc = mmu_translate(env, addr, 0, asc, &ret, &flags, &tec);
> +    if (exc) {
> +        /*
> +         * We don't care about ILEN or TEC, as we're not going to
> +         * deliver the exception -- thus resetting exception_index below.
> +         * TODO: clean this up.
> +         */
> +        trigger_pgm_exception(env, exc, ILEN_UNWIND);

Yeah, this needs a cleanup.

>          cc = 3;
>      }
>      if (cs->exception_index == EXCP_PGM) {
> diff --git a/target/s390x/mmu_helper.c b/target/s390x/mmu_helper.c
> index ed6570db62..a9219942b1 100644
> --- a/target/s390x/mmu_helper.c
> +++ b/target/s390x/mmu_helper.c
> @@ -349,17 +349,15 @@ static void mmu_handle_skey(target_ulong addr, int rw, int *flags)
>   * @return       0 if the translation was successful, -1 if a fault occurred
>   */
>  int mmu_translate(CPUS390XState *env, target_ulong vaddr, int rw, uint64_t asc,
> -                  target_ulong *raddr, int *flags, bool exc)
> +                  target_ulong *raddr, int *flags, uint64_t *tec)
>  {
> -    /* Code accesses have an undefined ilc, let's use 2 bytes. */
> -    const int ilen = (rw == MMU_INST_FETCH) ? 2 : ILEN_AUTO;

Now I realize that this ilen currently gets overwritten in
s390_cpu_tlb_fill().

> -    uint64_t tec = (vaddr & TARGET_PAGE_MASK) | (asc >> 46) |
> -                   (rw == MMU_DATA_STORE ? FS_WRITE : FS_READ);
>      uint64_t asce;
>      int r;
>  
> -
> +    *tec = (vaddr & TARGET_PAGE_MASK) | (asc >> 46) |
> +            (rw == MMU_DATA_STORE ? FS_WRITE : FS_READ);
>      *flags = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
> +
>      if (is_low_address(vaddr & TARGET_PAGE_MASK) && lowprot_enabled(env, asc)) {
>          /*
>           * If any part of this page is currently protected, make sure the
> @@ -371,10 +369,7 @@ int mmu_translate(CPUS390XState *env, target_ulong vaddr, int rw, uint64_t asc,
>           */
>          *flags |= PAGE_WRITE_INV;
>          if (is_low_address(vaddr) && rw == MMU_DATA_STORE) {
> -            if (exc) {
> -                trigger_access_exception(env, PGM_PROTECTION, ILEN_AUTO, 0);
> -            }
> -            return -EACCES;
> +            return PGM_PROTECTION;
>          }
>      }
>  
> @@ -404,20 +399,14 @@ int mmu_translate(CPUS390XState *env, target_ulong vaddr, int rw, uint64_t asc,
>      /* perform the DAT translation */
>      r = mmu_translate_asce(env, vaddr, asc, asce, raddr, flags, rw);
>      if (unlikely(r)) {
> -        if (exc) {
> -            trigger_access_exception(env, r, ilen, tec);
> -        }
> -        return -1;
> +        return r;
>      }
>  
>      /* check for DAT protection */
>      if (unlikely(rw == MMU_DATA_STORE && !(*flags & PAGE_WRITE))) {
> -        if (exc) {
> -            /* DAT sets bit 61 only */
> -            tec |= 0x4;
> -            trigger_access_exception(env, PGM_PROTECTION, ilen, tec);
> -        }
> -        return -1;
> +        /* DAT sets bit 61 only */
> +        *tec |= 0x4;
> +        return PGM_PROTECTION;
>      }
>  
>  nodat:
> @@ -441,9 +430,12 @@ static int translate_pages(S390CPU *cpu, vaddr addr, int nr_pages,
>      int ret, i, pflags;
>  
>      for (i = 0; i < nr_pages; i++) {
> -        ret = mmu_translate(env, addr, is_write, asc, &pages[i], &pflags, true);
> +        uint64_t tec;
> +
> +        ret = mmu_translate(env, addr, is_write, asc, &pages[i], &pflags, &tec);
>          if (ret) {
> -            return ret;
> +            trigger_access_exception(env, ret, ILEN_AUTO, tec);
> +            return -EFAULT;
>          }
>          if (!address_space_access_valid(&address_space_memory, pages[i],
>                                          TARGET_PAGE_SIZE, is_write,
> 


-- 

Thanks,

David / dhildenb


^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH v3 11/18] target/s390: Return exception from translate_pages
  2019-09-26 16:26 ` [PATCH v3 11/18] target/s390: Return exception from translate_pages Richard Henderson
@ 2019-09-27 10:56   ` David Hildenbrand
  0 siblings, 0 replies; 49+ messages in thread
From: David Hildenbrand @ 2019-09-27 10:56 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: qemu-s390x

On 26.09.19 18:26, Richard Henderson wrote:
> Do not raise the exception directly within translate_pages,
> but pass it back so that caller may do so.
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  target/s390x/mmu_helper.c | 20 ++++++++++----------
>  1 file changed, 10 insertions(+), 10 deletions(-)
> 
> diff --git a/target/s390x/mmu_helper.c b/target/s390x/mmu_helper.c
> index a9219942b1..5ecd9ee87e 100644
> --- a/target/s390x/mmu_helper.c
> +++ b/target/s390x/mmu_helper.c
> @@ -423,25 +423,22 @@ nodat:
>   * the MEMOP interface.
>   */
>  static int translate_pages(S390CPU *cpu, vaddr addr, int nr_pages,
> -                           target_ulong *pages, bool is_write)
> +                           target_ulong *pages, bool is_write, uint64_t *tec)
>  {
>      uint64_t asc = cpu->env.psw.mask & PSW_MASK_ASC;
>      CPUS390XState *env = &cpu->env;
>      int ret, i, pflags;
>  
>      for (i = 0; i < nr_pages; i++) {
> -        uint64_t tec;
> -
> -        ret = mmu_translate(env, addr, is_write, asc, &pages[i], &pflags, &tec);
> +        ret = mmu_translate(env, addr, is_write, asc, &pages[i], &pflags, tec);
>          if (ret) {
> -            trigger_access_exception(env, ret, ILEN_AUTO, tec);
> -            return -EFAULT;
> +            return ret;
>          }
>          if (!address_space_access_valid(&address_space_memory, pages[i],
>                                          TARGET_PAGE_SIZE, is_write,
>                                          MEMTXATTRS_UNSPECIFIED)) {
> -            trigger_access_exception(env, PGM_ADDRESSING, ILEN_AUTO, 0);
> -            return -EFAULT;
> +            *tec = 0; /* unused */
> +            return PGM_ADDRESSING;
>          }
>          addr += TARGET_PAGE_SIZE;
>      }
> @@ -469,6 +466,7 @@ int s390_cpu_virt_mem_rw(S390CPU *cpu, vaddr laddr, uint8_t ar, void *hostbuf,
>  {
>      int currlen, nr_pages, i;
>      target_ulong *pages;
> +    uint64_t tec;
>      int ret;
>  
>      if (kvm_enabled()) {
> @@ -482,8 +480,10 @@ int s390_cpu_virt_mem_rw(S390CPU *cpu, vaddr laddr, uint8_t ar, void *hostbuf,
>                 + 1;
>      pages = g_malloc(nr_pages * sizeof(*pages));
>  
> -    ret = translate_pages(cpu, laddr, nr_pages, pages, is_write);
> -    if (ret == 0 && hostbuf != NULL) {
> +    ret = translate_pages(cpu, laddr, nr_pages, pages, is_write, &tec);
> +    if (ret) {
> +        trigger_access_exception(&cpu->env, ret, ILEN_AUTO, tec);
> +    } else if (hostbuf != NULL) {
>          /* Copy data by stepping through the area page by page */
>          for (i = 0; i < nr_pages; i++) {
>              currlen = MIN(len, TARGET_PAGE_SIZE - (laddr % TARGET_PAGE_SIZE));
> 

Reviewed-by: David Hildenbrand <david@redhat.com>

-- 

Thanks,

David / dhildenb


^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH v3 12/18] target/s390x: Remove fail variable from s390_cpu_tlb_fill
  2019-09-26 16:26 ` [PATCH v3 12/18] target/s390x: Remove fail variable from s390_cpu_tlb_fill Richard Henderson
@ 2019-09-27 10:56   ` David Hildenbrand
  0 siblings, 0 replies; 49+ messages in thread
From: David Hildenbrand @ 2019-09-27 10:56 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: qemu-s390x

On 26.09.19 18:26, Richard Henderson wrote:
> Now that excp always contains a real exception number, we can
> use that instead of a separate fail variable.  This allows a
> redundant test to be removed.
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  target/s390x/excp_helper.c | 19 +++++++------------
>  1 file changed, 7 insertions(+), 12 deletions(-)
> 
> diff --git a/target/s390x/excp_helper.c b/target/s390x/excp_helper.c
> index 6a0728b65f..98a1ee8317 100644
> --- a/target/s390x/excp_helper.c
> +++ b/target/s390x/excp_helper.c
> @@ -127,7 +127,7 @@ bool s390_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
>      CPUS390XState *env = &cpu->env;
>      target_ulong vaddr, raddr;
>      uint64_t asc, tec;
> -    int prot, fail, excp;
> +    int prot, excp;
>  
>      qemu_log_mask(CPU_LOG_MMU, "%s: addr 0x%" VADDR_PRIx " rw %d mmu_idx %d\n",
>                    __func__, address, access_type, mmu_idx);
> @@ -141,20 +141,18 @@ bool s390_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
>              vaddr &= 0x7fffffff;
>          }
>          excp = mmu_translate(env, vaddr, access_type, asc, &raddr, &prot, &tec);
> -        fail = excp;
>      } else if (mmu_idx == MMU_REAL_IDX) {
>          /* 31-Bit mode */
>          if (!(env->psw.mask & PSW_MASK_64)) {
>              vaddr &= 0x7fffffff;
>          }
>          excp = mmu_translate_real(env, vaddr, access_type, &raddr, &prot, &tec);
> -        fail = excp;
>      } else {
>          g_assert_not_reached();
>      }
>  
>      /* check out of RAM access */
> -    if (!fail &&
> +    if (!excp &&
>          !address_space_access_valid(&address_space_memory, raddr,
>                                      TARGET_PAGE_SIZE, access_type,
>                                      MEMTXATTRS_UNSPECIFIED)) {
> @@ -163,10 +161,9 @@ bool s390_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
>                        __func__, (uint64_t)raddr, (uint64_t)ram_size);
>          excp = PGM_ADDRESSING;
>          tec = 0; /* unused */
> -        fail = 1;
>      }
>  
> -    if (!fail) {
> +    if (!excp) {
>          qemu_log_mask(CPU_LOG_MMU,
>                        "%s: set tlb %" PRIx64 " -> %" PRIx64 " (%x)\n",
>                        __func__, (uint64_t)vaddr, (uint64_t)raddr, prot);
> @@ -178,13 +175,11 @@ bool s390_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
>          return false;
>      }
>  
> -    if (excp) {
> -        if (excp != PGM_ADDRESSING) {
> -            stq_phys(env_cpu(env)->as,
> -                     env->psa + offsetof(LowCore, trans_exc_code), tec);
> -        }
> -        trigger_pgm_exception(env, excp, ILEN_AUTO);
> +    if (excp != PGM_ADDRESSING) {
> +        stq_phys(env_cpu(env)->as,
> +                 env->psa + offsetof(LowCore, trans_exc_code), tec);
>      }
> +    trigger_pgm_exception(env, excp, ILEN_AUTO);
>      cpu_restore_state(cs, retaddr, true);
>  
>      /*
> 

Reviewed-by: David Hildenbrand <david@redhat.com>

-- 

Thanks,

David / dhildenb


^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH v3 13/18] target/s390x: Simplify helper_lra
  2019-09-26 16:26 ` [PATCH v3 13/18] target/s390x: Simplify helper_lra Richard Henderson
@ 2019-09-27 10:57   ` David Hildenbrand
  0 siblings, 0 replies; 49+ messages in thread
From: David Hildenbrand @ 2019-09-27 10:57 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: qemu-s390x

On 26.09.19 18:26, Richard Henderson wrote:
> We currently call trigger_pgm_exception to set cs->exception_index
> and env->int_pgm_code and then read the values back and then
> reset cs->exception_index so that the exception is not delivered.
> 
> Instead, use the exception type that we already have directly
> without ever triggering an exception that must be suppressed.
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  target/s390x/mem_helper.c | 17 +++--------------
>  1 file changed, 3 insertions(+), 14 deletions(-)
> 
> diff --git a/target/s390x/mem_helper.c b/target/s390x/mem_helper.c
> index e15aa296dd..4254548935 100644
> --- a/target/s390x/mem_helper.c
> +++ b/target/s390x/mem_helper.c
> @@ -2361,34 +2361,23 @@ void HELPER(sturg)(CPUS390XState *env, uint64_t addr, uint64_t v1)
>  /* load real address */
>  uint64_t HELPER(lra)(CPUS390XState *env, uint64_t addr)
>  {
> -    CPUState *cs = env_cpu(env);
> -    uint32_t cc = 0;
>      uint64_t asc = env->psw.mask & PSW_MASK_ASC;
>      uint64_t ret, tec;
> -    int old_exc, flags, exc;
> +    int flags, exc, cc;
>  
>      /* XXX incomplete - has more corner cases */
>      if (!(env->psw.mask & PSW_MASK_64) && (addr >> 32)) {
>          tcg_s390_program_interrupt(env, PGM_SPECIAL_OP, GETPC());
>      }
>  
> -    old_exc = cs->exception_index;
>      exc = mmu_translate(env, addr, 0, asc, &ret, &flags, &tec);
>      if (exc) {
> -        /*
> -         * We don't care about ILEN or TEC, as we're not going to
> -         * deliver the exception -- thus resetting exception_index below.
> -         * TODO: clean this up.
> -         */
> -        trigger_pgm_exception(env, exc, ILEN_UNWIND);
>          cc = 3;
> -    }
> -    if (cs->exception_index == EXCP_PGM) {
> -        ret = env->int_pgm_code | 0x80000000;
> +        ret = exc | 0x80000000;
>      } else {
> +        cc = 0;
>          ret |= addr & ~TARGET_PAGE_MASK;
>      }
> -    cs->exception_index = old_exc;
>  
>      env->cc_op = cc;
>      return ret;
> 


Much better

Reviewed-by: David Hildenbrand <david@redhat.com>

-- 

Thanks,

David / dhildenb


^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH v3 14/18] target/s390x: Rely on unwinding in s390_cpu_tlb_fill
  2019-09-26 16:26 ` [PATCH v3 14/18] target/s390x: Rely on unwinding in s390_cpu_tlb_fill Richard Henderson
@ 2019-09-27 11:02   ` David Hildenbrand
  2019-09-27 16:16     ` Richard Henderson
  0 siblings, 1 reply; 49+ messages in thread
From: David Hildenbrand @ 2019-09-27 11:02 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: qemu-s390x

On 26.09.19 18:26, Richard Henderson wrote:
> We currently set ilen to AUTO, then overwrite that during
> unwinding, then overwrite that for the code access case.
> 
> This can be simplified to setting ilen to our arbitrary
> value for the (undefined) code access case, then rely on
> unwinding to overwrite that with the correct value for
> the data access case.
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  target/s390x/excp_helper.c | 23 +++++++----------------
>  1 file changed, 7 insertions(+), 16 deletions(-)
> 
> diff --git a/target/s390x/excp_helper.c b/target/s390x/excp_helper.c
> index 98a1ee8317..8ce992e639 100644
> --- a/target/s390x/excp_helper.c
> +++ b/target/s390x/excp_helper.c
> @@ -96,7 +96,7 @@ bool s390_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
>  {
>      S390CPU *cpu = S390_CPU(cs);
>  
> -    trigger_pgm_exception(&cpu->env, PGM_ADDRESSING, ILEN_AUTO);
> +    trigger_pgm_exception(&cpu->env, PGM_ADDRESSING, ILEN_UNWIND);

Hmm, we always trigger a pgm exceptions, meaning we set
cs->exception_index even if we have probe = true. Confused by that.

>      /* On real machines this value is dropped into LowMem.  Since this
>         is userland, simply put this someplace that cpu_loop can find it.  */
>      cpu->env.__excp_addr = address;
> @@ -179,24 +179,15 @@ bool s390_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
>          stq_phys(env_cpu(env)->as,
>                   env->psa + offsetof(LowCore, trans_exc_code), tec);
>      }
> -    trigger_pgm_exception(env, excp, ILEN_AUTO);
> -    cpu_restore_state(cs, retaddr, true);
>  
>      /*
> -     * The ILC value for code accesses is undefined.  The important
> -     * thing here is to *not* leave env->int_pgm_ilen set to ILEN_AUTO,
> -     * which would cause do_program_interrupt to attempt to read from
> -     * env->psw.addr again.  C.f. the condition in trigger_page_fault,
> -     * but is not universally applied.
> -     *
> -     * ??? If we remove ILEN_AUTO, by moving the computation of ILEN
> -     * into cpu_restore_state, then we may remove this entirely.
> +     * For data accesses, ILEN will be filled in from the unwind info,
> +     * within cpu_loop_exit_restore.  For code accesses, retaddr == 0,
> +     * and so unwinding will not occur.  However, ILEN is also undefined
> +     * for that case -- we choose to set ILEN = 2.
>       */
> -    if (access_type == MMU_INST_FETCH) {
> -        env->int_pgm_ilen = 2;
> -    }
> -
> -    cpu_loop_exit(cs);
> +    trigger_pgm_exception(env, excp, 2);

I wonder if it is still worth setting this only conditionally. Most
probably not.

> +    cpu_loop_exit_restore(cs, retaddr);
>  }
>  
>  static void do_program_interrupt(CPUS390XState *env)
> 


-- 

Thanks,

David / dhildenb


^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH v3 15/18] target/s390x: Rely on unwinding in s390_cpu_virt_mem_rw
  2019-09-26 16:26 ` [PATCH v3 15/18] target/s390x: Rely on unwinding in s390_cpu_virt_mem_rw Richard Henderson
@ 2019-09-27 11:04   ` David Hildenbrand
  0 siblings, 0 replies; 49+ messages in thread
From: David Hildenbrand @ 2019-09-27 11:04 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: qemu-s390x

On 26.09.19 18:26, Richard Henderson wrote:
> For TCG, we will always call s390_cpu_virt_mem_handle_exc,
> which will go through the unwinder to set ILEN.  For KVM,
> we do not go through do_program_interrupt, so this argument
> is unused.
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  target/s390x/mmu_helper.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/target/s390x/mmu_helper.c b/target/s390x/mmu_helper.c
> index 5ecd9ee87e..bf7fddb056 100644
> --- a/target/s390x/mmu_helper.c
> +++ b/target/s390x/mmu_helper.c
> @@ -482,7 +482,7 @@ int s390_cpu_virt_mem_rw(S390CPU *cpu, vaddr laddr, uint8_t ar, void *hostbuf,
>  
>      ret = translate_pages(cpu, laddr, nr_pages, pages, is_write, &tec);
>      if (ret) {
> -        trigger_access_exception(&cpu->env, ret, ILEN_AUTO, tec);
> +        trigger_access_exception(&cpu->env, ret, ILEN_UNWIND, tec);
>      } else if (hostbuf != NULL) {
>          /* Copy data by stepping through the area page by page */
>          for (i = 0; i < nr_pages; i++) {
> 

Reviewed-by: David Hildenbrand <david@redhat.com>

-- 

Thanks,

David / dhildenb


^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH v3 16/18] target/s390x: Remove ILEN_AUTO
  2019-09-26 16:26 ` [PATCH v3 16/18] target/s390x: Remove ILEN_AUTO Richard Henderson
@ 2019-09-27 11:04   ` David Hildenbrand
  0 siblings, 0 replies; 49+ messages in thread
From: David Hildenbrand @ 2019-09-27 11:04 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: qemu-s390x

On 26.09.19 18:26, Richard Henderson wrote:
> This setting is no longer used.
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  target/s390x/cpu.h         | 2 --
>  target/s390x/excp_helper.c | 3 ---
>  2 files changed, 5 deletions(-)
> 
> diff --git a/target/s390x/cpu.h b/target/s390x/cpu.h
> index a5eab491cd..fc941c7d76 100644
> --- a/target/s390x/cpu.h
> +++ b/target/s390x/cpu.h
> @@ -816,8 +816,6 @@ void s390_io_interrupt(uint16_t subchannel_id, uint16_t subchannel_nr,
>                         uint32_t io_int_parm, uint32_t io_int_word);
>  /* instruction length set by unwind info */
>  #define ILEN_UNWIND                 0
> -/* automatically detect the instruction length */
> -#define ILEN_AUTO                   0xff
>  #define RA_IGNORED                  0
>  void s390_program_interrupt(CPUS390XState *env, uint32_t code, uintptr_t ra);
>  /* service interrupts are floating therefore we must not pass an cpustate */
> diff --git a/target/s390x/excp_helper.c b/target/s390x/excp_helper.c
> index 8ce992e639..c252e9a7d8 100644
> --- a/target/s390x/excp_helper.c
> +++ b/target/s390x/excp_helper.c
> @@ -196,9 +196,6 @@ static void do_program_interrupt(CPUS390XState *env)
>      LowCore *lowcore;
>      int ilen = env->int_pgm_ilen;
>  
> -    if (ilen == ILEN_AUTO) {
> -        ilen = get_ilen(cpu_ldub_code(env, env->psw.addr));
> -    }
>      assert(ilen == 2 || ilen == 4 || ilen == 6);
>  
>      switch (env->int_pgm_code) {
> 

Reviewed-by: David Hildenbrand <david@redhat.com>

-- 

Thanks,

David / dhildenb


^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH v3 17/18] target/s390x: Remove ilen argument from trigger_access_exception
  2019-09-26 16:26 ` [PATCH v3 17/18] target/s390x: Remove ilen argument from trigger_access_exception Richard Henderson
@ 2019-09-27 11:04   ` David Hildenbrand
  0 siblings, 0 replies; 49+ messages in thread
From: David Hildenbrand @ 2019-09-27 11:04 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: qemu-s390x

On 26.09.19 18:26, Richard Henderson wrote:
> The single caller passes ILEN_UNWIND; pass that along to
> trigger_pgm_exception directly.
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  target/s390x/mmu_helper.c | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)
> 
> diff --git a/target/s390x/mmu_helper.c b/target/s390x/mmu_helper.c
> index bf7fddb056..e6c3139c57 100644
> --- a/target/s390x/mmu_helper.c
> +++ b/target/s390x/mmu_helper.c
> @@ -33,7 +33,7 @@
>  #define FS_WRITE 0x400
>  
>  static void trigger_access_exception(CPUS390XState *env, uint32_t type,
> -                                     uint32_t ilen, uint64_t tec)
> +                                     uint64_t tec)
>  {
>      S390CPU *cpu = env_archcpu(env);
>  
> @@ -44,7 +44,7 @@ static void trigger_access_exception(CPUS390XState *env, uint32_t type,
>          if (type != PGM_ADDRESSING) {
>              stq_phys(cs->as, env->psa + offsetof(LowCore, trans_exc_code), tec);
>          }
> -        trigger_pgm_exception(env, type, ilen);
> +        trigger_pgm_exception(env, type, ILEN_UNWIND);
>      }
>  }
>  
> @@ -482,7 +482,7 @@ int s390_cpu_virt_mem_rw(S390CPU *cpu, vaddr laddr, uint8_t ar, void *hostbuf,
>  
>      ret = translate_pages(cpu, laddr, nr_pages, pages, is_write, &tec);
>      if (ret) {
> -        trigger_access_exception(&cpu->env, ret, ILEN_UNWIND, tec);
> +        trigger_access_exception(&cpu->env, ret, tec);
>      } else if (hostbuf != NULL) {
>          /* Copy data by stepping through the area page by page */
>          for (i = 0; i < nr_pages; i++) {
> 

Reviewed-by: David Hildenbrand <david@redhat.com>

-- 

Thanks,

David / dhildenb


^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH v3 18/18] target/s390x: Remove ilen argument from trigger_pgm_exception
  2019-09-26 16:26 ` [PATCH v3 18/18] target/s390x: Remove ilen argument from trigger_pgm_exception Richard Henderson
@ 2019-09-27 11:05   ` David Hildenbrand
  0 siblings, 0 replies; 49+ messages in thread
From: David Hildenbrand @ 2019-09-27 11:05 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: qemu-s390x

On 26.09.19 18:26, Richard Henderson wrote:
> All but one caller passes ILEN_UNWIND, which is not stored.
> For the one use case in s390_cpu_tlb_fill, set int_pgm_ilen
> directly, simply to avoid the assert within do_program_interrupt.
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  target/s390x/internal.h    | 2 +-
>  target/s390x/excp_helper.c | 7 ++++---
>  target/s390x/interrupt.c   | 7 ++-----
>  target/s390x/mmu_helper.c  | 2 +-
>  4 files changed, 8 insertions(+), 10 deletions(-)
> 
> diff --git a/target/s390x/internal.h b/target/s390x/internal.h
> index c993c3ef40..d37816104d 100644
> --- a/target/s390x/internal.h
> +++ b/target/s390x/internal.h
> @@ -317,7 +317,7 @@ void cpu_unmap_lowcore(LowCore *lowcore);
>  
>  
>  /* interrupt.c */
> -void trigger_pgm_exception(CPUS390XState *env, uint32_t code, uint32_t ilen);
> +void trigger_pgm_exception(CPUS390XState *env, uint32_t code);
>  void cpu_inject_clock_comparator(S390CPU *cpu);
>  void cpu_inject_cpu_timer(S390CPU *cpu);
>  void cpu_inject_emergency_signal(S390CPU *cpu, uint16_t src_cpu_addr);
> diff --git a/target/s390x/excp_helper.c b/target/s390x/excp_helper.c
> index c252e9a7d8..e70c20d363 100644
> --- a/target/s390x/excp_helper.c
> +++ b/target/s390x/excp_helper.c
> @@ -42,7 +42,7 @@ void QEMU_NORETURN tcg_s390_program_interrupt(CPUS390XState *env,
>      cpu_restore_state(cs, ra, true);
>      qemu_log_mask(CPU_LOG_INT, "program interrupt at %#" PRIx64 "\n",
>                    env->psw.addr);
> -    trigger_pgm_exception(env, code, ILEN_UNWIND);
> +    trigger_pgm_exception(env, code);
>      cpu_loop_exit(cs);
>  }
>  
> @@ -96,7 +96,7 @@ bool s390_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
>  {
>      S390CPU *cpu = S390_CPU(cs);
>  
> -    trigger_pgm_exception(&cpu->env, PGM_ADDRESSING, ILEN_UNWIND);
> +    trigger_pgm_exception(&cpu->env, PGM_ADDRESSING);
>      /* On real machines this value is dropped into LowMem.  Since this
>         is userland, simply put this someplace that cpu_loop can find it.  */
>      cpu->env.__excp_addr = address;
> @@ -186,7 +186,8 @@ bool s390_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
>       * and so unwinding will not occur.  However, ILEN is also undefined
>       * for that case -- we choose to set ILEN = 2.
>       */
> -    trigger_pgm_exception(env, excp, 2);
> +    env->int_pgm_ilen = 2;
> +    trigger_pgm_exception(env, excp);
>      cpu_loop_exit_restore(cs, retaddr);
>  }
>  
> diff --git a/target/s390x/interrupt.c b/target/s390x/interrupt.c
> index 2b71e03914..4cdbbc8849 100644
> --- a/target/s390x/interrupt.c
> +++ b/target/s390x/interrupt.c
> @@ -22,16 +22,13 @@
>  #endif
>  
>  /* Ensure to exit the TB after this call! */
> -void trigger_pgm_exception(CPUS390XState *env, uint32_t code, uint32_t ilen)
> +void trigger_pgm_exception(CPUS390XState *env, uint32_t code)
>  {
>      CPUState *cs = env_cpu(env);
>  
>      cs->exception_index = EXCP_PGM;
>      env->int_pgm_code = code;
> -    /* If ILEN_UNWIND, int_pgm_ilen already has the correct value.  */
> -    if (ilen != ILEN_UNWIND) {
> -        env->int_pgm_ilen = ilen;
> -    }
> +    /* env->int_pgm_ilen is already set, or will be set during unwinding */
>  }
>  
>  void s390_program_interrupt(CPUS390XState *env, uint32_t code, uintptr_t ra)
> diff --git a/target/s390x/mmu_helper.c b/target/s390x/mmu_helper.c
> index e6c3139c57..ba02d33e86 100644
> --- a/target/s390x/mmu_helper.c
> +++ b/target/s390x/mmu_helper.c
> @@ -44,7 +44,7 @@ static void trigger_access_exception(CPUS390XState *env, uint32_t type,
>          if (type != PGM_ADDRESSING) {
>              stq_phys(cs->as, env->psa + offsetof(LowCore, trans_exc_code), tec);
>          }
> -        trigger_pgm_exception(env, type, ILEN_UNWIND);
> +        trigger_pgm_exception(env, type);
>      }
>  }
>  
> 

Reviewed-by: David Hildenbrand <david@redhat.com>

-- 

Thanks,

David / dhildenb


^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH v3 08/18] target/s390: Return exception from mmu_translate_real
  2019-09-27 10:44   ` David Hildenbrand
@ 2019-09-27 12:47     ` David Hildenbrand
  2019-09-27 16:08     ` Richard Henderson
  1 sibling, 0 replies; 49+ messages in thread
From: David Hildenbrand @ 2019-09-27 12:47 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: qemu-s390x

On 27.09.19 12:44, David Hildenbrand wrote:
> On 26.09.19 18:26, Richard Henderson wrote:
>> Do not raise the exception directly within mmu_translate_real,
>> but pass it back so that caller may do so.
>>
>> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
>> ---
>>  target/s390x/internal.h    | 2 +-
>>  target/s390x/excp_helper.c | 4 ++--
>>  target/s390x/mmu_helper.c  | 8 ++++----
>>  3 files changed, 7 insertions(+), 7 deletions(-)
>>
>> diff --git a/target/s390x/internal.h b/target/s390x/internal.h
>> index c243fa725b..c4388aaf23 100644
>> --- a/target/s390x/internal.h
>> +++ b/target/s390x/internal.h
>> @@ -362,7 +362,7 @@ void probe_write_access(CPUS390XState *env, uint64_t addr, uint64_t len,
>>  int mmu_translate(CPUS390XState *env, target_ulong vaddr, int rw, uint64_t asc,
>>                    target_ulong *raddr, int *flags, bool exc);
>>  int mmu_translate_real(CPUS390XState *env, target_ulong raddr, int rw,
>> -                       target_ulong *addr, int *flags);
>> +                       target_ulong *addr, int *flags, uint64_t *tec);
>>  
>>  
>>  /* misc_helper.c */
>> diff --git a/target/s390x/excp_helper.c b/target/s390x/excp_helper.c
>> index ab2ed47fef..906b87c071 100644
>> --- a/target/s390x/excp_helper.c
>> +++ b/target/s390x/excp_helper.c
>> @@ -147,8 +147,8 @@ bool s390_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
>>          if (!(env->psw.mask & PSW_MASK_64)) {
>>              vaddr &= 0x7fffffff;
>>          }
>> -        fail = mmu_translate_real(env, vaddr, access_type, &raddr, &prot);
>> -        excp = 0; /* exception already raised */
>> +        excp = mmu_translate_real(env, vaddr, access_type, &raddr, &prot, &tec);
>> +        fail = excp;
>>      } else {
>>          g_assert_not_reached();
>>      }
>> diff --git a/target/s390x/mmu_helper.c b/target/s390x/mmu_helper.c
>> index 3ef40a37a7..b783c62bd7 100644
>> --- a/target/s390x/mmu_helper.c
>> +++ b/target/s390x/mmu_helper.c
>> @@ -523,10 +523,10 @@ void s390_cpu_virt_mem_handle_exc(S390CPU *cpu, uintptr_t ra)
>>   * @param rw     0 = read, 1 = write, 2 = code fetch
>>   * @param addr   the translated address is stored to this pointer
>>   * @param flags  the PAGE_READ/WRITE/EXEC flags are stored to this pointer
>> - * @return       0 if the translation was successful, < 0 if a fault occurred
>> + * @return       0 = success, != 0, the exception to raise
>>   */
>>  int mmu_translate_real(CPUS390XState *env, target_ulong raddr, int rw,
>> -                       target_ulong *addr, int *flags)
>> +                       target_ulong *addr, int *flags, uint64_t *tec)
>>  {
>>      const bool lowprot_enabled = env->cregs[0] & CR0_LOWPROT;
>>  
>> @@ -535,8 +535,8 @@ int mmu_translate_real(CPUS390XState *env, target_ulong raddr, int rw,
>>          /* see comment in mmu_translate() how this works */
>>          *flags |= PAGE_WRITE_INV;
>>          if (is_low_address(raddr) && rw == MMU_DATA_STORE) {
>> -            trigger_access_exception(env, PGM_PROTECTION, ILEN_AUTO, 0);
>> -            return -EACCES;
>> +            *tec = 0;
>> +            return PGM_PROTECTION;
>>          }
>>      }
>>  
>>
> 
> Note that
> 
> [PATCH v1 2/5] s390x/mmu: Implement ESOP-2 and
> access-exception-fetch/store-indication facility
> 
> also messes with the tec (which is okay), but also with the ILEN on
> instruction fetches.

I'll drop the ilen change from that patch, now that I figured out how it
works :)

-- 

Thanks,

David / dhildenb


^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH v3 02/18] target/s390x: Add ilen to unwind data
  2019-09-27 10:30   ` David Hildenbrand
@ 2019-09-27 16:02     ` Richard Henderson
  2019-09-30  7:55       ` David Hildenbrand
  0 siblings, 1 reply; 49+ messages in thread
From: Richard Henderson @ 2019-09-27 16:02 UTC (permalink / raw)
  To: David Hildenbrand, qemu-devel; +Cc: qemu-s390x, Richard Henderson

On 9/27/19 3:30 AM, David Hildenbrand wrote:
>> +    /* Update ILEN, except for breakpoint, where we didn't load an insn.  */
>> +    if (ilen) {
>> +        env->int_pgm_ilen = ilen;
>> +    }
> 
> I am not completely sure about breakpoint handling and which
> implications we'll have when not setting int_pgm_ilen ...

Yeah.  Possibly to make it simple I should simply assign 2 as the length of a
breakpoint, bearing in mind that there is no a s390 exception to be delivered
-- this is purely a qemu-internal thing, raising EXCP_DEBUG to get back to the
gdbstub interface.

> I wonder if that change can help to better handle exceptions during
> EXECUTE, whereby we have to indicate the EXECUTE instruction and the
> ilen of the EXECUTE instruction (so the pc and ilen of the original
> EXECUTE function, not of the EXECUTE target).

Yes, that's already there.  The ilen of the execute insn is placed in the low 4
bits of env->ex_value, and that's what we record as ilen within extract_insn().

> I don't completely like the current interrupt handling when we have
> "env->ex_value" in "s390_cpu_exec_interrupt()". I'd love to see that
> check go, then we can reuse that function easily e.g., in MVC to test
> and inject exceptions while processing such an interruptible instruction
> - like MVC.

I don't think that reusing s390_cpu_exec_interrupt directly is a good idea.
There's other cleanup that needs to happen when exiting a TB.

What I think you should do instead is check env_neg(env)->icount_decr, exactly
like we do at the start of every basic block, and use that as an indication
that you should exit back to the main loop.


r~


^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH v3 08/18] target/s390: Return exception from mmu_translate_real
  2019-09-27 10:44   ` David Hildenbrand
  2019-09-27 12:47     ` David Hildenbrand
@ 2019-09-27 16:08     ` Richard Henderson
  1 sibling, 0 replies; 49+ messages in thread
From: Richard Henderson @ 2019-09-27 16:08 UTC (permalink / raw)
  To: David Hildenbrand, qemu-devel; +Cc: qemu-s390x

On 9/27/19 3:44 AM, David Hildenbrand wrote:
> Note that
> 
> [PATCH v1 2/5] s390x/mmu: Implement ESOP-2 and
> access-exception-fetch/store-indication facility
> 
> also messes with the tec (which is okay), but also with the ILEN on
> instruction fetches.

Yes, I saw that minor conflict.  Easy to fix up.


r~


^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH v3 14/18] target/s390x: Rely on unwinding in s390_cpu_tlb_fill
  2019-09-27 11:02   ` David Hildenbrand
@ 2019-09-27 16:16     ` Richard Henderson
  2019-09-30  7:56       ` David Hildenbrand
  0 siblings, 1 reply; 49+ messages in thread
From: Richard Henderson @ 2019-09-27 16:16 UTC (permalink / raw)
  To: David Hildenbrand, qemu-devel; +Cc: qemu-s390x

On 9/27/19 4:02 AM, David Hildenbrand wrote:
> On 26.09.19 18:26, Richard Henderson wrote:
>> We currently set ilen to AUTO, then overwrite that during
>> unwinding, then overwrite that for the code access case.
>>
>> This can be simplified to setting ilen to our arbitrary
>> value for the (undefined) code access case, then rely on
>> unwinding to overwrite that with the correct value for
>> the data access case.
>>
>> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
>> ---
>>  target/s390x/excp_helper.c | 23 +++++++----------------
>>  1 file changed, 7 insertions(+), 16 deletions(-)
>>
>> diff --git a/target/s390x/excp_helper.c b/target/s390x/excp_helper.c
>> index 98a1ee8317..8ce992e639 100644
>> --- a/target/s390x/excp_helper.c
>> +++ b/target/s390x/excp_helper.c
>> @@ -96,7 +96,7 @@ bool s390_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
>>  {
>>      S390CPU *cpu = S390_CPU(cs);
>>  
>> -    trigger_pgm_exception(&cpu->env, PGM_ADDRESSING, ILEN_AUTO);
>> +    trigger_pgm_exception(&cpu->env, PGM_ADDRESSING, ILEN_UNWIND);
> 
> Hmm, we always trigger a pgm exceptions, meaning we set
> cs->exception_index even if we have probe = true. Confused by that.

This is the CONFIG_USER_ONLY version, for which probe is always false.  Perhaps
I shouldn't have made the function interface identical, but it did appear to
make things cleaner for most targets.

>> +    trigger_pgm_exception(env, excp, 2);
> 
> I wonder if it is still worth setting this only conditionally. Most
> probably not.

I don't see that it would be.  I hope the comment is clear about this arbitrary
value is overwritten during unwinding.


r~


^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH v3 01/18] target/s390x: Truncate 32-bit psw_addr before creating TB
  2019-09-27 10:23   ` David Hildenbrand
@ 2019-09-27 18:24     ` Richard Henderson
  0 siblings, 0 replies; 49+ messages in thread
From: Richard Henderson @ 2019-09-27 18:24 UTC (permalink / raw)
  To: David Hildenbrand, qemu-devel; +Cc: qemu-s390x

On 9/27/19 3:23 AM, David Hildenbrand wrote:
>> +    pc = env->psw.addr;
>> +    if (!(flags & FLAG_MASK_64)) {
>> +        pc &= 0x7fffffff;
>> +    }
> 
> If you're fancy, you could also add 24-bit addressing mode wrapping.
> 
> Maybe unlikely(!(flags & FLAG_MASK_64)), but not sure how big the gain
> will actually be.

So, it appears that this patch, and the existing code in
s390x_tr_init_disas_context, are wrong.

Page 4-7 of the v11 PoO says that we must generate a specification exception
and not wrap.  I believe that the only way to force this to happen is with an
explicit LOAD PSW EXTENDED instruction.  Branches and sequential instruction
execution both wrap the addresses before writing back to the PSW.

I will drop this patch for now and we'll look again at instruction address later.


r~


^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH v3 02/18] target/s390x: Add ilen to unwind data
  2019-09-27 16:02     ` Richard Henderson
@ 2019-09-30  7:55       ` David Hildenbrand
  2019-09-30 15:03         ` Richard Henderson
  0 siblings, 1 reply; 49+ messages in thread
From: David Hildenbrand @ 2019-09-30  7:55 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: qemu-s390x, Richard Henderson

On 27.09.19 18:02, Richard Henderson wrote:
> On 9/27/19 3:30 AM, David Hildenbrand wrote:
>>> +    /* Update ILEN, except for breakpoint, where we didn't load an insn.  */
>>> +    if (ilen) {
>>> +        env->int_pgm_ilen = ilen;
>>> +    }
>>
>> I am not completely sure about breakpoint handling and which
>> implications we'll have when not setting int_pgm_ilen ...
> 
> Yeah.  Possibly to make it simple I should simply assign 2 as the length of a
> breakpoint, bearing in mind that there is no a s390 exception to be delivered
> -- this is purely a qemu-internal thing, raising EXCP_DEBUG to get back to the
> gdbstub interface.
> 
>> I wonder if that change can help to better handle exceptions during
>> EXECUTE, whereby we have to indicate the EXECUTE instruction and the
>> ilen of the EXECUTE instruction (so the pc and ilen of the original
>> EXECUTE function, not of the EXECUTE target).
> 
> Yes, that's already there.  The ilen of the execute insn is placed in the low 4
> bits of env->ex_value, and that's what we record as ilen within extract_insn().

Ah, good to know. I'll have to review PGM injection, which ILEN we
currently indicate and which one we are supposed to indicate.

> 
>> I don't completely like the current interrupt handling when we have
>> "env->ex_value" in "s390_cpu_exec_interrupt()". I'd love to see that
>> check go, then we can reuse that function easily e.g., in MVC to test
>> and inject exceptions while processing such an interruptible instruction
>> - like MVC.
> 
> I don't think that reusing s390_cpu_exec_interrupt directly is a good idea.
> There's other cleanup that needs to happen when exiting a TB.
> 
> What I think you should do instead is check env_neg(env)->icount_decr, exactly
> like we do at the start of every basic block, and use that as an indication
> that you should exit back to the main loop.

The issue is that when we return to the main loop we really have to
inject an interrupt - otherwise we might simply skip parts of the
(interruptible) instruction and continue with the next one.

However, with I/O interrupts, we can actually race against other VCPUs.
So the I/O interrupt might be gone by the time we arrive in the main loop.

-- 

Thanks,

David / dhildenb


^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH v3 14/18] target/s390x: Rely on unwinding in s390_cpu_tlb_fill
  2019-09-27 16:16     ` Richard Henderson
@ 2019-09-30  7:56       ` David Hildenbrand
  0 siblings, 0 replies; 49+ messages in thread
From: David Hildenbrand @ 2019-09-30  7:56 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: qemu-s390x

On 27.09.19 18:16, Richard Henderson wrote:
> On 9/27/19 4:02 AM, David Hildenbrand wrote:
>> On 26.09.19 18:26, Richard Henderson wrote:
>>> We currently set ilen to AUTO, then overwrite that during
>>> unwinding, then overwrite that for the code access case.
>>>
>>> This can be simplified to setting ilen to our arbitrary
>>> value for the (undefined) code access case, then rely on
>>> unwinding to overwrite that with the correct value for
>>> the data access case.
>>>
>>> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
>>> ---
>>>  target/s390x/excp_helper.c | 23 +++++++----------------
>>>  1 file changed, 7 insertions(+), 16 deletions(-)
>>>
>>> diff --git a/target/s390x/excp_helper.c b/target/s390x/excp_helper.c
>>> index 98a1ee8317..8ce992e639 100644
>>> --- a/target/s390x/excp_helper.c
>>> +++ b/target/s390x/excp_helper.c
>>> @@ -96,7 +96,7 @@ bool s390_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
>>>  {
>>>      S390CPU *cpu = S390_CPU(cs);
>>>  
>>> -    trigger_pgm_exception(&cpu->env, PGM_ADDRESSING, ILEN_AUTO);
>>> +    trigger_pgm_exception(&cpu->env, PGM_ADDRESSING, ILEN_UNWIND);
>>
>> Hmm, we always trigger a pgm exceptions, meaning we set
>> cs->exception_index even if we have probe = true. Confused by that.
> 
> This is the CONFIG_USER_ONLY version, for which probe is always false.  Perhaps
> I shouldn't have made the function interface identical, but it did appear to
> make things cleaner for most targets.
> 
>>> +    trigger_pgm_exception(env, excp, 2);
>>
>> I wonder if it is still worth setting this only conditionally. Most
>> probably not.
> 
> I don't see that it would be.  I hope the comment is clear about this arbitrary
> value is overwritten during unwinding.

It's confusing, but I get it :)

-- 

Thanks,

David / dhildenb


^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH v3 02/18] target/s390x: Add ilen to unwind data
  2019-09-30  7:55       ` David Hildenbrand
@ 2019-09-30 15:03         ` Richard Henderson
  2019-09-30 15:42           ` David Hildenbrand
  0 siblings, 1 reply; 49+ messages in thread
From: Richard Henderson @ 2019-09-30 15:03 UTC (permalink / raw)
  To: David Hildenbrand, Richard Henderson, qemu-devel; +Cc: qemu-s390x

On 9/30/19 12:55 AM, David Hildenbrand wrote:
>> What I think you should do instead is check env_neg(env)->icount_decr, exactly
>> like we do at the start of every basic block, and use that as an indication
>> that you should exit back to the main loop.
> 
> The issue is that when we return to the main loop we really have to
> inject an interrupt - otherwise we might simply skip parts of the
> (interruptible) instruction and continue with the next one.

Do we?  We will return to the main loop with psw.addr still pointing at MVCL,
so the interrupt is delivered, and when the exception returns we restart the
MVCL.  Or, an interrupt is not delivered and we restart from psw.addr and still
restart the MVCL.

We probably would have to take a hard look at EXECUTE of MVCL to see if that is
actually restartable.  Not that it makes particular sense to want that combo,
but it's required to work.

> However, with I/O interrupts, we can actually race against other VCPUs.
> So the I/O interrupt might be gone by the time we arrive in the main loop.

Of course, but it's no different with this case than any other.  If the
interrupt has already been handled, then we will simply restart the next TB as
per normal.


r~



^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH v3 02/18] target/s390x: Add ilen to unwind data
  2019-09-30 15:03         ` Richard Henderson
@ 2019-09-30 15:42           ` David Hildenbrand
  2019-09-30 16:15             ` Richard Henderson
  0 siblings, 1 reply; 49+ messages in thread
From: David Hildenbrand @ 2019-09-30 15:42 UTC (permalink / raw)
  To: Richard Henderson, Richard Henderson, qemu-devel; +Cc: qemu-s390x

On 30.09.19 17:03, Richard Henderson wrote:
> On 9/30/19 12:55 AM, David Hildenbrand wrote:
>>> What I think you should do instead is check env_neg(env)->icount_decr, exactly
>>> like we do at the start of every basic block, and use that as an indication
>>> that you should exit back to the main loop.
>>
>> The issue is that when we return to the main loop we really have to
>> inject an interrupt - otherwise we might simply skip parts of the
>> (interruptible) instruction and continue with the next one.
> 
> Do we?  We will return to the main loop with psw.addr still pointing at MVCL,
> so the interrupt is delivered, and when the exception returns we restart the
> MVCL.  Or, an interrupt is not delivered and we restart from psw.addr and still
> restart the MVCL.

If that's the case, then this should indeed work.

> 
> We probably would have to take a hard look at EXECUTE of MVCL to see if that is
> actually restartable.  Not that it makes particular sense to want that combo,
> but it's required to work.
> 

Yes, this has to work. I'll look into that once I have some time.

>> However, with I/O interrupts, we can actually race against other VCPUs.
>> So the I/O interrupt might be gone by the time we arrive in the main loop.
> 
> Of course, but it's no different with this case than any other.  If the
> interrupt has already been handled, then we will simply restart the next TB as
> per normal.
Yeah, I was mostly concerned that "the next TB" will be "the next
instruction" and not "the original instruction again".

-- 

Thanks,

David / dhildenb


^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH v3 02/18] target/s390x: Add ilen to unwind data
  2019-09-30 15:42           ` David Hildenbrand
@ 2019-09-30 16:15             ` Richard Henderson
  2019-09-30 17:13               ` David Hildenbrand
  0 siblings, 1 reply; 49+ messages in thread
From: Richard Henderson @ 2019-09-30 16:15 UTC (permalink / raw)
  To: David Hildenbrand, Richard Henderson, qemu-devel; +Cc: qemu-s390x

On 9/30/19 8:42 AM, David Hildenbrand wrote:
>> Of course, but it's no different with this case than any other.  If the
>> interrupt has already been handled, then we will simply restart the next TB as
>> per normal.
> Yeah, I was mostly concerned that "the next TB" will be "the next
> instruction" and not "the original instruction again".

Ah, well, that's easy.  The next TB will start from psw.addr, and when we
cpu_loop_exit_restore(), psw.addr will be set to the current instruction.

This is exactly the same as when we raise a PGM_ADDRESSING exception which
needs to be restarted after the kernel swaps in the page.


r~



^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH v3 02/18] target/s390x: Add ilen to unwind data
  2019-09-30 16:15             ` Richard Henderson
@ 2019-09-30 17:13               ` David Hildenbrand
  0 siblings, 0 replies; 49+ messages in thread
From: David Hildenbrand @ 2019-09-30 17:13 UTC (permalink / raw)
  To: Richard Henderson, Richard Henderson, qemu-devel; +Cc: qemu-s390x

On 30.09.19 18:15, Richard Henderson wrote:
> On 9/30/19 8:42 AM, David Hildenbrand wrote:
>>> Of course, but it's no different with this case than any other.  If the
>>> interrupt has already been handled, then we will simply restart the next TB as
>>> per normal.
>> Yeah, I was mostly concerned that "the next TB" will be "the next
>> instruction" and not "the original instruction again".
> 
> Ah, well, that's easy.  The next TB will start from psw.addr, and when we
> cpu_loop_exit_restore(), psw.addr will be set to the current instruction.
> 
> This is exactly the same as when we raise a PGM_ADDRESSING exception which
> needs to be restarted after the kernel swaps in the page.
> 

Now that I think about it, this makes perfect sense :)

So it's mostly checking if there is an exception (like you said) and
then doing a cpu_loop_exit_restore() (if I'm not wrong, but I'll have to
look at the details).

-- 

Thanks,

David / dhildenb


^ permalink raw reply	[flat|nested] 49+ messages in thread

end of thread, other threads:[~2019-09-30 17:14 UTC | newest]

Thread overview: 49+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-09-26 16:25 [PATCH v3 00/18] target/s390: Use tcg unwinding for ilen Richard Henderson
2019-09-26 16:25 ` [PATCH v3 01/18] target/s390x: Truncate 32-bit psw_addr before creating TB Richard Henderson
2019-09-27 10:23   ` David Hildenbrand
2019-09-27 18:24     ` Richard Henderson
2019-09-26 16:25 ` [PATCH v3 02/18] target/s390x: Add ilen to unwind data Richard Henderson
2019-09-27 10:30   ` David Hildenbrand
2019-09-27 16:02     ` Richard Henderson
2019-09-30  7:55       ` David Hildenbrand
2019-09-30 15:03         ` Richard Henderson
2019-09-30 15:42           ` David Hildenbrand
2019-09-30 16:15             ` Richard Henderson
2019-09-30 17:13               ` David Hildenbrand
2019-09-26 16:26 ` [PATCH v3 03/18] target/s390x: Remove ilen parameter from tcg_s390_program_interrupt Richard Henderson
2019-09-27 10:31   ` David Hildenbrand
2019-09-26 16:26 ` [PATCH v3 04/18] target/s390x: Remove ilen parameter from s390_program_interrupt Richard Henderson
2019-09-27 10:34   ` David Hildenbrand
2019-09-26 16:26 ` [PATCH v3 05/18] target/s390x: Use tcg_s390_program_interrupt in TCG helpers Richard Henderson
2019-09-27 10:40   ` David Hildenbrand
2019-09-26 16:26 ` [PATCH v3 06/18] target/s390x: Push trigger_pgm_exception lower in s390_cpu_tlb_fill Richard Henderson
2019-09-27 10:41   ` David Hildenbrand
2019-09-26 16:26 ` [PATCH v3 07/18] target/s390x: Handle tec " Richard Henderson
2019-09-27 10:42   ` David Hildenbrand
2019-09-26 16:26 ` [PATCH v3 08/18] target/s390: Return exception from mmu_translate_real Richard Henderson
2019-09-27 10:44   ` David Hildenbrand
2019-09-27 12:47     ` David Hildenbrand
2019-09-27 16:08     ` Richard Henderson
2019-09-26 16:26 ` [PATCH v3 09/18] target/s390x: Remove exc argument to mmu_translate_asce Richard Henderson
2019-09-27 10:45   ` David Hildenbrand
2019-09-26 16:26 ` [PATCH v3 10/18] target/s390: Return exception from mmu_translate Richard Henderson
2019-09-27 10:55   ` David Hildenbrand
2019-09-26 16:26 ` [PATCH v3 11/18] target/s390: Return exception from translate_pages Richard Henderson
2019-09-27 10:56   ` David Hildenbrand
2019-09-26 16:26 ` [PATCH v3 12/18] target/s390x: Remove fail variable from s390_cpu_tlb_fill Richard Henderson
2019-09-27 10:56   ` David Hildenbrand
2019-09-26 16:26 ` [PATCH v3 13/18] target/s390x: Simplify helper_lra Richard Henderson
2019-09-27 10:57   ` David Hildenbrand
2019-09-26 16:26 ` [PATCH v3 14/18] target/s390x: Rely on unwinding in s390_cpu_tlb_fill Richard Henderson
2019-09-27 11:02   ` David Hildenbrand
2019-09-27 16:16     ` Richard Henderson
2019-09-30  7:56       ` David Hildenbrand
2019-09-26 16:26 ` [PATCH v3 15/18] target/s390x: Rely on unwinding in s390_cpu_virt_mem_rw Richard Henderson
2019-09-27 11:04   ` David Hildenbrand
2019-09-26 16:26 ` [PATCH v3 16/18] target/s390x: Remove ILEN_AUTO Richard Henderson
2019-09-27 11:04   ` David Hildenbrand
2019-09-26 16:26 ` [PATCH v3 17/18] target/s390x: Remove ilen argument from trigger_access_exception Richard Henderson
2019-09-27 11:04   ` David Hildenbrand
2019-09-26 16:26 ` [PATCH v3 18/18] target/s390x: Remove ilen argument from trigger_pgm_exception Richard Henderson
2019-09-27 11:05   ` David Hildenbrand
2019-09-27  8:18 ` [PATCH v3 00/18] target/s390: Use tcg unwinding for ilen David Hildenbrand

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).