diff options
author | Mikael Pettersson <mikpe@it.uu.se> | 2009-08-15 07:58:11 -0400 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2009-08-15 10:10:31 -0400 |
commit | 369842658a36bcea28ecb643ba4bdb53919330dd (patch) | |
tree | 1a590eabceea85b974360eca2cfba54d86ae4933 /arch/arm/kernel/calls.S | |
parent | 4bf1fa5a34aa2dd0d2cc58f0fc213a2e22d007a4 (diff) |
ARM: 5677/1: ARM support for TIF_RESTORE_SIGMASK/pselect6/ppoll/epoll_pwait
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 ¤t->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: Mikael Pettersson <mikpe@it.uu.se>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/kernel/calls.S')
-rw-r--r-- | arch/arm/kernel/calls.S | 10 |
1 files changed, 5 insertions, 5 deletions
diff --git a/arch/arm/kernel/calls.S b/arch/arm/kernel/calls.S index f776e72a4cb8..ecfa98954d1d 100644 --- a/arch/arm/kernel/calls.S +++ b/arch/arm/kernel/calls.S | |||
@@ -81,7 +81,7 @@ | |||
81 | CALL(sys_ni_syscall) /* was sys_ssetmask */ | 81 | CALL(sys_ni_syscall) /* was sys_ssetmask */ |
82 | /* 70 */ CALL(sys_setreuid16) | 82 | /* 70 */ CALL(sys_setreuid16) |
83 | CALL(sys_setregid16) | 83 | CALL(sys_setregid16) |
84 | CALL(sys_sigsuspend_wrapper) | 84 | CALL(sys_sigsuspend) |
85 | CALL(sys_sigpending) | 85 | CALL(sys_sigpending) |
86 | CALL(sys_sethostname) | 86 | CALL(sys_sethostname) |
87 | /* 75 */ CALL(sys_setrlimit) | 87 | /* 75 */ CALL(sys_setrlimit) |
@@ -188,7 +188,7 @@ | |||
188 | CALL(sys_rt_sigpending) | 188 | CALL(sys_rt_sigpending) |
189 | CALL(sys_rt_sigtimedwait) | 189 | CALL(sys_rt_sigtimedwait) |
190 | CALL(sys_rt_sigqueueinfo) | 190 | CALL(sys_rt_sigqueueinfo) |
191 | CALL(sys_rt_sigsuspend_wrapper) | 191 | CALL(sys_rt_sigsuspend) |
192 | /* 180 */ CALL(ABI(sys_pread64, sys_oabi_pread64)) | 192 | /* 180 */ CALL(ABI(sys_pread64, sys_oabi_pread64)) |
193 | CALL(ABI(sys_pwrite64, sys_oabi_pwrite64)) | 193 | CALL(ABI(sys_pwrite64, sys_oabi_pwrite64)) |
194 | CALL(sys_chown16) | 194 | CALL(sys_chown16) |
@@ -344,8 +344,8 @@ | |||
344 | CALL(sys_readlinkat) | 344 | CALL(sys_readlinkat) |
345 | CALL(sys_fchmodat) | 345 | CALL(sys_fchmodat) |
346 | CALL(sys_faccessat) | 346 | CALL(sys_faccessat) |
347 | /* 335 */ CALL(sys_ni_syscall) /* eventually pselect6 */ | 347 | /* 335 */ CALL(sys_pselect6) |
348 | CALL(sys_ni_syscall) /* eventually ppoll */ | 348 | CALL(sys_ppoll) |
349 | CALL(sys_unshare) | 349 | CALL(sys_unshare) |
350 | CALL(sys_set_robust_list) | 350 | CALL(sys_set_robust_list) |
351 | CALL(sys_get_robust_list) | 351 | CALL(sys_get_robust_list) |
@@ -355,7 +355,7 @@ | |||
355 | CALL(sys_vmsplice) | 355 | CALL(sys_vmsplice) |
356 | CALL(sys_move_pages) | 356 | CALL(sys_move_pages) |
357 | /* 345 */ CALL(sys_getcpu) | 357 | /* 345 */ CALL(sys_getcpu) |
358 | CALL(sys_ni_syscall) /* eventually epoll_pwait */ | 358 | CALL(sys_epoll_pwait) |
359 | CALL(sys_kexec_load) | 359 | CALL(sys_kexec_load) |
360 | CALL(sys_utimensat) | 360 | CALL(sys_utimensat) |
361 | CALL(sys_signalfd) | 361 | CALL(sys_signalfd) |