target/s390x: Add ilen to unwind data

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>
Message-Id: <20191001171614.8405-2-richard.henderson@linaro.org>
Reviewed-by: David Hildenbrand <david@redhat.com>
Signed-off-by: David Hildenbrand <david@redhat.com>
master
Richard Henderson 2019-10-01 10:15:57 -07:00 committed by David Hildenbrand
parent b580b6ee05
commit c87ff4d108
3 changed files with 24 additions and 5 deletions

View File

@ -34,7 +34,7 @@
/* The z/Architecture has a strong memory model with some store-after-load re-ordering */ /* 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 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_MODE0_SUFFIX _primary
#define MMU_MODE1_SUFFIX _secondary #define MMU_MODE1_SUFFIX _secondary
@ -804,6 +804,8 @@ int cpu_s390x_signal_handler(int host_signum, void *pinfo, void *puc);
void s390_crw_mchk(void); void s390_crw_mchk(void);
void s390_io_interrupt(uint16_t subchannel_id, uint16_t subchannel_nr, void s390_io_interrupt(uint16_t subchannel_id, uint16_t subchannel_nr,
uint32_t io_int_parm, uint32_t io_int_word); 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 */ /* automatically detect the instruction length */
#define ILEN_AUTO 0xff #define ILEN_AUTO 0xff
#define RA_IGNORED 0 #define RA_IGNORED 0

View File

@ -28,7 +28,10 @@ void trigger_pgm_exception(CPUS390XState *env, uint32_t code, uint32_t ilen)
cs->exception_index = EXCP_PGM; cs->exception_index = EXCP_PGM;
env->int_pgm_code = code; 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, void s390_program_interrupt(CPUS390XState *env, uint32_t code, int ilen,

View File

@ -6309,6 +6309,9 @@ static DisasJumpType translate_one(CPUS390XState *env, DisasContext *s)
/* Search for the insn in the table. */ /* Search for the insn in the table. */
insn = extract_insn(env, s, &f); 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. */ /* Not found means unimplemented/illegal opcode. */
if (insn == NULL) { if (insn == NULL) {
qemu_log_mask(LOG_UNIMP, "unimplemented opcode 0x%02x%02x\n", qemu_log_mask(LOG_UNIMP, "unimplemented opcode 0x%02x%02x\n",
@ -6463,9 +6466,6 @@ static void s390x_tr_tb_start(DisasContextBase *db, CPUState *cs)
static void s390x_tr_insn_start(DisasContextBase *dcbase, 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, static bool s390x_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cs,
@ -6473,6 +6473,14 @@ static bool s390x_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cs,
{ {
DisasContext *dc = container_of(dcbase, DisasContext, base); DisasContext *dc = container_of(dcbase, DisasContext, base);
/*
* Emit an insn_start to accompany the breakpoint exception.
* The ILEN value is a dummy, since this does not result in
* an s390x exception, but an internal qemu exception which
* brings us back to interact with the gdbstub.
*/
tcg_gen_insn_start(dc->base.pc_next, dc->cc_op, 2);
dc->base.is_jmp = DISAS_PC_STALE; dc->base.is_jmp = DISAS_PC_STALE;
dc->do_debug = true; dc->do_debug = true;
/* The address covered by the breakpoint must be included in /* The address covered by the breakpoint must be included in
@ -6567,8 +6575,14 @@ void restore_state_to_opc(CPUS390XState *env, TranslationBlock *tb,
target_ulong *data) target_ulong *data)
{ {
int cc_op = data[1]; int cc_op = data[1];
env->psw.addr = data[0]; 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)) { if ((cc_op != CC_OP_DYNAMIC) && (cc_op != CC_OP_STATIC)) {
env->cc_op = cc_op; env->cc_op = cc_op;
} }
/* Record ILEN. */
env->int_pgm_ilen = data[2];
} }