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:
Denis Drakhnia 2021-02-12 16:08:06 +02:00 committed by Alibek Omarov
parent 19e386d72a
commit 4ca7a8e3fe
2 changed files with 6 additions and 7 deletions

View File

@ -44,18 +44,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 == -TARGET_ERESTARTSYS) {
/* do not set sysret address and syscall will be restarted */
} else if (ret != -TARGET_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;
}

View File

@ -1188,7 +1188,6 @@ static void e2k_tr_translate_insn(DisasContextBase *db, CPUState *cs)
case E2K_SYSCALL_ADDR6:
/* fake enter into syscall handler */
ctx->base.is_jmp = DISAS_NORETURN;
e2k_gen_save_pc(E2K_SYSRET_ADDR);
gen_helper_syscall(cpu_env);
tcg_gen_exit_tb(NULL, TB_EXIT_IDX0);
break;