• Mikael Pettersson's avatar
    ARM: 5677/1: ARM support for TIF_RESTORE_SIGMASK/pselect6/ppoll/epoll_pwait · 36984265
    Mikael Pettersson authored
    This patch adds support for TIF_RESTORE_SIGMASK to ARM's
    signal handling, which allows to hook up the pselect6, ppoll,
    and epoll_pwait syscalls on ARM.
    
    Tested here with eabi userspace and a test program with a
    deliberate race between a child's exit and the parent's
    sigprocmask/select sequence. Using sys_pselect6() instead
    of sigprocmask/select reliably prevents the race.
    
    The other arch's support for TIF_RESTORE_SIGMASK has evolved
    over time:
    
    In 2.6.16:
    - add TIF_RESTORE_SIGMASK which parallels TIF_SIGPENDING
    - test both when checking for pending signal [changed later]
    - reimplement sys_sigsuspend() to use current->saved_sigmask,
      TIF_RESTORE_SIGMASK [changed later], and -ERESTARTNOHAND;
      ditto for sys_rt_sigsuspend(), but drop private code and
      use common code via __ARCH_WANT_SYS_RT_SIGSUSPEND;
    - there are now no "extra" calls to do_signal() so its oldset
      parameter is always &current->blocked so need not be passed,
      also its return value is changed to void
    - change handle_signal() to return 0/-errno
    - change do_signal() to honor TIF_RESTORE_SIGMASK:
      + get oldset from current->saved_sigmask if TIF_RESTORE_SIGMASK
        is set
      + if handle_signal() was successful then clear TIF_RESTORE_SIGMASK
      + if no signal was delivered and TIF_RESTORE_SIGMASK is set then
        clear it and restore the sigmask
    - hook up sys_pselect6() and sys_ppoll()
    
    In 2.6.19:
    - hook up sys_epoll_pwait()
    
    In 2.6.26:
    - allow archs to override how TIF_RESTORE_SIGMASK is implemented;
      default set_restore_sigmask() sets both TIF_RESTORE_SIGMASK and
      TIF_SIGPENDING; archs need now just test TIF_SIGPENDING again
      when checking for pending signal work; some archs now implement
      TIF_RESTORE_SIGMASK as a secondary/non-atomic thread flag bit
    - call set_restore_sigmask() in sys_sigsuspend() instead of setting
      TIF_RESTORE_SIGMASK
    
    In 2.6.29-rc:
    - kill sys_pselect7() which no arch wanted
    
    So for 2.6.31-rc6/ARM this patch does the following:
    - Add TIF_RESTORE_SIGMASK. Use the generic set_restore_sigmask()
      which sets both TIF_SIGPENDING and TIF_RESTORE_SIGMASK, so
      TIF_RESTORE_SIGMASK need not claim one of the scarce low thread
      flags, and existing TIF_SIGPENDING and _TIF_WORK_MASK tests need
      not be extended for TIF_RESTORE_SIGMASK.
    - sys_sigsuspend() is reimplemented to use current->saved_sigmask
      and set_restore_sigmask(), making it identical to most other archs
    - The private code for sys_rt_sigsuspend() is removed, instead
      generic code supplies it via __ARCH_WANT_SYS_RT_SIGSUSPEND.
    - sys_sigsuspend() and sys_rt_sigsuspend() no longer need a pt_regs
      parameter, so their assembly code wrappers are removed.
    - handle_signal() is changed to return 0 on success or -errno.
    - The oldset parameter to do_signal() is now redundant and removed,
      and the return value is now also redundant and changed to void.
    - do_signal() is changed to honor TIF_RESTORE_SIGMASK:
      + get oldset from current->saved_sigmask if TIF_RESTORE_SIGMASK
        is set
      + if handle_signal() was successful then clear TIF_RESTORE_SIGMASK
      + if no signal was delivered and TIF_RESTORE_SIGMASK is set then
        clear it and restore the sigmask
    - Hook up sys_pselect6, sys_ppoll, and sys_epoll_pwait.
    Signed-off-by: default avatarMikael Pettersson <mikpe@it.uu.se>
    Signed-off-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
    36984265
signal.c 19 KB