From: Helge Deller <[email protected]> The CLONE_PARENT_SETTID option requires the implementation to store the child thread ID at the location pointed to by parent_tid in the parent's memory.
Fix our implementation and move the code from the client side (where fork returned 0), to the parent side and store the return value from the fork call (which is the client TID) in the parent_tid pointer. Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3340 Signed-off-by: Helge Deller <[email protected]> Reviewed-by: Peter Maydell <[email protected]> (cherry picked from commit b03a6ac6fa5d7775b9f912fa5c39f7b92388c6a2) Signed-off-by: Michael Tokarev <[email protected]> diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 76b655da2b..b8b256c430 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -6918,8 +6918,6 @@ static int do_fork(CPUArchState *env, unsigned int flags, abi_ulong newsp, the child process gets its own copy of the lock. */ if (flags & CLONE_CHILD_SETTID) put_user_u32(sys_gettid(), child_tidptr); - if (flags & CLONE_PARENT_SETTID) - put_user_u32(sys_gettid(), parent_tidptr); ts = get_task_state(cpu); if (flags & CLONE_SETTLS) cpu_set_tls (env, newtls); @@ -6927,6 +6925,8 @@ static int do_fork(CPUArchState *env, unsigned int flags, abi_ulong newsp, ts->child_tidptr = child_tidptr; } else { cpu_clone_regs_parent(env, flags); + if (flags & CLONE_PARENT_SETTID) + put_user_u32(ret, parent_tidptr); if (flags & CLONE_PIDFD) { int pid_fd = 0; #if defined(__NR_pidfd_open) && defined(TARGET_NR_pidfd_open) -- 2.47.3
