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 Denis Drakhnia
parent 5e66da5f7d
commit e404c06a2d
2 changed files with 6 additions and 7 deletions

View File

@ -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;
}

View File

@ -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;