mirror of
https://github.com/torvalds/linux.git
synced 2024-11-14 08:02:07 +00:00
369842658a
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>
384 lines
10 KiB
ArmAsm
384 lines
10 KiB
ArmAsm
/*
|
|
* linux/arch/arm/kernel/calls.S
|
|
*
|
|
* Copyright (C) 1995-2005 Russell King
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License version 2 as
|
|
* published by the Free Software Foundation.
|
|
*
|
|
* This file is included thrice in entry-common.S
|
|
*/
|
|
/* 0 */ CALL(sys_restart_syscall)
|
|
CALL(sys_exit)
|
|
CALL(sys_fork_wrapper)
|
|
CALL(sys_read)
|
|
CALL(sys_write)
|
|
/* 5 */ CALL(sys_open)
|
|
CALL(sys_close)
|
|
CALL(sys_ni_syscall) /* was sys_waitpid */
|
|
CALL(sys_creat)
|
|
CALL(sys_link)
|
|
/* 10 */ CALL(sys_unlink)
|
|
CALL(sys_execve_wrapper)
|
|
CALL(sys_chdir)
|
|
CALL(OBSOLETE(sys_time)) /* used by libc4 */
|
|
CALL(sys_mknod)
|
|
/* 15 */ CALL(sys_chmod)
|
|
CALL(sys_lchown16)
|
|
CALL(sys_ni_syscall) /* was sys_break */
|
|
CALL(sys_ni_syscall) /* was sys_stat */
|
|
CALL(sys_lseek)
|
|
/* 20 */ CALL(sys_getpid)
|
|
CALL(sys_mount)
|
|
CALL(OBSOLETE(sys_oldumount)) /* used by libc4 */
|
|
CALL(sys_setuid16)
|
|
CALL(sys_getuid16)
|
|
/* 25 */ CALL(OBSOLETE(sys_stime))
|
|
CALL(sys_ptrace)
|
|
CALL(OBSOLETE(sys_alarm)) /* used by libc4 */
|
|
CALL(sys_ni_syscall) /* was sys_fstat */
|
|
CALL(sys_pause)
|
|
/* 30 */ CALL(OBSOLETE(sys_utime)) /* used by libc4 */
|
|
CALL(sys_ni_syscall) /* was sys_stty */
|
|
CALL(sys_ni_syscall) /* was sys_getty */
|
|
CALL(sys_access)
|
|
CALL(sys_nice)
|
|
/* 35 */ CALL(sys_ni_syscall) /* was sys_ftime */
|
|
CALL(sys_sync)
|
|
CALL(sys_kill)
|
|
CALL(sys_rename)
|
|
CALL(sys_mkdir)
|
|
/* 40 */ CALL(sys_rmdir)
|
|
CALL(sys_dup)
|
|
CALL(sys_pipe)
|
|
CALL(sys_times)
|
|
CALL(sys_ni_syscall) /* was sys_prof */
|
|
/* 45 */ CALL(sys_brk)
|
|
CALL(sys_setgid16)
|
|
CALL(sys_getgid16)
|
|
CALL(sys_ni_syscall) /* was sys_signal */
|
|
CALL(sys_geteuid16)
|
|
/* 50 */ CALL(sys_getegid16)
|
|
CALL(sys_acct)
|
|
CALL(sys_umount)
|
|
CALL(sys_ni_syscall) /* was sys_lock */
|
|
CALL(sys_ioctl)
|
|
/* 55 */ CALL(sys_fcntl)
|
|
CALL(sys_ni_syscall) /* was sys_mpx */
|
|
CALL(sys_setpgid)
|
|
CALL(sys_ni_syscall) /* was sys_ulimit */
|
|
CALL(sys_ni_syscall) /* was sys_olduname */
|
|
/* 60 */ CALL(sys_umask)
|
|
CALL(sys_chroot)
|
|
CALL(sys_ustat)
|
|
CALL(sys_dup2)
|
|
CALL(sys_getppid)
|
|
/* 65 */ CALL(sys_getpgrp)
|
|
CALL(sys_setsid)
|
|
CALL(sys_sigaction)
|
|
CALL(sys_ni_syscall) /* was sys_sgetmask */
|
|
CALL(sys_ni_syscall) /* was sys_ssetmask */
|
|
/* 70 */ CALL(sys_setreuid16)
|
|
CALL(sys_setregid16)
|
|
CALL(sys_sigsuspend)
|
|
CALL(sys_sigpending)
|
|
CALL(sys_sethostname)
|
|
/* 75 */ CALL(sys_setrlimit)
|
|
CALL(OBSOLETE(sys_old_getrlimit)) /* used by libc4 */
|
|
CALL(sys_getrusage)
|
|
CALL(sys_gettimeofday)
|
|
CALL(sys_settimeofday)
|
|
/* 80 */ CALL(sys_getgroups16)
|
|
CALL(sys_setgroups16)
|
|
CALL(OBSOLETE(old_select)) /* used by libc4 */
|
|
CALL(sys_symlink)
|
|
CALL(sys_ni_syscall) /* was sys_lstat */
|
|
/* 85 */ CALL(sys_readlink)
|
|
CALL(sys_uselib)
|
|
CALL(sys_swapon)
|
|
CALL(sys_reboot)
|
|
CALL(OBSOLETE(sys_old_readdir)) /* used by libc4 */
|
|
/* 90 */ CALL(OBSOLETE(old_mmap)) /* used by libc4 */
|
|
CALL(sys_munmap)
|
|
CALL(sys_truncate)
|
|
CALL(sys_ftruncate)
|
|
CALL(sys_fchmod)
|
|
/* 95 */ CALL(sys_fchown16)
|
|
CALL(sys_getpriority)
|
|
CALL(sys_setpriority)
|
|
CALL(sys_ni_syscall) /* was sys_profil */
|
|
CALL(sys_statfs)
|
|
/* 100 */ CALL(sys_fstatfs)
|
|
CALL(sys_ni_syscall) /* sys_ioperm */
|
|
CALL(OBSOLETE(ABI(sys_socketcall, sys_oabi_socketcall)))
|
|
CALL(sys_syslog)
|
|
CALL(sys_setitimer)
|
|
/* 105 */ CALL(sys_getitimer)
|
|
CALL(sys_newstat)
|
|
CALL(sys_newlstat)
|
|
CALL(sys_newfstat)
|
|
CALL(sys_ni_syscall) /* was sys_uname */
|
|
/* 110 */ CALL(sys_ni_syscall) /* was sys_iopl */
|
|
CALL(sys_vhangup)
|
|
CALL(sys_ni_syscall)
|
|
CALL(OBSOLETE(sys_syscall)) /* call a syscall */
|
|
CALL(sys_wait4)
|
|
/* 115 */ CALL(sys_swapoff)
|
|
CALL(sys_sysinfo)
|
|
CALL(OBSOLETE(ABI(sys_ipc, sys_oabi_ipc)))
|
|
CALL(sys_fsync)
|
|
CALL(sys_sigreturn_wrapper)
|
|
/* 120 */ CALL(sys_clone_wrapper)
|
|
CALL(sys_setdomainname)
|
|
CALL(sys_newuname)
|
|
CALL(sys_ni_syscall) /* modify_ldt */
|
|
CALL(sys_adjtimex)
|
|
/* 125 */ CALL(sys_mprotect)
|
|
CALL(sys_sigprocmask)
|
|
CALL(sys_ni_syscall) /* was sys_create_module */
|
|
CALL(sys_init_module)
|
|
CALL(sys_delete_module)
|
|
/* 130 */ CALL(sys_ni_syscall) /* was sys_get_kernel_syms */
|
|
CALL(sys_quotactl)
|
|
CALL(sys_getpgid)
|
|
CALL(sys_fchdir)
|
|
CALL(sys_bdflush)
|
|
/* 135 */ CALL(sys_sysfs)
|
|
CALL(sys_personality)
|
|
CALL(sys_ni_syscall) /* reserved for afs_syscall */
|
|
CALL(sys_setfsuid16)
|
|
CALL(sys_setfsgid16)
|
|
/* 140 */ CALL(sys_llseek)
|
|
CALL(sys_getdents)
|
|
CALL(sys_select)
|
|
CALL(sys_flock)
|
|
CALL(sys_msync)
|
|
/* 145 */ CALL(sys_readv)
|
|
CALL(sys_writev)
|
|
CALL(sys_getsid)
|
|
CALL(sys_fdatasync)
|
|
CALL(sys_sysctl)
|
|
/* 150 */ CALL(sys_mlock)
|
|
CALL(sys_munlock)
|
|
CALL(sys_mlockall)
|
|
CALL(sys_munlockall)
|
|
CALL(sys_sched_setparam)
|
|
/* 155 */ CALL(sys_sched_getparam)
|
|
CALL(sys_sched_setscheduler)
|
|
CALL(sys_sched_getscheduler)
|
|
CALL(sys_sched_yield)
|
|
CALL(sys_sched_get_priority_max)
|
|
/* 160 */ CALL(sys_sched_get_priority_min)
|
|
CALL(sys_sched_rr_get_interval)
|
|
CALL(sys_nanosleep)
|
|
CALL(sys_arm_mremap)
|
|
CALL(sys_setresuid16)
|
|
/* 165 */ CALL(sys_getresuid16)
|
|
CALL(sys_ni_syscall) /* vm86 */
|
|
CALL(sys_ni_syscall) /* was sys_query_module */
|
|
CALL(sys_poll)
|
|
CALL(sys_nfsservctl)
|
|
/* 170 */ CALL(sys_setresgid16)
|
|
CALL(sys_getresgid16)
|
|
CALL(sys_prctl)
|
|
CALL(sys_rt_sigreturn_wrapper)
|
|
CALL(sys_rt_sigaction)
|
|
/* 175 */ CALL(sys_rt_sigprocmask)
|
|
CALL(sys_rt_sigpending)
|
|
CALL(sys_rt_sigtimedwait)
|
|
CALL(sys_rt_sigqueueinfo)
|
|
CALL(sys_rt_sigsuspend)
|
|
/* 180 */ CALL(ABI(sys_pread64, sys_oabi_pread64))
|
|
CALL(ABI(sys_pwrite64, sys_oabi_pwrite64))
|
|
CALL(sys_chown16)
|
|
CALL(sys_getcwd)
|
|
CALL(sys_capget)
|
|
/* 185 */ CALL(sys_capset)
|
|
CALL(sys_sigaltstack_wrapper)
|
|
CALL(sys_sendfile)
|
|
CALL(sys_ni_syscall) /* getpmsg */
|
|
CALL(sys_ni_syscall) /* putpmsg */
|
|
/* 190 */ CALL(sys_vfork_wrapper)
|
|
CALL(sys_getrlimit)
|
|
CALL(sys_mmap2)
|
|
CALL(ABI(sys_truncate64, sys_oabi_truncate64))
|
|
CALL(ABI(sys_ftruncate64, sys_oabi_ftruncate64))
|
|
/* 195 */ CALL(ABI(sys_stat64, sys_oabi_stat64))
|
|
CALL(ABI(sys_lstat64, sys_oabi_lstat64))
|
|
CALL(ABI(sys_fstat64, sys_oabi_fstat64))
|
|
CALL(sys_lchown)
|
|
CALL(sys_getuid)
|
|
/* 200 */ CALL(sys_getgid)
|
|
CALL(sys_geteuid)
|
|
CALL(sys_getegid)
|
|
CALL(sys_setreuid)
|
|
CALL(sys_setregid)
|
|
/* 205 */ CALL(sys_getgroups)
|
|
CALL(sys_setgroups)
|
|
CALL(sys_fchown)
|
|
CALL(sys_setresuid)
|
|
CALL(sys_getresuid)
|
|
/* 210 */ CALL(sys_setresgid)
|
|
CALL(sys_getresgid)
|
|
CALL(sys_chown)
|
|
CALL(sys_setuid)
|
|
CALL(sys_setgid)
|
|
/* 215 */ CALL(sys_setfsuid)
|
|
CALL(sys_setfsgid)
|
|
CALL(sys_getdents64)
|
|
CALL(sys_pivot_root)
|
|
CALL(sys_mincore)
|
|
/* 220 */ CALL(sys_madvise)
|
|
CALL(ABI(sys_fcntl64, sys_oabi_fcntl64))
|
|
CALL(sys_ni_syscall) /* TUX */
|
|
CALL(sys_ni_syscall)
|
|
CALL(sys_gettid)
|
|
/* 225 */ CALL(ABI(sys_readahead, sys_oabi_readahead))
|
|
CALL(sys_setxattr)
|
|
CALL(sys_lsetxattr)
|
|
CALL(sys_fsetxattr)
|
|
CALL(sys_getxattr)
|
|
/* 230 */ CALL(sys_lgetxattr)
|
|
CALL(sys_fgetxattr)
|
|
CALL(sys_listxattr)
|
|
CALL(sys_llistxattr)
|
|
CALL(sys_flistxattr)
|
|
/* 235 */ CALL(sys_removexattr)
|
|
CALL(sys_lremovexattr)
|
|
CALL(sys_fremovexattr)
|
|
CALL(sys_tkill)
|
|
CALL(sys_sendfile64)
|
|
/* 240 */ CALL(sys_futex)
|
|
CALL(sys_sched_setaffinity)
|
|
CALL(sys_sched_getaffinity)
|
|
CALL(sys_io_setup)
|
|
CALL(sys_io_destroy)
|
|
/* 245 */ CALL(sys_io_getevents)
|
|
CALL(sys_io_submit)
|
|
CALL(sys_io_cancel)
|
|
CALL(sys_exit_group)
|
|
CALL(sys_lookup_dcookie)
|
|
/* 250 */ CALL(sys_epoll_create)
|
|
CALL(ABI(sys_epoll_ctl, sys_oabi_epoll_ctl))
|
|
CALL(ABI(sys_epoll_wait, sys_oabi_epoll_wait))
|
|
CALL(sys_remap_file_pages)
|
|
CALL(sys_ni_syscall) /* sys_set_thread_area */
|
|
/* 255 */ CALL(sys_ni_syscall) /* sys_get_thread_area */
|
|
CALL(sys_set_tid_address)
|
|
CALL(sys_timer_create)
|
|
CALL(sys_timer_settime)
|
|
CALL(sys_timer_gettime)
|
|
/* 260 */ CALL(sys_timer_getoverrun)
|
|
CALL(sys_timer_delete)
|
|
CALL(sys_clock_settime)
|
|
CALL(sys_clock_gettime)
|
|
CALL(sys_clock_getres)
|
|
/* 265 */ CALL(sys_clock_nanosleep)
|
|
CALL(sys_statfs64_wrapper)
|
|
CALL(sys_fstatfs64_wrapper)
|
|
CALL(sys_tgkill)
|
|
CALL(sys_utimes)
|
|
/* 270 */ CALL(sys_arm_fadvise64_64)
|
|
CALL(sys_pciconfig_iobase)
|
|
CALL(sys_pciconfig_read)
|
|
CALL(sys_pciconfig_write)
|
|
CALL(sys_mq_open)
|
|
/* 275 */ CALL(sys_mq_unlink)
|
|
CALL(sys_mq_timedsend)
|
|
CALL(sys_mq_timedreceive)
|
|
CALL(sys_mq_notify)
|
|
CALL(sys_mq_getsetattr)
|
|
/* 280 */ CALL(sys_waitid)
|
|
CALL(sys_socket)
|
|
CALL(ABI(sys_bind, sys_oabi_bind))
|
|
CALL(ABI(sys_connect, sys_oabi_connect))
|
|
CALL(sys_listen)
|
|
/* 285 */ CALL(sys_accept)
|
|
CALL(sys_getsockname)
|
|
CALL(sys_getpeername)
|
|
CALL(sys_socketpair)
|
|
CALL(sys_send)
|
|
/* 290 */ CALL(ABI(sys_sendto, sys_oabi_sendto))
|
|
CALL(sys_recv)
|
|
CALL(sys_recvfrom)
|
|
CALL(sys_shutdown)
|
|
CALL(sys_setsockopt)
|
|
/* 295 */ CALL(sys_getsockopt)
|
|
CALL(ABI(sys_sendmsg, sys_oabi_sendmsg))
|
|
CALL(sys_recvmsg)
|
|
CALL(ABI(sys_semop, sys_oabi_semop))
|
|
CALL(sys_semget)
|
|
/* 300 */ CALL(sys_semctl)
|
|
CALL(sys_msgsnd)
|
|
CALL(sys_msgrcv)
|
|
CALL(sys_msgget)
|
|
CALL(sys_msgctl)
|
|
/* 305 */ CALL(sys_shmat)
|
|
CALL(sys_shmdt)
|
|
CALL(sys_shmget)
|
|
CALL(sys_shmctl)
|
|
CALL(sys_add_key)
|
|
/* 310 */ CALL(sys_request_key)
|
|
CALL(sys_keyctl)
|
|
CALL(ABI(sys_semtimedop, sys_oabi_semtimedop))
|
|
/* vserver */ CALL(sys_ni_syscall)
|
|
CALL(sys_ioprio_set)
|
|
/* 315 */ CALL(sys_ioprio_get)
|
|
CALL(sys_inotify_init)
|
|
CALL(sys_inotify_add_watch)
|
|
CALL(sys_inotify_rm_watch)
|
|
CALL(sys_mbind)
|
|
/* 320 */ CALL(sys_get_mempolicy)
|
|
CALL(sys_set_mempolicy)
|
|
CALL(sys_openat)
|
|
CALL(sys_mkdirat)
|
|
CALL(sys_mknodat)
|
|
/* 325 */ CALL(sys_fchownat)
|
|
CALL(sys_futimesat)
|
|
CALL(ABI(sys_fstatat64, sys_oabi_fstatat64))
|
|
CALL(sys_unlinkat)
|
|
CALL(sys_renameat)
|
|
/* 330 */ CALL(sys_linkat)
|
|
CALL(sys_symlinkat)
|
|
CALL(sys_readlinkat)
|
|
CALL(sys_fchmodat)
|
|
CALL(sys_faccessat)
|
|
/* 335 */ CALL(sys_pselect6)
|
|
CALL(sys_ppoll)
|
|
CALL(sys_unshare)
|
|
CALL(sys_set_robust_list)
|
|
CALL(sys_get_robust_list)
|
|
/* 340 */ CALL(sys_splice)
|
|
CALL(sys_sync_file_range2)
|
|
CALL(sys_tee)
|
|
CALL(sys_vmsplice)
|
|
CALL(sys_move_pages)
|
|
/* 345 */ CALL(sys_getcpu)
|
|
CALL(sys_epoll_pwait)
|
|
CALL(sys_kexec_load)
|
|
CALL(sys_utimensat)
|
|
CALL(sys_signalfd)
|
|
/* 350 */ CALL(sys_timerfd_create)
|
|
CALL(sys_eventfd)
|
|
CALL(sys_fallocate)
|
|
CALL(sys_timerfd_settime)
|
|
CALL(sys_timerfd_gettime)
|
|
/* 355 */ CALL(sys_signalfd4)
|
|
CALL(sys_eventfd2)
|
|
CALL(sys_epoll_create1)
|
|
CALL(sys_dup3)
|
|
CALL(sys_pipe2)
|
|
/* 360 */ CALL(sys_inotify_init1)
|
|
CALL(sys_preadv)
|
|
CALL(sys_pwritev)
|
|
CALL(sys_rt_tgsigqueueinfo)
|
|
CALL(sys_perf_counter_open)
|
|
#ifndef syscalls_counted
|
|
.equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls
|
|
#define syscalls_counted
|
|
#endif
|
|
.rept syscalls_padding
|
|
CALL(sys_ni_syscall)
|
|
.endr
|