[Qemu-devel] [PATCH v2 00/16] Augment support for signal handling

Miloš Stojanović posted 16 patches 6 years, 10 months ago
Failed in applying to current master (apply log)
Test checkpatch passed
Test docker passed
Test s390x passed
linux-user/qemu.h         |  11 +++
linux-user/signal.c       | 235 +++++++++++++++++++++++++++++++++++++++++++++-
linux-user/strace.c       | 177 ++++++++++++++++++++++++++++++++--
linux-user/strace.list    |  16 ++--
linux-user/syscall.c      | 208 +++++++++++++++++++++++++++++++++++++---
linux-user/syscall_defs.h |  32 +++++++
6 files changed, 651 insertions(+), 28 deletions(-)
[Qemu-devel] [PATCH v2 00/16] Augment support for signal handling
Posted by Miloš Stojanović 6 years, 10 months ago
Change from v1 to v2:
tswapal_target_sigset() is no longer static since it was breaking the build.

This patch set deals with QEMU Linux user mode functionalities related to
signal handling. It is composed of four sections:

A. Extend strace support (patches 1-2, 8-9):

   Strace support is added for getuid(), gettid(), getppid(), geteuid(),
   tkill(), tgkill() and rt_sigqueueinfo(), along with support for printing
   the uinfo structure of rt_sigqueueinfo() of rt_tgsigqueueinfo() instead
   of a pointer to it. Additionally, some minor fixes of inconsistent spaces
   in the output of print_siginfo() are added.

B. Fix some signal handling issues (patches 3-5):

   Fix the ssetmask() system call by removing the invocation of
   sigorset() using the old and the new signal masks as arguments.
   Change the unlock_user() argument from arg1 to arg3 to match with
   lock_user(), since arg3 contains the pointer to the siginfo_t structure.
   Change the type of the first argument of rt_sigqueinfo()
   from int to pid_t in the syscall declaration.

C. Adding support for rt_tgsigqueueinfo() (patches 6-7):

   Add a new system call: rt_tgsigqueueinfo().

   This system call is similar to rt_sigqueueinfo(), but instead of
   sending the signal and data to the whole thread group with the ID
   equal to the argument tgid, it sends it to a single thread within
   that thread group. The ID of the thread is specified by the tid
   argument.

   The implementation is based on the rt_sigqueueinfo() in linux-user
   mode, where the tid is added as the second argument and the
   previous second and third argument become arguments three and four,
   respectively.

D. Add support for larger target signal range (RFC patches 10-16):

   Add target signal mask tracking and multiplexing of target signals out
   of the host range. The patches are marked as RFC because they introduce
   significant new functionalities regarding signal handling in QEMU.

   Currently, QEMU has a copy of the host signal and suspend masks and
   that is usually enough, since most of the time the signal mask of the
   target architecture is either the same length or narrower. If however
   the signal mask is wider, then part of it won't be tracked. The signals
   that are in the target range but out of the host range were treated like
   faulty signals and couldn't be used. This problem is solved by enabling
   the usage of one of the host signals as a multiplex for all the target
   signals that are out of range. In order to have the target signal masks
   available, tracking of target signal masks is implemented.

   The rt_sigqueueinfo()/rt_tgsigqueueinfo() system calls multiplex target
   signals by setting the si_errno value to the actual value of the signal
   and sending the signal to a predefined host signal number.
   The host_signal_handler() will pull out the multiplexed signals and set
   their signal number to the correct value. The si_errno field is used
   here but this implementation can be replaced with any other unused field
   in the uinfo structure. Using this implementation both rt_sigqueueinfo(),
   rt_tgsigqueueinfo(), as well as kill() (for pid > 0) and tgkill() can be
   emulated.

   The tkill() system call and kill() with the argument pid <= 0 couldn't
   be implemented simply using this method because it requires acquiring
   information about, and sending simultaneous signals to multiple threads
   or processes. These functionalities are out of the scope of
   rt_sigqueueinfo()/rt_tgsigqueueinfo().

