diff mbox series

[v2,1/1] linux-user/signal: Decode waitid si_code

Message ID 1fb2d56aa23a81f4473e638abe9e2d78c09a3d5b.1611080607.git.alistair.francis@wdc.com (mailing list archive)
State New, archived
Headers show
Series [v2,1/1] linux-user/signal: Decode waitid si_code | expand

Commit Message

Alistair Francis Jan. 19, 2021, 6:24 p.m. UTC
When mapping the host waitid status to the target status we previously
just used decoding information in the status value. This doesn't follow
what the waitid documentation describes, which instead suggests using
the si_code value for the decoding. This results in the incorrect values
seen when calling waitid. This is especially apparent on RV32 where all
wait calls use waitid (see the bug case).

This patch just passes the waitid status directly back to the guest.

Buglink: https://bugs.launchpad.net/qemu/+bug/1906193
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
v2:
 - Set tinfo->_sifields._sigchld._status directly from status

 linux-user/signal.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

Comments

Andreas K. Huettel Jan. 20, 2021, 8:12 p.m. UTC | #1
> 
> This patch just passes the waitid status directly back to the guest.
> 

This works at least as well as the previous versions, so ++ from me. 

Will do more testing over the next days to see if it maybe also improves the 
additional oddities I observed. 

Tested-by: Andreas K. Hüttel <dilfridge@gentoo.org>

