diff --git a/linux-user/main.c b/linux-user/main.c index 58dc91ced5..c16d7edc3a 100644 --- a/linux-user/main.c +++ b/linux-user/main.c @@ -3385,6 +3385,7 @@ void cpu_loop(CPUS390XState *env) int trapnr, n, sig; target_siginfo_t info; target_ulong addr; + abi_long ret; while (1) { cpu_exec_start(cs); @@ -3402,9 +3403,14 @@ void cpu_loop(CPUS390XState *env) n = env->regs[1]; } env->psw.addr += env->int_svc_ilen; - env->regs[2] = do_syscall(env, n, env->regs[2], env->regs[3], - env->regs[4], env->regs[5], - env->regs[6], env->regs[7], 0, 0); + ret = do_syscall(env, n, env->regs[2], env->regs[3], + env->regs[4], env->regs[5], + env->regs[6], env->regs[7], 0, 0); + if (ret == -TARGET_ERESTARTSYS) { + env->psw.addr -= env->int_svc_ilen; + } else if (ret != -TARGET_QEMU_ESIGRETURN) { + env->regs[2] = ret; + } break; case EXCP_DEBUG: diff --git a/linux-user/s390x/target_signal.h b/linux-user/s390x/target_signal.h index b4816b040f..a6fb2873a3 100644 --- a/linux-user/s390x/target_signal.h +++ b/linux-user/s390x/target_signal.h @@ -23,4 +23,5 @@ static inline abi_ulong get_sp_from_cpustate(CPUS390XState *state) return state->regs[15]; } + #endif /* TARGET_SIGNAL_H */ diff --git a/linux-user/signal.c b/linux-user/signal.c index 3eea6b7981..51e11c14fb 100644 --- a/linux-user/signal.c +++ b/linux-user/signal.c @@ -4280,7 +4280,7 @@ long do_sigreturn(CPUS390XState *env) } unlock_user_struct(frame, frame_addr, 0); - return env->regs[2]; + return -TARGET_QEMU_ESIGRETURN; badframe: force_sig(TARGET_SIGSEGV); @@ -4310,7 +4310,7 @@ long do_rt_sigreturn(CPUS390XState *env) goto badframe; } unlock_user_struct(frame, frame_addr, 0); - return env->regs[2]; + return -TARGET_QEMU_ESIGRETURN; badframe: unlock_user_struct(frame, frame_addr, 0);