提交 47575997 编写于 作者: J Jincheng Miao 提交者: Riku Voipio

linux-user: Fix syscall instruction usermode emulation on X86_64

Currently syscall instruction is buggy on user mode X86_64,
the EIP is updated after do_syscall(), that is too late for
clone(). Because clone() will create a thread at the env->EIP
(the address of syscall insn), and then child thread enters
do_syscall() again, that is not expected. Sometimes it is tragic.

User mode syscall insn emulation is not used MSR, so the
action should be same to INT 0x80. INT 0x80 will update EIP in
do_interrupt(), ditto for syscall() for consistency.
Signed-off-by: NJincheng Miao <jmiao@redhat.com>
Reviewed-by: NRichard Henderson <rth@twiddle.net>
Signed-off-by: NRiku Voipio <riku.voipio@linaro.org>
上级 0b2effd7
......@@ -309,7 +309,6 @@ void cpu_loop(CPUX86State *env)
env->regs[8],
env->regs[9],
0, 0);
env->eip = env->exception_next_eip;
break;
#endif
case EXCP0B_NOSEG:
......
......@@ -1127,8 +1127,8 @@ static void do_interrupt_user(CPUX86State *env, int intno, int is_int,
/* Since we emulate only user space, we cannot do more than
exiting the emulation with the suitable exception and error
code */
if (is_int) {
code. So update EIP for INT 0x80 and EXCP_SYSCALL. */
if (is_int || intno == EXCP_SYSCALL) {
env->eip = next_eip;
}
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册