> Buglink: https://bugs.launchpad.net/qemu/+bug/1906193
> Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
> ---
> v2:
>  - Set tinfo->_sifields._sigchld._status directly from status
> 
>  linux-user/signal.c | 3 +--
>  1 file changed, 1 insertion(+), 2 deletions(-)
> 
> diff --git a/linux-user/signal.c b/linux-user/signal.c
> index 73de934c65..7eecec46c4 100644
> --- a/linux-user/signal.c
> +++ b/linux-user/signal.c
> @@ -349,8 +349,7 @@ static inline void
> host_to_target_siginfo_noswap(target_siginfo_t *tinfo, case TARGET_SIGCHLD:
>              tinfo->_sifields._sigchld._pid = info->si_pid;
>              tinfo->_sifields._sigchld._uid = info->si_uid;
> -            tinfo->_sifields._sigchld._status
> -                = host_to_target_waitstatus(info->si_status);
> +            tinfo->_sifields._sigchld._status = info->si_status;
>              tinfo->_sifields._sigchld._utime = info->si_utime;
>              tinfo->_sifields._sigchld._stime = info->si_stime;
>              si_type = QEMU_SI_CHLD;
Andreas K. Huettel Jan. 21, 2021, 3:15 p.m. UTC | #2
Am Mittwoch, 20. Januar 2021, 22:12:30 EET schrieb Andreas K. Hüttel:
> > This patch just passes the waitid status directly back to the guest.
> 
> This works at least as well as the previous versions, so ++ from me.
> 
> Will do more testing over the next days to see if it maybe also improves the
> additional oddities I observed.
> 

So the patch is good since it clearly resolves the linked bug. 

However, something else is still broken (maybe related; unchanged compared to 
the previous patch version). I keep seeing hanging "qemu-riscv32 /bin/bash 
..." processes using 100% cpu. If I attach strace (on the host arch x86-64) to 
qemu, I see an infinite loop:

waitid(P_ALL, -1, {}, WNOHANG|WEXITED, NULL) = 0
rt_sigprocmask(SIG_SETMASK, ~[RTMIN RT_1], NULL, 8) = 0
rt_sigprocmask(SIG_SETMASK, ~[RTMIN RT_1], NULL, 8) = 0
rt_sigprocmask(SIG_SETMASK, [CHLD], NULL, 8) = 0
rt_sigprocmask(SIG_SETMASK, ~[RTMIN RT_1], NULL, 8) = 0
rt_sigprocmask(SIG_SETMASK, ~[RTMIN RT_1], NULL, 8) = 0
rt_sigprocmask(SIG_SETMASK, [CHLD], NULL, 8) = 0
waitid(P_ALL, -1, {}, WNOHANG|WEXITED, NULL) = 0
rt_sigprocmask(SIG_SETMASK, ~[RTMIN RT_1], NULL, 8) = 0
rt_sigprocmask(SIG_SETMASK, ~[RTMIN RT_1], NULL, 8) = 0
rt_sigprocmask(SIG_SETMASK, [CHLD], NULL, 8) = 0
rt_sigprocmask(SIG_SETMASK, ~[RTMIN RT_1], NULL, 8) = 0
rt_sigprocmask(SIG_SETMASK, ~[RTMIN RT_1], NULL, 8) = 0
rt_sigprocmask(SIG_SETMASK, [CHLD], NULL, 8) = 0
...

Unfortunately I do not have a simple reproducer. This is somewhere in the 
middle of our build system...

Otherwise, I can re-build glibc, gcc, binutils, make  in the qemu chroot 
without obvious problems, with one striking strange detail - "make" refuses to 
run more than one concurrent process (even with MAKEOPTS="-j9"). Something is 
off there.
Alistair Francis Feb. 12, 2021, 9:44 p.m. UTC | #3
On Thu, Jan 21, 2021 at 7:15 AM Andreas K. Hüttel <dilfridge@gentoo.org> wrote:
>
> Am Mittwoch, 20. Januar 2021, 22:12:30 EET schrieb Andreas K. Hüttel:
> > > This patch just passes the waitid status directly back to the guest.
> >
> > This works at least as well as the previous versions, so ++ from me.
> >
> > Will do more testing over the next days to see if it maybe also improves the
> > additional oddities I observed.
> >
>
> So the patch is good since it clearly resolves the linked bug.
>
> However, something else is still broken (maybe related; unchanged compared to
> the previous patch version). I keep seeing hanging "qemu-riscv32 /bin/bash
> ..." processes using 100% cpu. If I attach strace (on the host arch x86-64) to
> qemu, I see an infinite loop:
>
> waitid(P_ALL, -1, {}, WNOHANG|WEXITED, NULL) = 0
> rt_sigprocmask(SIG_SETMASK, ~[RTMIN RT_1], NULL, 8) = 0
> rt_sigprocmask(SIG_SETMASK, ~[RTMIN RT_1], NULL, 8) = 0
> rt_sigprocmask(SIG_SETMASK, [CHLD], NULL, 8) = 0
> rt_sigprocmask(SIG_SETMASK, ~[RTMIN RT_1], NULL, 8) = 0
> rt_sigprocmask(SIG_SETMASK, ~[RTMIN RT_1], NULL, 8) = 0
> rt_sigprocmask(SIG_SETMASK, [CHLD], NULL, 8) = 0
> waitid(P_ALL, -1, {}, WNOHANG|WEXITED, NULL) = 0
> rt_sigprocmask(SIG_SETMASK, ~[RTMIN RT_1], NULL, 8) = 0
> rt_sigprocmask(SIG_SETMASK, ~[RTMIN RT_1], NULL, 8) = 0
> rt_sigprocmask(SIG_SETMASK, [CHLD], NULL, 8) = 0
> rt_sigprocmask(SIG_SETMASK, ~[RTMIN RT_1], NULL, 8) = 0
> rt_sigprocmask(SIG_SETMASK, ~[RTMIN RT_1], NULL, 8) = 0
> rt_sigprocmask(SIG_SETMASK, [CHLD], NULL, 8) = 0
> ...
>
> Unfortunately I do not have a simple reproducer. This is somewhere in the
> middle of our build system...
>
> Otherwise, I can re-build glibc, gcc, binutils, make  in the qemu chroot
> without obvious problems, with one striking strange detail - "make" refuses to
> run more than one concurrent process (even with MAKEOPTS="-j9"). Something is
> off there.

Ping!

Even though it seems like there are still issues with RV32, this is a
step in the right direction.

Alistair

>
> --
> Andreas K. Hüttel
> dilfridge@gentoo.org
> Gentoo Linux developer
> (council, qa, toolchain, base-system, perl, libreoffice)
Laurent Vivier Feb. 13, 2021, 4:08 p.m. UTC | #4
Le 19/01/2021 à 19:24, Alistair Francis a écrit :
> When mapping the host waitid status to the target status we previously
> just used decoding information in the status value. This doesn't follow
> what the waitid documentation describes, which instead suggests using
> the si_code value for the decoding. This results in the incorrect values
> seen when calling waitid. This is especially apparent on RV32 where all
> wait calls use waitid (see the bug case).
> 
> This patch just passes the waitid status directly back to the guest.
> 
> Buglink: https://bugs.launchpad.net/qemu/+bug/1906193
> Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
> ---
> v2:
>  - Set tinfo->_sifields._sigchld._status directly from status
> 
>  linux-user/signal.c | 3 +--
>  1 file changed, 1 insertion(+), 2 deletions(-)
> 
> diff --git a/linux-user/signal.c b/linux-user/signal.c
> index 73de934c65..7eecec46c4 100644
> --- a/linux-user/signal.c
> +++ b/linux-user/signal.c
> @@ -349,8 +349,7 @@ static inline void host_to_target_siginfo_noswap(target_siginfo_t *tinfo,
>          case TARGET_SIGCHLD:
>              tinfo->_sifields._sigchld._pid = info->si_pid;
>              tinfo->_sifields._sigchld._uid = info->si_uid;
> -            tinfo->_sifields._sigchld._status
> -                = host_to_target_waitstatus(info->si_status);
> +            tinfo->_sifields._sigchld._status = info->si_status;
>              tinfo->_sifields._sigchld._utime = info->si_utime;
>              tinfo->_sifields._sigchld._stime = info->si_stime;
>              si_type = QEMU_SI_CHLD;
> 

Reviewed-by: Laurent Vivier <laurent@vivier.eu>
Laurent Vivier Feb. 13, 2021, 4:15 p.m. UTC | #5
Le 19/01/2021 à 19:24, Alistair Francis a écrit :
> When mapping the host waitid status to the target status we previously
> just used decoding information in the status value. This doesn't follow
> what the waitid documentation describes, which instead suggests using
> the si_code value for the decoding. This results in the incorrect values
> seen when calling waitid. This is especially apparent on RV32 where all
> wait calls use waitid (see the bug case).
> 
> This patch just passes the waitid status directly back to the guest.
> 
> Buglink: https://bugs.launchpad.net/qemu/+bug/1906193
> Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
> ---
> v2:
>  - Set tinfo->_sifields._sigchld._status directly from status
> 
>  linux-user/signal.c | 3 +--
>  1 file changed, 1 insertion(+), 2 deletions(-)
> 
> diff --git a/linux-user/signal.c b/linux-user/signal.c
> index 73de934c65..7eecec46c4 100644
> --- a/linux-user/signal.c
> +++ b/linux-user/signal.c
> @@ -349,8 +349,7 @@ static inline void host_to_target_siginfo_noswap(target_siginfo_t *tinfo,
>          case TARGET_SIGCHLD:
>              tinfo->_sifields._sigchld._pid = info->si_pid;
>              tinfo->_sifields._sigchld._uid = info->si_uid;
> -            tinfo->_sifields._sigchld._status
> -                = host_to_target_waitstatus(info->si_status);
> +            tinfo->_sifields._sigchld._status = info->si_status;
>              tinfo->_sifields._sigchld._utime = info->si_utime;
>              tinfo->_sifields._sigchld._stime = info->si_stime;
>              si_type = QEMU_SI_CHLD;
> 

Applied to my linux-user-for-6.0 branch.

Thanks,
Laurent
diff mbox series

Patch

diff --git a/linux-user/signal.c b/linux-user/signal.c
index 73de934c65..7eecec46c4 100644
--- a/linux-user/signal.c
+++ b/linux-user/signal.c
@@ -349,8 +349,7 @@  static inline void host_to_target_siginfo_noswap(target_siginfo_t *tinfo,
         case TARGET_SIGCHLD:
             tinfo->_sifields._sigchld._pid = info->si_pid;
             tinfo->_sifields._sigchld._uid = info->si_uid;
-            tinfo->_sifields._sigchld._status
-                = host_to_target_waitstatus(info->si_status);
+            tinfo->_sifields._sigchld._status = info->si_status;
             tinfo->_sifields._sigchld._utime = info->si_utime;
             tinfo->_sifields._sigchld._stime = info->si_stime;
             si_type = QEMU_SI_CHLD;