* [Qemu-devel] [PATCH] linux-user: Fix syscall instruction usermode emulation on X86_64
@ 2014-08-08 3:56 Jincheng Miao
2014-08-08 17:09 ` Richard Henderson
2014-08-12 7:22 ` Riku Voipio
0 siblings, 2 replies; 3+ messages in thread
From: Jincheng Miao @ 2014-08-08 3:56 UTC (permalink / raw)
To: qemu-devel; +Cc: peter.maydell, riku.voipio, Jincheng Miao, rth
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: Jincheng Miao <jmiao@redhat.com>
---
linux-user/main.c | 1 -
target-i386/seg_helper.c | 4 ++--
2 files changed, 2 insertions(+), 3 deletions(-)
diff --git a/linux-user/main.c b/linux-user/main.c
index b453a39..472a16d 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -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:
diff --git a/target-i386/seg_helper.c b/target-i386/seg_helper.c
index 2d970d0..13eefba 100644
--- a/target-i386/seg_helper.c
+++ b/target-i386/seg_helper.c
@@ -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;
}
}
--
1.7.1
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [Qemu-devel] [PATCH] linux-user: Fix syscall instruction usermode emulation on X86_64
2014-08-08 3:56 [Qemu-devel] [PATCH] linux-user: Fix syscall instruction usermode emulation on X86_64 Jincheng Miao
@ 2014-08-08 17:09 ` Richard Henderson
2014-08-12 7:22 ` Riku Voipio
1 sibling, 0 replies; 3+ messages in thread
From: Richard Henderson @ 2014-08-08 17:09 UTC (permalink / raw)
To: Jincheng Miao, qemu-devel; +Cc: peter.maydell, riku.voipio
On 08/07/2014 05:56 PM, Jincheng Miao wrote:
> 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: Jincheng Miao <jmiao@redhat.com>
> ---
> linux-user/main.c | 1 -
> target-i386/seg_helper.c | 4 ++--
> 2 files changed, 2 insertions(+), 3 deletions(-)
Reviewed-by: Richard Henderson <rth@twiddle.net>
r~
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [Qemu-devel] [PATCH] linux-user: Fix syscall instruction usermode emulation on X86_64
2014-08-08 3:56 [Qemu-devel] [PATCH] linux-user: Fix syscall instruction usermode emulation on X86_64 Jincheng Miao
2014-08-08 17:09 ` Richard Henderson
@ 2014-08-12 7:22 ` Riku Voipio
1 sibling, 0 replies; 3+ messages in thread
From: Riku Voipio @ 2014-08-12 7:22 UTC (permalink / raw)
To: Jincheng Miao; +Cc: peter.maydell, riku.voipio, qemu-devel, rth
On Fri, Aug 08, 2014 at 11:56:54AM +0800, Jincheng Miao wrote:
> 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.
Thanks applied to linux-user tree for next pull request.
Riku
> Signed-off-by: Jincheng Miao <jmiao@redhat.com>
> ---
> linux-user/main.c | 1 -
> target-i386/seg_helper.c | 4 ++--
> 2 files changed, 2 insertions(+), 3 deletions(-)
>
> diff --git a/linux-user/main.c b/linux-user/main.c
> index b453a39..472a16d 100644
> --- a/linux-user/main.c
> +++ b/linux-user/main.c
> @@ -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:
> diff --git a/target-i386/seg_helper.c b/target-i386/seg_helper.c
> index 2d970d0..13eefba 100644
> --- a/target-i386/seg_helper.c
> +++ b/target-i386/seg_helper.c
> @@ -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;
> }
> }
> --
> 1.7.1
>
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2014-08-12 7:23 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-08-08 3:56 [Qemu-devel] [PATCH] linux-user: Fix syscall instruction usermode emulation on X86_64 Jincheng Miao
2014-08-08 17:09 ` Richard Henderson
2014-08-12 7:22 ` Riku Voipio
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).