On Mon, 2021-07-05 at 11:36 +0200, David Hildenbrand wrote: > On 23.06.21 04:32, Ilya Leoshkevich wrote: > > For SIGILL, SIGFPE and SIGTRAP the PSW must point after the > > instruction, and at the instruction for other signals. Currently > > under > > qemu-user it always points at the instruction. > > > > Fix by advancing psw.addr for these signals. > > > > Buglink: https://gitlab.com/qemu-project/qemu/-/issues/319 > > Signed-off-by: Ilya Leoshkevich <i...@linux.ibm.com> > > Co-developed-by: Ulrich Weigand <ulrich.weig...@de.ibm.com> > > --- > > linux-user/s390x/cpu_loop.c | 5 +++++ > > 1 file changed, 5 insertions(+) > > > > diff --git a/linux-user/s390x/cpu_loop.c b/linux- > > user/s390x/cpu_loop.c > > index 30568139df..230217feeb 100644 > > --- a/linux-user/s390x/cpu_loop.c > > +++ b/linux-user/s390x/cpu_loop.c > > @@ -133,6 +133,11 @@ void cpu_loop(CPUS390XState *env) > > > > do_signal_pc: > > addr = env->psw.addr; > > + /* > > + * For SIGILL, SIGFPE and SIGTRAP the PSW must point > > after the > > + * instruction. > > + */ > > + env->psw.addr += env->int_pgm_ilen; > > We also reach this path via EXCP_DEBUG. How can we expect > env->int_pgm_ilen to contain something sensible in that case?
You are right, this breaks breakpoints after getting any PGM exception (they turn into "Program received signal SIGTRAP, Trace/breakpoint trap." instead of the usual "Breakpoint N"). We don't need a PSW rewind here, since it's already incremented throught the following sequence: 1) GDB asks QEMU to set a breakpoint using a $Z0 packet. 2) translator_loop() notices the breakpoint and calls s390x_tr_breakpoint_check(). 3) s390x_tr_breakpoint_check() sets DisasContextBase.is_jmp to DISAS_PC_STALE and increments DisasContextBase.pc_next by 2. 4) translator_loop() calls s390x_tr_tb_stop(). 5) s390x_tr_tb_stop() calls update_psw_addr(), so the JITed code increments the PSWA by 2 as well. 6) s390x_tr_tb_stop() calls gen_exception(EXCP_DEBUG). What do you think about the following amend? --- a/linux-user/s390x/cpu_loop.c +++ b/linux-user/s390x/cpu_loop.c @@ -64,7 +64,13 @@ void cpu_loop(CPUS390XState *env) case EXCP_DEBUG: sig = TARGET_SIGTRAP; n = TARGET_TRAP_BRKPT; - goto do_signal_pc; + /* + * For SIGTRAP the PSW must point after the instruction, which it + * already does thanks to s390x_tr_tb_stop(). si_addr doesn't need + * to be filled. + */ + addr = 0; + goto do_signal; case EXCP_PGM: n = env->int_pgm_code; switch (n) { @@ -134,8 +140,7 @@ void cpu_loop(CPUS390XState *env) do_signal_pc: addr = env->psw.addr; /* - * For SIGILL, SIGFPE and SIGTRAP the PSW must point after the - * instruction. + * For SIGILL and SIGFPE the PSW must point after the instruction. */ env->psw.addr += env->int_pgm_ilen; do_signal: Best regards, Ilya