Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


Merge branch 'devel'
[palacios.git] / kitten / include / lwk / signal.h
1 #ifndef _LWK_SIGNAL_H
2 #define _LWK_SIGNAL_H
3
4 #include <arch/signal.h>
5 #include <arch/siginfo.h>
6
7 #ifdef __KERNEL__
8 #include <lwk/list.h>
9 #include <lwk/spinlock.h>
10
11 /*
12  * Real Time signals may be queued.
13  */
14
15 struct sigqueue {
16         struct list_head list;
17         int flags;
18         siginfo_t info;
19         struct user_struct *user;
20 };
21
22 /* flags values. */
23 #define SIGQUEUE_PREALLOC       1
24
25 struct sigpending {
26         struct list_head list;
27         sigset_t signal;
28 };
29
30 /*
31  * Define some primitives to manipulate sigset_t.
32  */
33
34 #ifndef __HAVE_ARCH_SIG_BITOPS
35 #include <lwk/bitops.h>
36
37 /* We don't use <lwk/bitops.h> for these because there is no need to
38    be atomic.  */
39 static inline void sigaddset(sigset_t *set, int _sig)
40 {
41         unsigned long sig = _sig - 1;
42         if (_NSIG_WORDS == 1)
43                 set->sig[0] |= 1UL << sig;
44         else
45                 set->sig[sig / _NSIG_BPW] |= 1UL << (sig % _NSIG_BPW);
46 }
47
48 static inline void sigdelset(sigset_t *set, int _sig)
49 {
50         unsigned long sig = _sig - 1;
51         if (_NSIG_WORDS == 1)
52                 set->sig[0] &= ~(1UL << sig);
53         else
54                 set->sig[sig / _NSIG_BPW] &= ~(1UL << (sig % _NSIG_BPW));
55 }
56
57 static inline int sigismember(sigset_t *set, int _sig)
58 {
59         unsigned long sig = _sig - 1;
60         if (_NSIG_WORDS == 1)
61                 return 1 & (set->sig[0] >> sig);
62         else
63                 return 1 & (set->sig[sig / _NSIG_BPW] >> (sig % _NSIG_BPW));
64 }
65
66 static inline int sigfindinword(unsigned long word)
67 {
68         return ffz(~word);
69 }
70
71 #endif /* __HAVE_ARCH_SIG_BITOPS */
72
73 static inline int sigisemptyset(sigset_t *set)
74 {
75         extern void _NSIG_WORDS_is_unsupported_size(void);
76         switch (_NSIG_WORDS) {
77         case 4:
78                 return (set->sig[3] | set->sig[2] |
79                         set->sig[1] | set->sig[0]) == 0;
80         case 2:
81                 return (set->sig[1] | set->sig[0]) == 0;
82         case 1:
83                 return set->sig[0] == 0;
84         default:
85                 _NSIG_WORDS_is_unsupported_size();
86                 return 0;
87         }
88 }
89
90 #define sigmask(sig)    (1UL << ((sig) - 1))
91
92 #ifndef __HAVE_ARCH_SIG_SETOPS
93 #include <lwk/string.h>
94
95 #define _SIG_SET_BINOP(name, op)                                        \
96 static inline void name(sigset_t *r, const sigset_t *a, const sigset_t *b) \
97 {                                                                       \
98         extern void _NSIG_WORDS_is_unsupported_size(void);              \
99         unsigned long a0, a1, a2, a3, b0, b1, b2, b3;                   \
100                                                                         \
101         switch (_NSIG_WORDS) {                                          \
102             case 4:                                                     \
103                 a3 = a->sig[3]; a2 = a->sig[2];                         \
104                 b3 = b->sig[3]; b2 = b->sig[2];                         \
105                 r->sig[3] = op(a3, b3);                                 \
106                 r->sig[2] = op(a2, b2);                                 \
107             case 2:                                                     \
108                 a1 = a->sig[1]; b1 = b->sig[1];                         \
109                 r->sig[1] = op(a1, b1);                                 \
110             case 1:                                                     \
111                 a0 = a->sig[0]; b0 = b->sig[0];                         \
112                 r->sig[0] = op(a0, b0);                                 \
113                 break;                                                  \
114             default:                                                    \
115                 _NSIG_WORDS_is_unsupported_size();                      \
116         }                                                               \
117 }
118
119 #define _sig_or(x,y)    ((x) | (y))
120 _SIG_SET_BINOP(sigorsets, _sig_or)
121
122 #define _sig_and(x,y)   ((x) & (y))
123 _SIG_SET_BINOP(sigandsets, _sig_and)
124
125 #define _sig_nand(x,y)  ((x) & ~(y))
126 _SIG_SET_BINOP(signandsets, _sig_nand)
127
128 #undef _SIG_SET_BINOP
129 #undef _sig_or
130 #undef _sig_and
131 #undef _sig_nand
132
133 #define _SIG_SET_OP(name, op)                                           \
134 static inline void name(sigset_t *set)                                  \
135 {                                                                       \
136         extern void _NSIG_WORDS_is_unsupported_size(void);              \
137                                                                         \
138         switch (_NSIG_WORDS) {                                          \
139             case 4: set->sig[3] = op(set->sig[3]);                      \
140                     set->sig[2] = op(set->sig[2]);                      \
141             case 2: set->sig[1] = op(set->sig[1]);                      \
142             case 1: set->sig[0] = op(set->sig[0]);                      \
143                     break;                                              \
144             default:                                                    \
145                 _NSIG_WORDS_is_unsupported_size();                      \
146         }                                                               \
147 }
148
149 #define _sig_not(x)     (~(x))
150 _SIG_SET_OP(signotset, _sig_not)
151
152 #undef _SIG_SET_OP
153 #undef _sig_not
154
155 static inline void sigemptyset(sigset_t *set)
156 {
157         switch (_NSIG_WORDS) {
158         default:
159                 memset(set, 0, sizeof(sigset_t));
160                 break;
161         case 2: set->sig[1] = 0;
162         case 1: set->sig[0] = 0;
163                 break;
164         }
165 }
166
167 static inline void sigfillset(sigset_t *set)
168 {
169         switch (_NSIG_WORDS) {
170         default:
171                 memset(set, -1, sizeof(sigset_t));
172                 break;
173         case 2: set->sig[1] = -1;
174         case 1: set->sig[0] = -1;
175                 break;
176         }
177 }
178
179 /* Some extensions for manipulating the low 32 signals in particular.  */
180
181 static inline void sigaddsetmask(sigset_t *set, unsigned long mask)
182 {
183         set->sig[0] |= mask;
184 }
185
186 static inline void sigdelsetmask(sigset_t *set, unsigned long mask)
187 {
188         set->sig[0] &= ~mask;
189 }
190
191 static inline int sigtestsetmask(sigset_t *set, unsigned long mask)
192 {
193         return (set->sig[0] & mask) != 0;
194 }
195
196 static inline void siginitset(sigset_t *set, unsigned long mask)
197 {
198         set->sig[0] = mask;
199         switch (_NSIG_WORDS) {
200         default:
201                 memset(&set->sig[1], 0, sizeof(long)*(_NSIG_WORDS-1));
202                 break;
203         case 2: set->sig[1] = 0;
204         case 1: ;
205         }
206 }
207
208 static inline void siginitsetinv(sigset_t *set, unsigned long mask)
209 {
210         set->sig[0] = ~mask;
211         switch (_NSIG_WORDS) {
212         default:
213                 memset(&set->sig[1], -1, sizeof(long)*(_NSIG_WORDS-1));
214                 break;
215         case 2: set->sig[1] = -1;
216         case 1: ;
217         }
218 }
219
220 #endif /* __HAVE_ARCH_SIG_SETOPS */
221
222 static inline void init_sigpending(struct sigpending *sig)
223 {
224         sigemptyset(&sig->signal);
225         INIT_LIST_HEAD(&sig->list);
226 }
227
228 extern void flush_sigqueue(struct sigpending *queue);
229
230 /* Test if 'sig' is valid signal. Use this instead of testing _NSIG directly */
231 static inline int valid_signal(unsigned long sig)
232 {
233         return sig <= _NSIG ? 1 : 0;
234 }
235
236 extern int next_signal(struct sigpending *pending, sigset_t *mask);
237 extern int group_send_sig_info(int sig, struct siginfo *info, struct task_struct *p);
238 extern int __group_send_sig_info(int, struct siginfo *, struct task_struct *);
239 extern long do_sigpending(void __user *, unsigned long);
240 extern int sigprocmask(int, sigset_t *, sigset_t *);
241
242 struct pt_regs;
243 extern int get_signal_to_deliver(siginfo_t *info, struct k_sigaction *return_ka, struct pt_regs *regs, void *cookie);
244
245 extern struct kmem_cache *sighand_cachep;
246
247 /*
248  * In POSIX a signal is sent either to a specific thread (LWK task)
249  * or to the process as a whole (LWK thread group).  How the signal
250  * is sent determines whether it's to one thread or the whole group,
251  * which determines which signal mask(s) are involved in blocking it
252  * from being delivered until later.  When the signal is delivered,
253  * either it's caught or ignored by a user handler or it has a default
254  * effect that applies to the whole thread group (POSIX process).
255  *
256  * The possible effects an unblocked signal set to SIG_DFL can have are:
257  *   ignore     - Nothing Happens
258  *   terminate  - kill the process, i.e. all threads in the group,
259  *                similar to exit_group.  The group leader (only) reports
260  *                WIFSIGNALED status to its parent.
261  *   coredump   - write a core dump file describing all threads using
262  *                the same mm and then kill all those threads
263  *   stop       - stop all the threads in the group, i.e. TASK_STOPPED state
264  *
265  * SIGKILL and SIGSTOP cannot be caught, blocked, or ignored.
266  * Other signals when not blocked and set to SIG_DFL behaves as follows.
267  * The job control signals also have other special effects.
268  *
269  *      +--------------------+------------------+
270  *      |  POSIX signal      |  default action  |
271  *      +--------------------+------------------+
272  *      |  SIGHUP            |  terminate       |
273  *      |  SIGINT            |  terminate       |
274  *      |  SIGQUIT           |  coredump        |
275  *      |  SIGILL            |  coredump        |
276  *      |  SIGTRAP           |  coredump        |
277  *      |  SIGABRT/SIGIOT    |  coredump        |
278  *      |  SIGBUS            |  coredump        |
279  *      |  SIGFPE            |  coredump        |
280  *      |  SIGKILL           |  terminate(+)    |
281  *      |  SIGUSR1           |  terminate       |
282  *      |  SIGSEGV           |  coredump        |
283  *      |  SIGUSR2           |  terminate       |
284  *      |  SIGPIPE           |  terminate       |
285  *      |  SIGALRM           |  terminate       |
286  *      |  SIGTERM           |  terminate       |
287  *      |  SIGCHLD           |  ignore          |
288  *      |  SIGCONT           |  ignore(*)       |
289  *      |  SIGSTOP           |  stop(*)(+)      |
290  *      |  SIGTSTP           |  stop(*)         |
291  *      |  SIGTTIN           |  stop(*)         |
292  *      |  SIGTTOU           |  stop(*)         |
293  *      |  SIGURG            |  ignore          |
294  *      |  SIGXCPU           |  coredump        |
295  *      |  SIGXFSZ           |  coredump        |
296  *      |  SIGVTALRM         |  terminate       |
297  *      |  SIGPROF           |  terminate       |
298  *      |  SIGPOLL/SIGIO     |  terminate       |
299  *      |  SIGSYS/SIGUNUSED  |  coredump        |
300  *      |  SIGSTKFLT         |  terminate       |
301  *      |  SIGWINCH          |  ignore          |
302  *      |  SIGPWR            |  terminate       |
303  *      |  SIGRTMIN-SIGRTMAX |  terminate       |
304  *      +--------------------+------------------+
305  *      |  non-POSIX signal  |  default action  |
306  *      +--------------------+------------------+
307  *      |  SIGEMT            |  coredump        |
308  *      +--------------------+------------------+
309  *
310  * (+) For SIGKILL and SIGSTOP the action is "always", not just "default".
311  * (*) Special job control effects:
312  * When SIGCONT is sent, it resumes the process (all threads in the group)
313  * from TASK_STOPPED state and also clears any pending/queued stop signals
314  * (any of those marked with "stop(*)").  This happens regardless of blocking,
315  * catching, or ignoring SIGCONT.  When any stop signal is sent, it clears
316  * any pending/queued SIGCONT signals; this happens regardless of blocking,
317  * catching, or ignored the stop signal, though (except for SIGSTOP) the
318  * default action of stopping the process may happen later or never.
319  */
320
321 #ifdef SIGEMT
322 #define SIGEMT_MASK     rt_sigmask(SIGEMT)
323 #else
324 #define SIGEMT_MASK     0
325 #endif
326
327 #if SIGRTMIN > BITS_PER_LONG
328 #define rt_sigmask(sig) (1ULL << ((sig)-1))
329 #else
330 #define rt_sigmask(sig) sigmask(sig)
331 #endif
332 #define siginmask(sig, mask) (rt_sigmask(sig) & (mask))
333
334 #define SIG_KERNEL_ONLY_MASK (\
335         rt_sigmask(SIGKILL)   |  rt_sigmask(SIGSTOP))
336
337 #define SIG_KERNEL_STOP_MASK (\
338         rt_sigmask(SIGSTOP)   |  rt_sigmask(SIGTSTP)   | \
339         rt_sigmask(SIGTTIN)   |  rt_sigmask(SIGTTOU)   )
340
341 #define SIG_KERNEL_COREDUMP_MASK (\
342         rt_sigmask(SIGQUIT)   |  rt_sigmask(SIGILL)    | \
343         rt_sigmask(SIGTRAP)   |  rt_sigmask(SIGABRT)   | \
344         rt_sigmask(SIGFPE)    |  rt_sigmask(SIGSEGV)   | \
345         rt_sigmask(SIGBUS)    |  rt_sigmask(SIGSYS)    | \
346         rt_sigmask(SIGXCPU)   |  rt_sigmask(SIGXFSZ)   | \
347         SIGEMT_MASK                                    )
348
349 #define SIG_KERNEL_IGNORE_MASK (\
350         rt_sigmask(SIGCONT)   |  rt_sigmask(SIGCHLD)   | \
351         rt_sigmask(SIGWINCH)  |  rt_sigmask(SIGURG)    )
352
353 #define sig_kernel_only(sig) \
354         (((sig) < SIGRTMIN) && siginmask(sig, SIG_KERNEL_ONLY_MASK))
355 #define sig_kernel_coredump(sig) \
356         (((sig) < SIGRTMIN) && siginmask(sig, SIG_KERNEL_COREDUMP_MASK))
357 #define sig_kernel_ignore(sig) \
358         (((sig) < SIGRTMIN) && siginmask(sig, SIG_KERNEL_IGNORE_MASK))
359 #define sig_kernel_stop(sig) \
360         (((sig) < SIGRTMIN) && siginmask(sig, SIG_KERNEL_STOP_MASK))
361
362 #define sig_needs_tasklist(sig) ((sig) == SIGCONT)
363
364 #define sig_user_defined(t, signr) \
365         (((t)->sighand->action[(signr)-1].sa.sa_handler != SIG_DFL) &&  \
366          ((t)->sighand->action[(signr)-1].sa.sa_handler != SIG_IGN))
367
368 #define sig_fatal(t, signr) \
369         (!siginmask(signr, SIG_KERNEL_IGNORE_MASK|SIG_KERNEL_STOP_MASK) && \
370          (t)->sighand->action[(signr)-1].sa.sa_handler == SIG_DFL)
371
372 #endif /* __KERNEL__ */
373
374 #endif /* _LWK_SIGNAL_H */