blob: 445156d2d30b15ec6a048a025a9800be57d4019e [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/* signal.c: FRV specific bits of signal handling
2 *
3 * Copyright (C) 2003-5 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com)
5 * - Derived from arch/m68k/kernel/signal.c
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version
10 * 2 of the License, or (at your option) any later version.
11 */
12
13#include <linux/sched.h>
14#include <linux/mm.h>
15#include <linux/smp.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070016#include <linux/kernel.h>
17#include <linux/signal.h>
18#include <linux/errno.h>
19#include <linux/wait.h>
20#include <linux/ptrace.h>
21#include <linux/unistd.h>
22#include <linux/personality.h>
David Howells4a3b9892009-06-11 13:05:24 +010023#include <linux/tracehook.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070024#include <asm/ucontext.h>
25#include <asm/uaccess.h>
26#include <asm/cacheflush.h>
27
28#define DEBUG_SIG 0
29
Linus Torvalds1da177e2005-04-16 15:20:36 -070030struct fdpic_func_descriptor {
31 unsigned long text;
32 unsigned long GOT;
33};
34
Linus Torvalds1da177e2005-04-16 15:20:36 -070035/*
36 * Atomically swap in the new signal mask, and wait for a signal.
37 */
38asmlinkage int sys_sigsuspend(int history0, int history1, old_sigset_t mask)
39{
Al Viro68f3f162012-05-21 21:42:32 -040040 sigset_t blocked;
41 siginitset(&blocked, mask);
42 return sigsuspend(&blocked);
Linus Torvalds1da177e2005-04-16 15:20:36 -070043}
44
45asmlinkage int sys_sigaction(int sig,
46 const struct old_sigaction __user *act,
47 struct old_sigaction __user *oact)
48{
49 struct k_sigaction new_ka, old_ka;
50 int ret;
51
52 if (act) {
53 old_sigset_t mask;
54 if (!access_ok(VERIFY_READ, act, sizeof(*act)) ||
55 __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
Al Virof0c22cd2012-04-22 17:20:02 -040056 __get_user(new_ka.sa.sa_restorer, &act->sa_restorer) ||
57 __get_user(new_ka.sa.sa_flags, &act->sa_flags) ||
58 __get_user(mask, &act->sa_mask))
Linus Torvalds1da177e2005-04-16 15:20:36 -070059 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -070060 siginitset(&new_ka.sa.sa_mask, mask);
61 }
62
63 ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
64
65 if (!ret && oact) {
66 if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) ||
67 __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
Al Virof0c22cd2012-04-22 17:20:02 -040068 __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer) ||
69 __put_user(old_ka.sa.sa_flags, &oact->sa_flags) ||
70 __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask))
Linus Torvalds1da177e2005-04-16 15:20:36 -070071 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -070072 }
73
74 return ret;
75}
76
Linus Torvalds1da177e2005-04-16 15:20:36 -070077/*
78 * Do a signal return; undo the signal stack.
79 */
80
81struct sigframe
82{
Al Viro9e4d11f2006-06-23 02:04:04 -070083 __sigrestore_t pretcode;
Linus Torvalds1da177e2005-04-16 15:20:36 -070084 int sig;
85 struct sigcontext sc;
86 unsigned long extramask[_NSIG_WORDS-1];
87 uint32_t retcode[2];
88};
89
90struct rt_sigframe
91{
Al Viro9e4d11f2006-06-23 02:04:04 -070092 __sigrestore_t pretcode;
Linus Torvalds1da177e2005-04-16 15:20:36 -070093 int sig;
Al Viro9e4d11f2006-06-23 02:04:04 -070094 struct siginfo __user *pinfo;
95 void __user *puc;
Linus Torvalds1da177e2005-04-16 15:20:36 -070096 struct siginfo info;
97 struct ucontext uc;
98 uint32_t retcode[2];
99};
100
101static int restore_sigcontext(struct sigcontext __user *sc, int *_gr8)
102{
103 struct user_context *user = current->thread.user;
104 unsigned long tbr, psr;
105
Al Viro20cd5142010-09-20 15:13:04 +0100106 /* Always make any pending restarted system calls return -EINTR */
107 current_thread_info()->restart_block.fn = do_no_restart_syscall;
108
Linus Torvalds1da177e2005-04-16 15:20:36 -0700109 tbr = user->i.tbr;
110 psr = user->i.psr;
111 if (copy_from_user(user, &sc->sc_context, sizeof(sc->sc_context)))
112 goto badframe;
113 user->i.tbr = tbr;
114 user->i.psr = psr;
115
116 restore_user_regs(user);
117
118 user->i.syscallno = -1; /* disable syscall checks */
119
120 *_gr8 = user->i.gr[8];
121 return 0;
122
123 badframe:
124 return 1;
125}
126
127asmlinkage int sys_sigreturn(void)
128{
129 struct sigframe __user *frame = (struct sigframe __user *) __frame->sp;
130 sigset_t set;
131 int gr8;
132
133 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
134 goto badframe;
135 if (__get_user(set.sig[0], &frame->sc.sc_oldmask))
136 goto badframe;
137
138 if (_NSIG_WORDS > 1 &&
139 __copy_from_user(&set.sig[1], &frame->extramask, sizeof(frame->extramask)))
140 goto badframe;
141
Matt Fleming7ebe0c52012-05-11 10:58:52 +1000142 set_current_blocked(&set);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700143
144 if (restore_sigcontext(&frame->sc, &gr8))
145 goto badframe;
146 return gr8;
147
148 badframe:
149 force_sig(SIGSEGV, current);
150 return 0;
151}
152
153asmlinkage int sys_rt_sigreturn(void)
154{
155 struct rt_sigframe __user *frame = (struct rt_sigframe __user *) __frame->sp;
156 sigset_t set;
157 int gr8;
158
159 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
160 goto badframe;
161 if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
162 goto badframe;
163
Matt Fleming7ebe0c52012-05-11 10:58:52 +1000164 set_current_blocked(&set);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700165
166 if (restore_sigcontext(&frame->uc.uc_mcontext, &gr8))
167 goto badframe;
168
Al Virofe761412012-12-23 02:13:57 -0500169 if (restore_altstack(&frame->uc.uc_stack))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700170 goto badframe;
171
172 return gr8;
173
174badframe:
175 force_sig(SIGSEGV, current);
176 return 0;
177}
178
179/*
180 * Set up a signal frame
181 */
182static int setup_sigcontext(struct sigcontext __user *sc, unsigned long mask)
183{
184 save_user_regs(current->thread.user);
185
186 if (copy_to_user(&sc->sc_context, current->thread.user, sizeof(sc->sc_context)) != 0)
187 goto badframe;
188
189 /* non-iBCS2 extensions.. */
190 if (__put_user(mask, &sc->sc_oldmask) < 0)
191 goto badframe;
192
193 return 0;
194
195 badframe:
196 return 1;
197}
198
199/*****************************************************************************/
200/*
201 * Determine which stack to use..
202 */
203static inline void __user *get_sigframe(struct k_sigaction *ka,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700204 size_t frame_size)
205{
206 unsigned long sp;
207
208 /* Default to using normal stack */
David Howellsfef2b582006-01-06 00:11:45 -0800209 sp = __frame->sp;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700210
211 /* This is the X/Open sanctioned signal stack switching. */
212 if (ka->sa.sa_flags & SA_ONSTACK) {
Laurent MEYERd09042d2006-06-23 02:05:36 -0700213 if (! sas_ss_flags(sp))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700214 sp = current->sas_ss_sp + current->sas_ss_size;
215 }
216
217 return (void __user *) ((sp - frame_size) & ~7UL);
David Howellsfef2b582006-01-06 00:11:45 -0800218
Linus Torvalds1da177e2005-04-16 15:20:36 -0700219} /* end get_sigframe() */
220
221/*****************************************************************************/
222/*
223 *
224 */
David Howellsfef2b582006-01-06 00:11:45 -0800225static int setup_frame(int sig, struct k_sigaction *ka, sigset_t *set)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700226{
227 struct sigframe __user *frame;
228 int rsig;
229
Al Viro5f4ad042010-09-20 15:13:09 +0100230 set_fs(USER_DS);
231
David Howellsfef2b582006-01-06 00:11:45 -0800232 frame = get_sigframe(ka, sizeof(*frame));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700233
234 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
235 goto give_sigsegv;
236
237 rsig = sig;
238 if (sig < 32 &&
239 __current_thread_info->exec_domain &&
240 __current_thread_info->exec_domain->signal_invmap)
241 rsig = __current_thread_info->exec_domain->signal_invmap[sig];
242
243 if (__put_user(rsig, &frame->sig) < 0)
244 goto give_sigsegv;
245
246 if (setup_sigcontext(&frame->sc, set->sig[0]))
247 goto give_sigsegv;
248
249 if (_NSIG_WORDS > 1) {
250 if (__copy_to_user(frame->extramask, &set->sig[1],
251 sizeof(frame->extramask)))
252 goto give_sigsegv;
253 }
254
255 /* Set up to return from userspace. If provided, use a stub
256 * already in userspace. */
257 if (ka->sa.sa_flags & SA_RESTORER) {
258 if (__put_user(ka->sa.sa_restorer, &frame->pretcode) < 0)
259 goto give_sigsegv;
260 }
261 else {
262 /* Set up the following code on the stack:
263 * setlos #__NR_sigreturn,gr7
264 * tira gr0,0
265 */
Al Viro9e4d11f2006-06-23 02:04:04 -0700266 if (__put_user((__sigrestore_t)frame->retcode, &frame->pretcode) ||
Linus Torvalds1da177e2005-04-16 15:20:36 -0700267 __put_user(0x8efc0000|__NR_sigreturn, &frame->retcode[0]) ||
268 __put_user(0xc0700000, &frame->retcode[1]))
269 goto give_sigsegv;
270
271 flush_icache_range((unsigned long) frame->retcode,
272 (unsigned long) (frame->retcode + 2));
273 }
274
Al Viro5f4ad042010-09-20 15:13:09 +0100275 /* Set up registers for the signal handler */
WANG Congecd0fa92008-04-29 00:59:15 -0700276 if (current->personality & FDPIC_FUNCPTRS) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700277 struct fdpic_func_descriptor __user *funcptr =
Al Viro9e4d11f2006-06-23 02:04:04 -0700278 (struct fdpic_func_descriptor __user *) ka->sa.sa_handler;
Al Viro5f4ad042010-09-20 15:13:09 +0100279 struct fdpic_func_descriptor desc;
280 if (copy_from_user(&desc, funcptr, sizeof(desc)))
281 goto give_sigsegv;
282 __frame->pc = desc.text;
283 __frame->gr15 = desc.GOT;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700284 } else {
David Howellsfef2b582006-01-06 00:11:45 -0800285 __frame->pc = (unsigned long) ka->sa.sa_handler;
286 __frame->gr15 = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700287 }
288
Al Viro5f4ad042010-09-20 15:13:09 +0100289 __frame->sp = (unsigned long) frame;
290 __frame->lr = (unsigned long) &frame->retcode;
291 __frame->gr8 = sig;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700292
293#if DEBUG_SIG
294 printk("SIG deliver %d (%s:%d): sp=%p pc=%lx ra=%p\n",
David Howellsfef2b582006-01-06 00:11:45 -0800295 sig, current->comm, current->pid, frame, __frame->pc,
David Howells8efc0ab2006-01-06 00:11:44 -0800296 frame->pretcode);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700297#endif
298
David Howellsa411aee2006-01-18 17:43:59 -0800299 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700300
301give_sigsegv:
Al Viroad0acab2010-09-20 15:13:14 +0100302 force_sigsegv(sig, current);
David Howellsa411aee2006-01-18 17:43:59 -0800303 return -EFAULT;
David Howells8efc0ab2006-01-06 00:11:44 -0800304
Linus Torvalds1da177e2005-04-16 15:20:36 -0700305} /* end setup_frame() */
306
307/*****************************************************************************/
308/*
309 *
310 */
David Howells8efc0ab2006-01-06 00:11:44 -0800311static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
David Howellsfef2b582006-01-06 00:11:45 -0800312 sigset_t *set)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700313{
314 struct rt_sigframe __user *frame;
315 int rsig;
316
Al Viro5f4ad042010-09-20 15:13:09 +0100317 set_fs(USER_DS);
318
David Howellsfef2b582006-01-06 00:11:45 -0800319 frame = get_sigframe(ka, sizeof(*frame));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700320
321 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
322 goto give_sigsegv;
323
324 rsig = sig;
325 if (sig < 32 &&
326 __current_thread_info->exec_domain &&
327 __current_thread_info->exec_domain->signal_invmap)
328 rsig = __current_thread_info->exec_domain->signal_invmap[sig];
329
330 if (__put_user(rsig, &frame->sig) ||
331 __put_user(&frame->info, &frame->pinfo) ||
332 __put_user(&frame->uc, &frame->puc))
333 goto give_sigsegv;
334
335 if (copy_siginfo_to_user(&frame->info, info))
336 goto give_sigsegv;
337
338 /* Create the ucontext. */
339 if (__put_user(0, &frame->uc.uc_flags) ||
Al Viro9e4d11f2006-06-23 02:04:04 -0700340 __put_user(NULL, &frame->uc.uc_link) ||
Al Virofe761412012-12-23 02:13:57 -0500341 __save_altstack(&frame->uc.uc_stack, __frame->sp))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700342 goto give_sigsegv;
343
344 if (setup_sigcontext(&frame->uc.uc_mcontext, set->sig[0]))
345 goto give_sigsegv;
346
347 if (__copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)))
348 goto give_sigsegv;
349
350 /* Set up to return from userspace. If provided, use a stub
351 * already in userspace. */
352 if (ka->sa.sa_flags & SA_RESTORER) {
353 if (__put_user(ka->sa.sa_restorer, &frame->pretcode))
354 goto give_sigsegv;
355 }
356 else {
357 /* Set up the following code on the stack:
358 * setlos #__NR_sigreturn,gr7
359 * tira gr0,0
360 */
Al Viro9e4d11f2006-06-23 02:04:04 -0700361 if (__put_user((__sigrestore_t)frame->retcode, &frame->pretcode) ||
Linus Torvalds1da177e2005-04-16 15:20:36 -0700362 __put_user(0x8efc0000|__NR_rt_sigreturn, &frame->retcode[0]) ||
363 __put_user(0xc0700000, &frame->retcode[1]))
364 goto give_sigsegv;
365
366 flush_icache_range((unsigned long) frame->retcode,
367 (unsigned long) (frame->retcode + 2));
368 }
369
370 /* Set up registers for signal handler */
WANG Congecd0fa92008-04-29 00:59:15 -0700371 if (current->personality & FDPIC_FUNCPTRS) {
Al Viro9e4d11f2006-06-23 02:04:04 -0700372 struct fdpic_func_descriptor __user *funcptr =
Linus Torvalds1da177e2005-04-16 15:20:36 -0700373 (struct fdpic_func_descriptor __user *) ka->sa.sa_handler;
Al Viro5f4ad042010-09-20 15:13:09 +0100374 struct fdpic_func_descriptor desc;
375 if (copy_from_user(&desc, funcptr, sizeof(desc)))
376 goto give_sigsegv;
377 __frame->pc = desc.text;
378 __frame->gr15 = desc.GOT;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700379 } else {
David Howellsfef2b582006-01-06 00:11:45 -0800380 __frame->pc = (unsigned long) ka->sa.sa_handler;
381 __frame->gr15 = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700382 }
383
Al Viro5f4ad042010-09-20 15:13:09 +0100384 __frame->sp = (unsigned long) frame;
385 __frame->lr = (unsigned long) &frame->retcode;
386 __frame->gr8 = sig;
387 __frame->gr9 = (unsigned long) &frame->info;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700388
389#if DEBUG_SIG
390 printk("SIG deliver %d (%s:%d): sp=%p pc=%lx ra=%p\n",
David Howellsfef2b582006-01-06 00:11:45 -0800391 sig, current->comm, current->pid, frame, __frame->pc,
David Howells8efc0ab2006-01-06 00:11:44 -0800392 frame->pretcode);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700393#endif
394
David Howellsa411aee2006-01-18 17:43:59 -0800395 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700396
397give_sigsegv:
Al Viroad0acab2010-09-20 15:13:14 +0100398 force_sigsegv(sig, current);
David Howellsa411aee2006-01-18 17:43:59 -0800399 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700400
401} /* end setup_rt_frame() */
402
403/*****************************************************************************/
404/*
405 * OK, we're invoking a handler
406 */
Al Viroa610d6e2012-05-21 23:42:15 -0400407static void handle_signal(unsigned long sig, siginfo_t *info,
Al Virob7f9a112012-05-02 09:59:21 -0400408 struct k_sigaction *ka)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700409{
Al Virob7f9a112012-05-02 09:59:21 -0400410 sigset_t *oldset = sigmask_to_save();
David Howells8efc0ab2006-01-06 00:11:44 -0800411 int ret;
412
Linus Torvalds1da177e2005-04-16 15:20:36 -0700413 /* Are we from a system call? */
Al Viroed1cde62010-09-20 15:13:25 +0100414 if (__frame->syscallno != -1) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700415 /* If so, check system call restarting.. */
David Howellsfef2b582006-01-06 00:11:45 -0800416 switch (__frame->gr8) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700417 case -ERESTART_RESTARTBLOCK:
418 case -ERESTARTNOHAND:
David Howellsfef2b582006-01-06 00:11:45 -0800419 __frame->gr8 = -EINTR;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700420 break;
421
422 case -ERESTARTSYS:
423 if (!(ka->sa.sa_flags & SA_RESTART)) {
David Howellsfef2b582006-01-06 00:11:45 -0800424 __frame->gr8 = -EINTR;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700425 break;
426 }
David Howells8efc0ab2006-01-06 00:11:44 -0800427
Linus Torvalds1da177e2005-04-16 15:20:36 -0700428 /* fallthrough */
429 case -ERESTARTNOINTR:
David Howellsfef2b582006-01-06 00:11:45 -0800430 __frame->gr8 = __frame->orig_gr8;
431 __frame->pc -= 4;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700432 }
Al Viroed1cde62010-09-20 15:13:25 +0100433 __frame->syscallno = -1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700434 }
435
436 /* Set up the stack frame */
437 if (ka->sa.sa_flags & SA_SIGINFO)
David Howellsfef2b582006-01-06 00:11:45 -0800438 ret = setup_rt_frame(sig, ka, info, oldset);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700439 else
David Howellsfef2b582006-01-06 00:11:45 -0800440 ret = setup_frame(sig, ka, oldset);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700441
Al Viroa610d6e2012-05-21 23:42:15 -0400442 if (ret)
443 return;
David Howells8efc0ab2006-01-06 00:11:44 -0800444
Al Viroefee9842012-04-28 02:04:15 -0400445 signal_delivered(sig, info, ka, __frame,
Al Viroa610d6e2012-05-21 23:42:15 -0400446 test_thread_flag(TIF_SINGLESTEP));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700447} /* end handle_signal() */
448
449/*****************************************************************************/
450/*
451 * Note that 'init' is a special process: it doesn't get signals it doesn't
452 * want to handle. Thus you cannot kill init even with a SIGKILL even by
453 * mistake.
454 */
David Howellsa411aee2006-01-18 17:43:59 -0800455static void do_signal(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700456{
457 struct k_sigaction ka;
458 siginfo_t info;
459 int signr;
460
David Howellsfef2b582006-01-06 00:11:45 -0800461 signr = get_signal_to_deliver(&info, &ka, __frame, NULL);
David Howellsa411aee2006-01-18 17:43:59 -0800462 if (signr > 0) {
Al Viroa610d6e2012-05-21 23:42:15 -0400463 handle_signal(signr, &info, &ka);
David Howellsa411aee2006-01-18 17:43:59 -0800464 return;
465 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700466
Linus Torvalds1da177e2005-04-16 15:20:36 -0700467 /* Did we come from a system call? */
Roel Kluinc896a2e2009-10-26 16:50:23 -0700468 if (__frame->syscallno != -1) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700469 /* Restart the system call - no handlers present */
David Howellsa411aee2006-01-18 17:43:59 -0800470 switch (__frame->gr8) {
471 case -ERESTARTNOHAND:
472 case -ERESTARTSYS:
473 case -ERESTARTNOINTR:
David Howellsfef2b582006-01-06 00:11:45 -0800474 __frame->gr8 = __frame->orig_gr8;
475 __frame->pc -= 4;
David Howellsa411aee2006-01-18 17:43:59 -0800476 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700477
David Howellsa411aee2006-01-18 17:43:59 -0800478 case -ERESTART_RESTARTBLOCK:
Al Viro44c7aff2010-09-20 15:13:19 +0100479 __frame->gr7 = __NR_restart_syscall;
David Howellsfef2b582006-01-06 00:11:45 -0800480 __frame->pc -= 4;
David Howellsa411aee2006-01-18 17:43:59 -0800481 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700482 }
Al Viroed1cde62010-09-20 15:13:25 +0100483 __frame->syscallno = -1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700484 }
485
David Howellsa411aee2006-01-18 17:43:59 -0800486 /* if there's no signal to deliver, we just put the saved sigmask
487 * back */
Al Viro51a7b442012-05-21 23:33:55 -0400488 restore_saved_sigmask();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700489} /* end do_signal() */
490
491/*****************************************************************************/
492/*
493 * notification of userspace execution resumption
David Howellsa411aee2006-01-18 17:43:59 -0800494 * - triggered by the TIF_WORK_MASK flags
Linus Torvalds1da177e2005-04-16 15:20:36 -0700495 */
496asmlinkage void do_notify_resume(__u32 thread_info_flags)
497{
498 /* pending single-step? */
499 if (thread_info_flags & _TIF_SINGLESTEP)
500 clear_thread_flag(TIF_SINGLESTEP);
501
502 /* deal with pending signal delivery */
Geert Uytterhoevena3936242012-06-02 13:08:39 +0200503 if (thread_info_flags & _TIF_SIGPENDING)
David Howellsa411aee2006-01-18 17:43:59 -0800504 do_signal();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700505
David Howellsb7bab882009-06-11 13:05:14 +0100506 /* deal with notification on about to resume userspace execution */
507 if (thread_info_flags & _TIF_NOTIFY_RESUME) {
508 clear_thread_flag(TIF_NOTIFY_RESUME);
David Howells4a3b9892009-06-11 13:05:24 +0100509 tracehook_notify_resume(__frame);
David Howellsb7bab882009-06-11 13:05:14 +0100510 }
511
Linus Torvalds1da177e2005-04-16 15:20:36 -0700512} /* end do_notify_resume() */