e2k: Fix syscall restart.
We cannot just change the IP address in E2K to restart the instruction because the same register can be read and written in the same instruction (and many more situations), but we can create a fake syscall instruction and restart it. Signed-off-by: Denis Drakhnya <numas13@gmail.com>
This commit is contained in:
parent
5e66da5f7d
commit
e404c06a2d
@ -47,18 +47,18 @@ void cpu_loop(CPUE2KState *env)
|
||||
// TODO: check what happens if env->wd.size is zero
|
||||
memcpy(args, env->regs, psize * sizeof(args[0]));
|
||||
|
||||
do {
|
||||
ret = do_syscall(env, args[0], args[1], args[2], args[3],
|
||||
args[4], args[5], args[6], args[7], args[8]);
|
||||
// FIXME: I don't know how to properly handle syscall restart
|
||||
} while (ret == -TARGET_ERESTARTSYS);
|
||||
ret = do_syscall(env, args[0], args[1], args[2], args[3],
|
||||
args[4], args[5], args[6], args[7], args[8]);
|
||||
|
||||
if (ret != -TARGET_QEMU_ESIGRETURN && env->wd.psize > 0) {
|
||||
if (ret == -QEMU_ERESTARTSYS) {
|
||||
/* do not set sysret address and syscall will be restarted */
|
||||
} else if (ret != -QEMU_ESIGRETURN && env->wd.psize > 0) {
|
||||
memset(env->tags, E2K_TAG_NON_NUMBER64,
|
||||
psize * sizeof(env->tags[0]));
|
||||
|
||||
env->regs[0] = ret;
|
||||
env->tags[0] = E2K_TAG_NUMBER64;
|
||||
env->ip = E2K_SYSRET_ADDR;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -1158,7 +1158,6 @@ static void e2k_tr_translate_insn(DisasContextBase *db, CPUState *cs)
|
||||
ctx->base.is_jmp = DISAS_NORETURN;
|
||||
/* force non-zero tb size */
|
||||
pc_next = ctx->base.pc_next + 8;
|
||||
e2k_gen_save_pc(E2K_SYSRET_ADDR);
|
||||
gen_helper_syscall(cpu_env);
|
||||
tcg_gen_exit_tb(NULL, TB_EXIT_IDX0);
|
||||
break;
|
||||
|
Loading…
Reference in New Issue
Block a user