mirror of https://github.com/proxmox/mirror_qemu
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
parent
b580b6ee05
commit
c87ff4d108
|
@ -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
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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];
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue