linux-user: Support for restarting system calls for S390 targets

Update the S390 main loop and sigreturn code:
 * on TARGET_ERESTARTSYS, wind guest PC backwards to repeat syscall insn
 * set all guest CPU state within signal.c code on sigreturn
 * handle TARGET_QEMU_ESIGRETURN in the main loop as the indication
   that the main loop should not touch any guest CPU state

Signed-off-by: Timothy Edward Baldwin <T.E.Baldwin99@members.leeds.ac.uk>
Message-id: 1441497448-32489-33-git-send-email-T.E.Baldwin99@members.leeds.ac.uk
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
[PMM: tweak commit message; remove stray double semicolon; drop
 TARGET_USE_ERESTARTSYS define]
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Riku Voipio <riku.voipio@linaro.org>
This commit is contained in:
Timothy E Baldwin 2016-05-12 18:47:40 +01:00 committed by Riku Voipio
parent 7ccb84a916
commit 47405ab642
3 changed files with 12 additions and 5 deletions

View File

@ -3385,6 +3385,7 @@ void cpu_loop(CPUS390XState *env)
int trapnr, n, sig; int trapnr, n, sig;
target_siginfo_t info; target_siginfo_t info;
target_ulong addr; target_ulong addr;
abi_long ret;
while (1) { while (1) {
cpu_exec_start(cs); cpu_exec_start(cs);
@ -3402,9 +3403,14 @@ void cpu_loop(CPUS390XState *env)
n = env->regs[1]; n = env->regs[1];
} }
env->psw.addr += env->int_svc_ilen; env->psw.addr += env->int_svc_ilen;
env->regs[2] = do_syscall(env, n, env->regs[2], env->regs[3], ret = do_syscall(env, n, env->regs[2], env->regs[3],
env->regs[4], env->regs[5], env->regs[4], env->regs[5],
env->regs[6], env->regs[7], 0, 0); 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; break;
case EXCP_DEBUG: case EXCP_DEBUG:

View File

@ -23,4 +23,5 @@ static inline abi_ulong get_sp_from_cpustate(CPUS390XState *state)
return state->regs[15]; return state->regs[15];
} }
#endif /* TARGET_SIGNAL_H */ #endif /* TARGET_SIGNAL_H */

View File

@ -4280,7 +4280,7 @@ long do_sigreturn(CPUS390XState *env)
} }
unlock_user_struct(frame, frame_addr, 0); unlock_user_struct(frame, frame_addr, 0);
return env->regs[2]; return -TARGET_QEMU_ESIGRETURN;
badframe: badframe:
force_sig(TARGET_SIGSEGV); force_sig(TARGET_SIGSEGV);
@ -4310,7 +4310,7 @@ long do_rt_sigreturn(CPUS390XState *env)
goto badframe; goto badframe;
} }
unlock_user_struct(frame, frame_addr, 0); unlock_user_struct(frame, frame_addr, 0);
return env->regs[2]; return -TARGET_QEMU_ESIGRETURN;
badframe: badframe:
unlock_user_struct(frame, frame_addr, 0); unlock_user_struct(frame, frame_addr, 0);