aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavide Libenzi <davidel@xmailserver.org>2007-05-11 01:23:13 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-05-11 11:29:36 -0400
commitfba2afaaec790dc5ab4ae8827972f342211bbb86 (patch)
tree2694d4cd8c6b7d69a5569b92151d61a3d4af39b7
parent5dc8bf8132d59c03fe2562bce165c2f03f021687 (diff)
signal/timer/event: signalfd core
This patch series implements the new signalfd() system call. I took part of the original Linus code (and you know how badly it can be broken :), and I added even more breakage ;) Signals are fetched from the same signal queue used by the process, so signalfd will compete with standard kernel delivery in dequeue_signal(). If you want to reliably fetch signals on the signalfd file, you need to block them with sigprocmask(SIG_BLOCK). This seems to be working fine on my Dual Opteron machine. I made a quick test program for it: http://www.xmailserver.org/signafd-test.c The signalfd() system call implements signal delivery into a file descriptor receiver. The signalfd file descriptor if created with the following API: int signalfd(int ufd, const sigset_t *mask, size_t masksize); The "ufd" parameter allows to change an existing signalfd sigmask, w/out going to close/create cycle (Linus idea). Use "ufd" == -1 if you want a brand new signalfd file. The "mask" allows to specify the signal mask of signals that we are interested in. The "masksize" parameter is the size of "mask". The signalfd fd supports the poll(2) and read(2) system calls. The poll(2) will return POLLIN when signals are available to be dequeued. As a direct consequence of supporting the Linux poll subsystem, the signalfd fd can use used together with epoll(2) too. The read(2) system call will return a "struct signalfd_siginfo" structure in the userspace supplied buffer. The return value is the number of bytes copied in the supplied buffer, or -1 in case of error. The read(2) call can also return 0, in case the sighand structure to which the signalfd was attached, has been orphaned. The O_NONBLOCK flag is also supported, and read(2) will return -EAGAIN in case no signal is available. If the size of the buffer passed to read(2) is lower than sizeof(struct signalfd_siginfo), -EINVAL is returned. A read from the signalfd can also return -ERESTARTSYS in case a signal hits the process. The format of the struct signalfd_siginfo is, and the valid fields depends of the (->code & __SI_MASK) value, in the same way a struct siginfo would: struct signalfd_siginfo { __u32 signo; /* si_signo */ __s32 err; /* si_errno */ __s32 code; /* si_code */ __u32 pid; /* si_pid */ __u32 uid; /* si_uid */ __s32 fd; /* si_fd */ __u32 tid; /* si_fd */ __u32 band; /* si_band */ __u32 overrun; /* si_overrun */ __u32 trapno; /* si_trapno */ __s32 status; /* si_status */ __s32 svint; /* si_int */ __u64 svptr; /* si_ptr */ __u64 utime; /* si_utime */ __u64 stime; /* si_stime */ __u64 addr; /* si_addr */ }; [akpm@linux-foundation.org: fix signalfd_copyinfo() on i386] Signed-off-by: Davide Libenzi <davidel@xmailserver.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--fs/Makefile1
-rw-r--r--fs/exec.c11
-rw-r--r--fs/signalfd.c349
-rw-r--r--include/linux/Kbuild1
-rw-r--r--include/linux/init_task.h1
-rw-r--r--include/linux/sched.h1
-rw-r--r--include/linux/signal.h1
-rw-r--r--include/linux/signalfd.h97
-rw-r--r--include/linux/syscalls.h1
-rw-r--r--init/Kconfig10
-rw-r--r--kernel/exit.c9
-rw-r--r--kernel/fork.c8
-rw-r--r--kernel/signal.c22
-rw-r--r--kernel/sys_ni.c3
14 files changed, 508 insertions, 7 deletions
diff --git a/fs/Makefile b/fs/Makefile
index b5cd46a88cb0..cd8a57aeac04 100644
--- a/fs/Makefile
+++ b/fs/Makefile
@@ -23,6 +23,7 @@ obj-$(CONFIG_INOTIFY) += inotify.o
23obj-$(CONFIG_INOTIFY_USER) += inotify_user.o 23obj-$(CONFIG_INOTIFY_USER) += inotify_user.o
24obj-$(CONFIG_EPOLL) += eventpoll.o 24obj-$(CONFIG_EPOLL) += eventpoll.o
25obj-$(CONFIG_ANON_INODES) += anon_inodes.o 25obj-$(CONFIG_ANON_INODES) += anon_inodes.o
26obj-$(CONFIG_SIGNALFD) += signalfd.o
26obj-$(CONFIG_COMPAT) += compat.o compat_ioctl.o 27obj-$(CONFIG_COMPAT) += compat.o compat_ioctl.o
27 28
28nfsd-$(CONFIG_NFSD) := nfsctl.o 29nfsd-$(CONFIG_NFSD) := nfsctl.o
diff --git a/fs/exec.c b/fs/exec.c
index 2255dc72deef..955a8eb66d70 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -50,6 +50,7 @@
50#include <linux/tsacct_kern.h> 50#include <linux/tsacct_kern.h>
51#include <linux/cn_proc.h> 51#include <linux/cn_proc.h>
52#include <linux/audit.h> 52#include <linux/audit.h>
53#include <linux/signalfd.h>
53 54
54#include <asm/uaccess.h> 55#include <asm/uaccess.h>
55#include <asm/mmu_context.h> 56#include <asm/mmu_context.h>
@@ -582,6 +583,13 @@ static int de_thread(struct task_struct *tsk)
582 int count; 583 int count;
583 584
584 /* 585 /*
586 * Tell all the sighand listeners that this sighand has
587 * been detached. The signalfd_detach() function grabs the
588 * sighand lock, if signal listeners are present on the sighand.
589 */
590 signalfd_detach(tsk);
591
592 /*
585 * If we don't share sighandlers, then we aren't sharing anything 593 * If we don't share sighandlers, then we aren't sharing anything
586 * and we can just re-use it all. 594 * and we can just re-use it all.
587 */ 595 */
@@ -757,8 +765,7 @@ no_thread_group:
757 spin_unlock(&oldsighand->siglock); 765 spin_unlock(&oldsighand->siglock);
758 write_unlock_irq(&tasklist_lock); 766 write_unlock_irq(&tasklist_lock);
759 767
760 if (atomic_dec_and_test(&oldsighand->count)) 768 __cleanup_sighand(oldsighand);
761 kmem_cache_free(sighand_cachep, oldsighand);
762 } 769 }
763 770
764 BUG_ON(!thread_group_leader(tsk)); 771 BUG_ON(!thread_group_leader(tsk));
diff --git a/fs/signalfd.c b/fs/signalfd.c
new file mode 100644
index 000000000000..7cfeab412b45
--- /dev/null
+++ b/fs/signalfd.c
@@ -0,0 +1,349 @@
1/*
2 * fs/signalfd.c
3 *
4 * Copyright (C) 2003 Linus Torvalds
5 *
6 * Mon Mar 5, 2007: Davide Libenzi <davidel@xmailserver.org>
7 * Changed ->read() to return a siginfo strcture instead of signal number.
8 * Fixed locking in ->poll().
9 * Added sighand-detach notification.
10 * Added fd re-use in sys_signalfd() syscall.
11 * Now using anonymous inode source.
12 * Thanks to Oleg Nesterov for useful code review and suggestions.
13 * More comments and suggestions from Arnd Bergmann.
14 */
15
16#include <linux/file.h>
17#include <linux/poll.h>
18#include <linux/init.h>
19#include <linux/fs.h>
20#include <linux/sched.h>
21#include <linux/kernel.h>
22#include <linux/signal.h>
23#include <linux/list.h>
24#include <linux/anon_inodes.h>
25#include <linux/signalfd.h>
26
27struct signalfd_ctx {
28 struct list_head lnk;
29 wait_queue_head_t wqh;
30 sigset_t sigmask;
31 struct task_struct *tsk;
32};
33
34struct signalfd_lockctx {
35 struct task_struct *tsk;
36 unsigned long flags;
37};
38
39/*
40 * Tries to acquire the sighand lock. We do not increment the sighand
41 * use count, and we do not even pin the task struct, so we need to
42 * do it inside an RCU read lock, and we must be prepared for the
43 * ctx->tsk going to NULL (in signalfd_deliver()), and for the sighand
44 * being detached. We return 0 if the sighand has been detached, or
45 * 1 if we were able to pin the sighand lock.
46 */
47static int signalfd_lock(struct signalfd_ctx *ctx, struct signalfd_lockctx *lk)
48{
49 struct sighand_struct *sighand = NULL;
50
51 rcu_read_lock();
52 lk->tsk = rcu_dereference(ctx->tsk);
53 if (likely(lk->tsk != NULL))
54 sighand = lock_task_sighand(lk->tsk, &lk->flags);
55 rcu_read_unlock();
56
57 if (sighand && !ctx->tsk) {
58 unlock_task_sighand(lk->tsk, &lk->flags);
59 sighand = NULL;
60 }
61
62 return sighand != NULL;
63}
64
65static void signalfd_unlock(struct signalfd_lockctx *lk)
66{
67 unlock_task_sighand(lk->tsk, &lk->flags);
68}
69
70/*
71 * This must be called with the sighand lock held.
72 */
73void signalfd_deliver(struct task_struct *tsk, int sig)
74{
75 struct sighand_struct *sighand = tsk->sighand;
76 struct signalfd_ctx *ctx, *tmp;
77
78 BUG_ON(!sig);
79 list_for_each_entry_safe(ctx, tmp, &sighand->signalfd_list, lnk) {
80 /*
81 * We use a negative signal value as a way to broadcast that the
82 * sighand has been orphaned, so that we can notify all the
83 * listeners about this. Remember the ctx->sigmask is inverted,
84 * so if the user is interested in a signal, that corresponding
85 * bit will be zero.
86 */
87 if (sig < 0) {
88 if (ctx->tsk == tsk) {
89 ctx->tsk = NULL;
90 list_del_init(&ctx->lnk);
91 wake_up(&ctx->wqh);
92 }
93 } else {
94 if (!sigismember(&ctx->sigmask, sig))
95 wake_up(&ctx->wqh);
96 }
97 }
98}
99
100static void signalfd_cleanup(struct signalfd_ctx *ctx)
101{
102 struct signalfd_lockctx lk;
103
104 /*
105 * This is tricky. If the sighand is gone, we do not need to remove
106 * context from the list, the list itself won't be there anymore.
107 */
108 if (signalfd_lock(ctx, &lk)) {
109 list_del(&ctx->lnk);
110 signalfd_unlock(&lk);
111 }
112 kfree(ctx);
113}
114
115static int signalfd_release(struct inode *inode, struct file *file)
116{
117 signalfd_cleanup(file->private_data);
118 return 0;
119}
120
121static unsigned int signalfd_poll(struct file *file, poll_table *wait)
122{
123 struct signalfd_ctx *ctx = file->private_data;
124 unsigned int events = 0;
125 struct signalfd_lockctx lk;
126
127 poll_wait(file, &ctx->wqh, wait);
128
129 /*
130 * Let the caller get a POLLIN in this case, ala socket recv() when
131 * the peer disconnects.
132 */
133 if (signalfd_lock(ctx, &lk)) {
134 if (next_signal(&lk.tsk->pending, &ctx->sigmask) > 0 ||
135 next_signal(&lk.tsk->signal->shared_pending,
136 &ctx->sigmask) > 0)
137 events |= POLLIN;
138 signalfd_unlock(&lk);
139 } else
140 events |= POLLIN;
141
142 return events;
143}
144
145/*
146 * Copied from copy_siginfo_to_user() in kernel/signal.c
147 */
148static int signalfd_copyinfo(struct signalfd_siginfo __user *uinfo,
149 siginfo_t const *kinfo)
150{
151 long err;
152
153 BUILD_BUG_ON(sizeof(struct signalfd_siginfo) != 128);
154
155 /*
156 * Unused memebers should be zero ...
157 */
158 err = __clear_user(uinfo, sizeof(*uinfo));
159
160 /*
161 * If you change siginfo_t structure, please be sure
162 * this code is fixed accordingly.
163 */
164 err |= __put_user(kinfo->si_signo, &uinfo->signo);
165 err |= __put_user(kinfo->si_errno, &uinfo->err);
166 err |= __put_user((short)kinfo->si_code, &uinfo->code);
167 switch (kinfo->si_code & __SI_MASK) {
168 case __SI_KILL:
169 err |= __put_user(kinfo->si_pid, &uinfo->pid);
170 err |= __put_user(kinfo->si_uid, &uinfo->uid);
171 break;
172 case __SI_TIMER:
173 err |= __put_user(kinfo->si_tid, &uinfo->tid);
174 err |= __put_user(kinfo->si_overrun, &uinfo->overrun);
175 err |= __put_user((long)kinfo->si_ptr, &uinfo->svptr);
176 break;
177 case __SI_POLL:
178 err |= __put_user(kinfo->si_band, &uinfo->band);
179 err |= __put_user(kinfo->si_fd, &uinfo->fd);
180 break;
181 case __SI_FAULT:
182 err |= __put_user((long)kinfo->si_addr, &uinfo->addr);
183#ifdef __ARCH_SI_TRAPNO
184 err |= __put_user(kinfo->si_trapno, &uinfo->trapno);
185#endif
186 break;
187 case __SI_CHLD:
188 err |= __put_user(kinfo->si_pid, &uinfo->pid);
189 err |= __put_user(kinfo->si_uid, &uinfo->uid);
190 err |= __put_user(kinfo->si_status, &uinfo->status);
191 err |= __put_user(kinfo->si_utime, &uinfo->utime);
192 err |= __put_user(kinfo->si_stime, &uinfo->stime);
193 break;
194 case __SI_RT: /* This is not generated by the kernel as of now. */
195 case __SI_MESGQ: /* But this is */
196 err |= __put_user(kinfo->si_pid, &uinfo->pid);
197 err |= __put_user(kinfo->si_uid, &uinfo->uid);
198 err |= __put_user((long)kinfo->si_ptr, &uinfo->svptr);
199 break;
200 default: /* this is just in case for now ... */
201 err |= __put_user(kinfo->si_pid, &uinfo->pid);
202 err |= __put_user(kinfo->si_uid, &uinfo->uid);
203 break;
204 }
205
206 return err ? -EFAULT: sizeof(*uinfo);
207}
208
209/*
210 * Returns either the size of a "struct signalfd_siginfo", or zero if the
211 * sighand we are attached to, has been orphaned. The "count" parameter
212 * must be at least the size of a "struct signalfd_siginfo".
213 */
214static ssize_t signalfd_read(struct file *file, char __user *buf, size_t count,
215 loff_t *ppos)
216{
217 struct signalfd_ctx *ctx = file->private_data;
218 ssize_t res = 0;
219 int locked, signo;
220 siginfo_t info;
221 struct signalfd_lockctx lk;
222 DECLARE_WAITQUEUE(wait, current);
223
224 if (count < sizeof(struct signalfd_siginfo))
225 return -EINVAL;
226 locked = signalfd_lock(ctx, &lk);
227 if (!locked)
228 return 0;
229 res = -EAGAIN;
230 signo = dequeue_signal(lk.tsk, &ctx->sigmask, &info);
231 if (signo == 0 && !(file->f_flags & O_NONBLOCK)) {
232 add_wait_queue(&ctx->wqh, &wait);
233 for (;;) {
234 set_current_state(TASK_INTERRUPTIBLE);
235 signo = dequeue_signal(lk.tsk, &ctx->sigmask, &info);
236 if (signo != 0)
237 break;
238 if (signal_pending(current)) {
239 res = -ERESTARTSYS;
240 break;
241 }
242 signalfd_unlock(&lk);
243 schedule();
244 locked = signalfd_lock(ctx, &lk);
245 if (unlikely(!locked)) {
246 /*
247 * Let the caller read zero byte, ala socket
248 * recv() when the peer disconnect. This test
249 * must be done before doing a dequeue_signal(),
250 * because if the sighand has been orphaned,
251 * the dequeue_signal() call is going to crash.
252 */
253 res = 0;
254 break;
255 }
256 }
257 remove_wait_queue(&ctx->wqh, &wait);
258 __set_current_state(TASK_RUNNING);
259 }
260 if (likely(locked))
261 signalfd_unlock(&lk);
262 if (likely(signo))
263 res = signalfd_copyinfo((struct signalfd_siginfo __user *) buf,
264 &info);
265
266 return res;
267}
268
269static const struct file_operations signalfd_fops = {
270 .release = signalfd_release,
271 .poll = signalfd_poll,
272 .read = signalfd_read,
273};
274
275/*
276 * Create a file descriptor that is associated with our signal
277 * state. We can pass it around to others if we want to, but
278 * it will always be _our_ signal state.
279 */
280asmlinkage long sys_signalfd(int ufd, sigset_t __user *user_mask, size_t sizemask)
281{
282 int error;
283 sigset_t sigmask;
284 struct signalfd_ctx *ctx;
285 struct sighand_struct *sighand;
286 struct file *file;
287 struct inode *inode;
288 struct signalfd_lockctx lk;
289
290 if (sizemask != sizeof(sigset_t) ||
291 copy_from_user(&sigmask, user_mask, sizeof(sigmask)))
292 return error = -EINVAL;
293 sigdelsetmask(&sigmask, sigmask(SIGKILL) | sigmask(SIGSTOP));
294 signotset(&sigmask);
295
296 if (ufd == -1) {
297 ctx = kmalloc(sizeof(*ctx), GFP_KERNEL);
298 if (!ctx)
299 return -ENOMEM;
300
301 init_waitqueue_head(&ctx->wqh);
302 ctx->sigmask = sigmask;
303 ctx->tsk = current;
304
305 sighand = current->sighand;
306 /*
307 * Add this fd to the list of signal listeners.
308 */
309 spin_lock_irq(&sighand->siglock);
310 list_add_tail(&ctx->lnk, &sighand->signalfd_list);
311 spin_unlock_irq(&sighand->siglock);
312
313 /*
314 * When we call this, the initialization must be complete, since
315 * anon_inode_getfd() will install the fd.
316 */
317 error = anon_inode_getfd(&ufd, &inode, &file, "[signalfd]",
318 &signalfd_fops, ctx);
319 if (error)
320 goto err_fdalloc;
321 } else {
322 file = fget(ufd);
323 if (!file)
324 return -EBADF;
325 ctx = file->private_data;
326 if (file->f_op != &signalfd_fops) {
327 fput(file);
328 return -EINVAL;
329 }
330 /*
331 * We need to be prepared of the fact that the sighand this fd
332 * is attached to, has been detched. In that case signalfd_lock()
333 * will return 0, and we'll just skip setting the new mask.
334 */
335 if (signalfd_lock(ctx, &lk)) {
336 ctx->sigmask = sigmask;
337 signalfd_unlock(&lk);
338 }
339 wake_up(&ctx->wqh);
340 fput(file);
341 }
342
343 return ufd;
344
345err_fdalloc:
346 signalfd_cleanup(ctx);
347 return error;
348}
349
diff --git a/include/linux/Kbuild b/include/linux/Kbuild
index 645b3b528150..bcd01f269f60 100644
--- a/include/linux/Kbuild
+++ b/include/linux/Kbuild
@@ -190,6 +190,7 @@ unifdef-y += errno.h
190unifdef-y += errqueue.h 190unifdef-y += errqueue.h
191unifdef-y += ethtool.h 191unifdef-y += ethtool.h
192unifdef-y += eventpoll.h 192unifdef-y += eventpoll.h
193unifdef-y += signalfd.h
193unifdef-y += ext2_fs.h 194unifdef-y += ext2_fs.h
194unifdef-y += ext3_fs.h 195unifdef-y += ext3_fs.h
195unifdef-y += fb.h 196unifdef-y += fb.h
diff --git a/include/linux/init_task.h b/include/linux/init_task.h
index 66e2f0a70814..276ccaa2670c 100644
--- a/include/linux/init_task.h
+++ b/include/linux/init_task.h
@@ -84,6 +84,7 @@ extern struct nsproxy init_nsproxy;
84 .count = ATOMIC_INIT(1), \ 84 .count = ATOMIC_INIT(1), \
85 .action = { { { .sa_handler = NULL, } }, }, \ 85 .action = { { { .sa_handler = NULL, } }, }, \
86 .siglock = __SPIN_LOCK_UNLOCKED(sighand.siglock), \ 86 .siglock = __SPIN_LOCK_UNLOCKED(sighand.siglock), \
87 .signalfd_list = LIST_HEAD_INIT(sighand.signalfd_list), \
87} 88}
88 89
89extern struct group_info init_groups; 90extern struct group_info init_groups;
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 75f44379b7e9..97c0c7da58ef 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -391,6 +391,7 @@ struct sighand_struct {
391 atomic_t count; 391 atomic_t count;
392 struct k_sigaction action[_NSIG]; 392 struct k_sigaction action[_NSIG];
393 spinlock_t siglock; 393 spinlock_t siglock;
394 struct list_head signalfd_list;
394}; 395};
395 396
396struct pacct_struct { 397struct pacct_struct {
diff --git a/include/linux/signal.h b/include/linux/signal.h
index 3fa0fab4a04b..9a5eac508e5e 100644
--- a/include/linux/signal.h
+++ b/include/linux/signal.h
@@ -233,6 +233,7 @@ static inline int valid_signal(unsigned long sig)
233 return sig <= _NSIG ? 1 : 0; 233 return sig <= _NSIG ? 1 : 0;
234} 234}
235 235
236extern int next_signal(struct sigpending *pending, sigset_t *mask);
236extern int group_send_sig_info(int sig, struct siginfo *info, struct task_struct *p); 237extern int group_send_sig_info(int sig, struct siginfo *info, struct task_struct *p);
237extern int __group_send_sig_info(int, struct siginfo *, struct task_struct *); 238extern int __group_send_sig_info(int, struct siginfo *, struct task_struct *);
238extern long do_sigpending(void __user *, unsigned long); 239extern long do_sigpending(void __user *, unsigned long);
diff --git a/include/linux/signalfd.h b/include/linux/signalfd.h
new file mode 100644
index 000000000000..510429495690
--- /dev/null
+++ b/include/linux/signalfd.h
@@ -0,0 +1,97 @@
1/*
2 * include/linux/signalfd.h
3 *
4 * Copyright (C) 2007 Davide Libenzi <davidel@xmailserver.org>
5 *
6 */
7
8#ifndef _LINUX_SIGNALFD_H
9#define _LINUX_SIGNALFD_H
10
11
12struct signalfd_siginfo {
13 __u32 signo;
14 __s32 err;
15 __s32 code;
16 __u32 pid;
17 __u32 uid;
18 __s32 fd;
19 __u32 tid;
20 __u32 band;
21 __u32 overrun;
22 __u32 trapno;
23 __s32 status;
24 __s32 svint;
25 __u64 svptr;
26 __u64 utime;
27 __u64 stime;
28 __u64 addr;
29
30 /*
31 * Pad strcture to 128 bytes. Remember to update the
32 * pad size when you add new memebers. We use a fixed
33 * size structure to avoid compatibility problems with
34 * future versions, and we leave extra space for additional
35 * members. We use fixed size members because this strcture
36 * comes out of a read(2) and we really don't want to have
37 * a compat on read(2).
38 */
39 __u8 __pad[48];
40};
41
42
43#ifdef __KERNEL__
44
45#ifdef CONFIG_SIGNALFD
46
47/*
48 * Deliver the signal to listening signalfd. This must be called
49 * with the sighand lock held. Same are the following that end up
50 * calling signalfd_deliver().
51 */
52void signalfd_deliver(struct task_struct *tsk, int sig);
53
54/*
55 * No need to fall inside signalfd_deliver() if no signal listeners
56 * are available.
57 */
58static inline void signalfd_notify(struct task_struct *tsk, int sig)
59{
60 if (unlikely(!list_empty(&tsk->sighand->signalfd_list)))
61 signalfd_deliver(tsk, sig);
62}
63
64/*
65 * The signal -1 is used to notify the signalfd that the sighand
66 * is on its way to be detached.
67 */
68static inline void signalfd_detach_locked(struct task_struct *tsk)
69{
70 if (unlikely(!list_empty(&tsk->sighand->signalfd_list)))
71 signalfd_deliver(tsk, -1);
72}
73
74static inline void signalfd_detach(struct task_struct *tsk)
75{
76 struct sighand_struct *sighand = tsk->sighand;
77
78 if (unlikely(!list_empty(&sighand->signalfd_list))) {
79 spin_lock_irq(&sighand->siglock);
80 signalfd_deliver(tsk, -1);
81 spin_unlock_irq(&sighand->siglock);
82 }
83}
84
85#else /* CONFIG_SIGNALFD */
86
87#define signalfd_deliver(t, s) do { } while (0)
88#define signalfd_notify(t, s) do { } while (0)
89#define signalfd_detach_locked(t) do { } while (0)
90#define signalfd_detach(t) do { } while (0)
91
92#endif /* CONFIG_SIGNALFD */
93
94#endif /* __KERNEL__ */
95
96#endif /* _LINUX_SIGNALFD_H */
97
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
index 3139f4412297..e049f14a75b7 100644
--- a/include/linux/syscalls.h
+++ b/include/linux/syscalls.h
@@ -604,6 +604,7 @@ asmlinkage long sys_get_robust_list(int pid,
604asmlinkage long sys_set_robust_list(struct robust_list_head __user *head, 604asmlinkage long sys_set_robust_list(struct robust_list_head __user *head,
605 size_t len); 605 size_t len);
606asmlinkage long sys_getcpu(unsigned __user *cpu, unsigned __user *node, struct getcpu_cache __user *cache); 606asmlinkage long sys_getcpu(unsigned __user *cpu, unsigned __user *node, struct getcpu_cache __user *cache);
607asmlinkage long sys_signalfd(int ufd, sigset_t __user *user_mask, size_t sizemask);
607 608
608int kernel_execve(const char *filename, char *const argv[], char *const envp[]); 609int kernel_execve(const char *filename, char *const argv[], char *const envp[]);
609 610
diff --git a/init/Kconfig b/init/Kconfig
index a80bd8326bc6..db707204b751 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -492,6 +492,16 @@ config EPOLL
492 Disabling this option will cause the kernel to be built without 492 Disabling this option will cause the kernel to be built without
493 support for epoll family of system calls. 493 support for epoll family of system calls.
494 494
495config SIGNALFD
496 bool "Enable signalfd() system call" if EMBEDDED
497 depends on ANON_INODES
498 default y
499 help
500 Enable the signalfd() system call that allows to receive signals
501 on a file descriptor.
502
503 If unsure, say Y.
504
495config SHMEM 505config SHMEM
496 bool "Use full shmem filesystem" if EMBEDDED 506 bool "Use full shmem filesystem" if EMBEDDED
497 default y 507 default y
diff --git a/kernel/exit.c b/kernel/exit.c
index e93691e9b325..c6d14b8008dd 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -24,6 +24,7 @@
24#include <linux/pid_namespace.h> 24#include <linux/pid_namespace.h>
25#include <linux/ptrace.h> 25#include <linux/ptrace.h>
26#include <linux/profile.h> 26#include <linux/profile.h>
27#include <linux/signalfd.h>
27#include <linux/mount.h> 28#include <linux/mount.h>
28#include <linux/proc_fs.h> 29#include <linux/proc_fs.h>
29#include <linux/kthread.h> 30#include <linux/kthread.h>
@@ -83,6 +84,14 @@ static void __exit_signal(struct task_struct *tsk)
83 sighand = rcu_dereference(tsk->sighand); 84 sighand = rcu_dereference(tsk->sighand);
84 spin_lock(&sighand->siglock); 85 spin_lock(&sighand->siglock);
85 86
87 /*
88 * Notify that this sighand has been detached. This must
89 * be called with the tsk->sighand lock held. Also, this
90 * access tsk->sighand internally, so it must be called
91 * before tsk->sighand is reset.
92 */
93 signalfd_detach_locked(tsk);
94
86 posix_cpu_timers_exit(tsk); 95 posix_cpu_timers_exit(tsk);
87 if (atomic_dec_and_test(&sig->count)) 96 if (atomic_dec_and_test(&sig->count))
88 posix_cpu_timers_exit_group(tsk); 97 posix_cpu_timers_exit_group(tsk);
diff --git a/kernel/fork.c b/kernel/fork.c
index 083bf8953ce8..49530e40ea8b 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -1422,12 +1422,15 @@ long do_fork(unsigned long clone_flags,
1422#define ARCH_MIN_MMSTRUCT_ALIGN 0 1422#define ARCH_MIN_MMSTRUCT_ALIGN 0
1423#endif 1423#endif
1424 1424
1425static void sighand_ctor(void *data, struct kmem_cache *cachep, unsigned long flags) 1425static void sighand_ctor(void *data, struct kmem_cache *cachep,
1426 unsigned long flags)
1426{ 1427{
1427 struct sighand_struct *sighand = data; 1428 struct sighand_struct *sighand = data;
1428 1429
1429 if (flags & SLAB_CTOR_CONSTRUCTOR) 1430 if (flags & SLAB_CTOR_CONSTRUCTOR) {
1430 spin_lock_init(&sighand->siglock); 1431 spin_lock_init(&sighand->siglock);
1432 INIT_LIST_HEAD(&sighand->signalfd_list);
1433 }
1431} 1434}
1432 1435
1433void __init proc_caches_init(void) 1436void __init proc_caches_init(void)
@@ -1453,7 +1456,6 @@ void __init proc_caches_init(void)
1453 SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL, NULL); 1456 SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL, NULL);
1454} 1457}
1455 1458
1456
1457/* 1459/*
1458 * Check constraints on flags passed to the unshare system call and 1460 * Check constraints on flags passed to the unshare system call and
1459 * force unsharing of additional process context as appropriate. 1461 * force unsharing of additional process context as appropriate.
diff --git a/kernel/signal.c b/kernel/signal.c
index 2ac3a668d9dd..34b7d6abce8f 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -21,6 +21,7 @@
21#include <linux/syscalls.h> 21#include <linux/syscalls.h>
22#include <linux/ptrace.h> 22#include <linux/ptrace.h>
23#include <linux/signal.h> 23#include <linux/signal.h>
24#include <linux/signalfd.h>
24#include <linux/capability.h> 25#include <linux/capability.h>
25#include <linux/freezer.h> 26#include <linux/freezer.h>
26#include <linux/pid_namespace.h> 27#include <linux/pid_namespace.h>
@@ -113,8 +114,7 @@ void recalc_sigpending(void)
113 114
114/* Given the mask, find the first available signal that should be serviced. */ 115/* Given the mask, find the first available signal that should be serviced. */
115 116
116static int 117int next_signal(struct sigpending *pending, sigset_t *mask)
117next_signal(struct sigpending *pending, sigset_t *mask)
118{ 118{
119 unsigned long i, *s, *m, x; 119 unsigned long i, *s, *m, x;
120 int sig = 0; 120 int sig = 0;
@@ -630,6 +630,12 @@ static int send_signal(int sig, struct siginfo *info, struct task_struct *t,
630 int ret = 0; 630 int ret = 0;
631 631
632 /* 632 /*
633 * Deliver the signal to listening signalfds. This must be called
634 * with the sighand lock held.
635 */
636 signalfd_notify(t, sig);
637
638 /*
633 * fast-pathed signals for kernel-internal things like SIGSTOP 639 * fast-pathed signals for kernel-internal things like SIGSTOP
634 * or SIGKILL. 640 * or SIGKILL.
635 */ 641 */
@@ -1280,6 +1286,11 @@ int send_sigqueue(int sig, struct sigqueue *q, struct task_struct *p)
1280 ret = 1; 1286 ret = 1;
1281 goto out; 1287 goto out;
1282 } 1288 }
1289 /*
1290 * Deliver the signal to listening signalfds. This must be called
1291 * with the sighand lock held.
1292 */
1293 signalfd_notify(p, sig);
1283 1294
1284 list_add_tail(&q->list, &p->pending.list); 1295 list_add_tail(&q->list, &p->pending.list);
1285 sigaddset(&p->pending.signal, sig); 1296 sigaddset(&p->pending.signal, sig);
@@ -1323,6 +1334,11 @@ send_group_sigqueue(int sig, struct sigqueue *q, struct task_struct *p)
1323 q->info.si_overrun++; 1334 q->info.si_overrun++;
1324 goto out; 1335 goto out;
1325 } 1336 }
1337 /*
1338 * Deliver the signal to listening signalfds. This must be called
1339 * with the sighand lock held.
1340 */
1341 signalfd_notify(p, sig);
1326 1342
1327 /* 1343 /*
1328 * Put this signal on the shared-pending queue. 1344 * Put this signal on the shared-pending queue.
@@ -1983,6 +1999,8 @@ int copy_siginfo_to_user(siginfo_t __user *to, siginfo_t *from)
1983 /* 1999 /*
1984 * If you change siginfo_t structure, please be sure 2000 * If you change siginfo_t structure, please be sure
1985 * this code is fixed accordingly. 2001 * this code is fixed accordingly.
2002 * Please remember to update the signalfd_copyinfo() function
2003 * inside fs/signalfd.c too, in case siginfo_t changes.
1986 * It should never copy any pad contained in the structure 2004 * It should never copy any pad contained in the structure
1987 * to avoid security leaks, but must copy the generic 2005 * to avoid security leaks, but must copy the generic
1988 * 3 ints plus the relevant union member. 2006 * 3 ints plus the relevant union member.
diff --git a/kernel/sys_ni.c b/kernel/sys_ni.c
index d7306d0f3dfc..807e9bb8fcdb 100644
--- a/kernel/sys_ni.c
+++ b/kernel/sys_ni.c
@@ -141,3 +141,6 @@ cond_syscall(compat_sys_migrate_pages);
141cond_syscall(sys_bdflush); 141cond_syscall(sys_bdflush);
142cond_syscall(sys_ioprio_set); 142cond_syscall(sys_ioprio_set);
143cond_syscall(sys_ioprio_get); 143cond_syscall(sys_ioprio_get);
144
145/* New file descriptors */
146cond_syscall(sys_signalfd);