Miloš Stojanović (16):
  linux-user: add strace for getuid(), gettid(), getppid(), geteuid()
  linux-user: add tkill(), tgkill() and rt_sigqueueinfo() strace
  linux-user: fix ssetmask() system call
  linux-user: fix mismatch of lock/unlock_user() invocations in
    rt_sigqueinfo() syscall
  linux-user: fix argument type declaration of rt_sigqueinfo() syscall
  linux-user: add support for rt_tgsigqueueinfo() system call
  linux-user: add rt_tgsigqueueinfo() strace
  linux-user: fix inconsistent spaces in print_siginfo() output
  linux-user: add strace support for uinfo structure of
    rt_sigqueueinfo() and rt_tgsigqueueinfo()
  [RFC] linux-user: add support for tracking the target signal mask
  [RFC] linux-user: add target_sigdelset() and target_sigorset()
  [RFC] linux-user: fix sigismember() check
  [RFC] linux-user: add functions for working with the target signal
    mask
  [RFC] linux-user: add functionality for tracking target signal mask
  [RFC] linux-user: add support for multiplexing larger target signals
  [RFC] linux-user: add support for multiplexing signals in
    rt_sigqueueinfo(), rt_tgsigqueueinfo(), kill() and tgkill()
    syscalls.

 linux-user/qemu.h         |  11 +++
 linux-user/signal.c       | 235 +++++++++++++++++++++++++++++++++++++++++++++-
 linux-user/strace.c       | 177 ++++++++++++++++++++++++++++++++--
 linux-user/strace.list    |  16 ++--
 linux-user/syscall.c      | 208 +++++++++++++++++++++++++++++++++++++---
 linux-user/syscall_defs.h |  32 +++++++
 6 files changed, 651 insertions(+), 28 deletions(-)

-- 
1.9.1


Re: [Qemu-devel] [PATCH v2 00/16] Augment support for signal handling
Posted by Peter Maydell 6 years, 9 months ago
On 15 May 2017 at 15:59, Miloš Stojanović <Milos.Stojanovic@rt-rk.com> wrote:
> D. Add support for larger target signal range (RFC patches 10-16):
>
>    Add target signal mask tracking and multiplexing of target signals out
>    of the host range. The patches are marked as RFC because they introduce
>    significant new functionalities regarding signal handling in QEMU.
>
>    Currently, QEMU has a copy of the host signal and suspend masks and
>    that is usually enough, since most of the time the signal mask of the
>    target architecture is either the same length or narrower. If however
>    the signal mask is wider, then part of it won't be tracked. The signals
>    that are in the target range but out of the host range were treated like
>    faulty signals and couldn't be used. This problem is solved by enabling
>    the usage of one of the host signals as a multiplex for all the target
>    signals that are out of range. In order to have the target signal masks
>    available, tracking of target signal masks is implemented.
>
>    The rt_sigqueueinfo()/rt_tgsigqueueinfo() system calls multiplex target
>    signals by setting the si_errno value to the actual value of the signal
>    and sending the signal to a predefined host signal number.
>    The host_signal_handler() will pull out the multiplexed signals and set
>    their signal number to the correct value. The si_errno field is used
>    here but this implementation can be replaced with any other unused field
>    in the uinfo structure. Using this implementation both rt_sigqueueinfo(),
>    rt_tgsigqueueinfo(), as well as kill() (for pid > 0) and tgkill() can be
>    emulated.
>
>    The tkill() system call and kill() with the argument pid <= 0 couldn't
>    be implemented simply using this method because it requires acquiring
>    information about, and sending simultaneous signals to multiple threads
>    or processes. These functionalities are out of the scope of
>    rt_sigqueueinfo()/rt_tgsigqueueinfo().

This certainly sounds good -- can it fix our problems with clashes
between the host libc and guest libc use of signals?

I do wonder if this is opening up subtle bugs, though: if the
guest does:
  * block signal X
  * some syscall
  * unblock X

then we shouldn't interrupt the syscall if signal X arrives.
That works when we use host signal X for guest signal X because
we just block host signal X. But I don't see how it works if X
has to be multiplexed.

As an implementation point: I see you've implemented this with
ifdefs. I think that if we're going to do it we should do it
always, because it's always the case that there are guest signals
that we can't directly represent with host signals, because of
the host libc stealing a couple for its internal use, so we always
need to multiplex at least a few signals. It also makes it easier
to reason about and test if everything is using the same code paths.

thanks
-- PMM