1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16#include <linux/sched.h>
17#include <linux/mm.h>
18#include <linux/smp.h>
19#include <linux/kernel.h>
20#include <linux/signal.h>
21#include <linux/errno.h>
22#include <linux/wait.h>
23#include <linux/ptrace.h>
24#include <linux/unistd.h>
25#include <linux/stddef.h>
26
27#include <asm/processor.h>
28#include <asm/ucontext.h>
29#include <asm/uaccess.h>
30
31#define DEBUG_SIG 0
32
33#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
34
35
36
37
38
39
40
41#define RESTART_CRIS_SYS(regs) regs->r10 = regs->orig_r10; regs->irp -= 2;
42
43void do_signal(int canrestart, struct pt_regs *regs);
44
45
46
47
48
49
50int sys_sigsuspend(old_sigset_t mask, long r11, long r12, long r13, long mof,
51 long srp, struct pt_regs *regs)
52{
53 mask &= _BLOCKABLE;
54 spin_lock_irq(¤t->sighand->siglock);
55 current->saved_sigmask = current->blocked;
56 siginitset(¤t->blocked, mask);
57 recalc_sigpending();
58 spin_unlock_irq(¤t->sighand->siglock);
59 current->state = TASK_INTERRUPTIBLE;
60 schedule();
61 set_thread_flag(TIF_RESTORE_SIGMASK);
62 return -ERESTARTNOHAND;
63}
64
65int sys_sigaction(int sig, const struct old_sigaction __user *act,
66 struct old_sigaction *oact)
67{
68 struct k_sigaction new_ka, old_ka;
69 int ret;
70
71 if (act) {
72 old_sigset_t mask;
73 if (!access_ok(VERIFY_READ, act, sizeof(*act)) ||
74 __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
75 __get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
76 return -EFAULT;
77 __get_user(new_ka.sa.sa_flags, &act->sa_flags);
78 __get_user(mask, &act->sa_mask);
79 siginitset(&new_ka.sa.sa_mask, mask);
80 }
81
82 ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
83
84 if (!ret && oact) {
85 if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) ||
86 __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
87 __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
88 return -EFAULT;
89 __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
90 __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
91 }
92
93 return ret;
94}
95
96int sys_sigaltstack(const stack_t *uss, stack_t __user *uoss)
97{
98 return do_sigaltstack(uss, uoss, rdusp());
99}
100
101
102
103
104
105
106struct sigframe {
107 struct sigcontext sc;
108 unsigned long extramask[_NSIG_WORDS-1];
109 unsigned char retcode[8];
110};
111
112struct rt_sigframe {
113 struct siginfo *pinfo;
114 void *puc;
115 struct siginfo info;
116 struct ucontext uc;
117 unsigned char retcode[8];
118};
119
120
121static int
122restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc)
123{
124 unsigned int err = 0;
125 unsigned long old_usp;
126
127
128 current_thread_info()->restart_block.fn = do_no_restart_syscall;
129
130
131
132
133
134
135 if (__copy_from_user(regs, sc, sizeof(struct pt_regs)))
136 goto badframe;
137
138
139
140 regs->dccr |= 1 << 8;
141
142
143
144
145
146
147 err |= __get_user(old_usp, &sc->usp);
148
149 wrusp(old_usp);
150
151
152
153
154
155
156 return err;
157
158badframe:
159 return 1;
160}
161
162
163
164asmlinkage int sys_sigreturn(long r10, long r11, long r12, long r13, long mof,
165 long srp, struct pt_regs *regs)
166{
167 struct sigframe __user *frame = (struct sigframe *)rdusp();
168 sigset_t set;
169
170
171
172
173
174
175 if (((long)frame) & 3)
176 goto badframe;
177
178 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
179 goto badframe;
180 if (__get_user(set.sig[0], &frame->sc.oldmask)
181 || (_NSIG_WORDS > 1
182 && __copy_from_user(&set.sig[1], frame->extramask,
183 sizeof(frame->extramask))))
184 goto badframe;
185
186 sigdelsetmask(&set, ~_BLOCKABLE);
187 spin_lock_irq(¤t->sighand->siglock);
188 current->blocked = set;
189 recalc_sigpending();
190 spin_unlock_irq(¤t->sighand->siglock);
191
192 if (restore_sigcontext(regs, &frame->sc))
193 goto badframe;
194
195
196
197 return regs->r10;
198
199badframe:
200 force_sig(SIGSEGV, current);
201 return 0;
202}
203
204
205
206asmlinkage int sys_rt_sigreturn(long r10, long r11, long r12, long r13,
207 long mof, long srp, struct pt_regs *regs)
208{
209 struct rt_sigframe __user *frame = (struct rt_sigframe *)rdusp();
210 sigset_t set;
211
212
213
214
215
216
217 if (((long)frame) & 3)
218 goto badframe;
219
220 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
221 goto badframe;
222 if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
223 goto badframe;
224
225 sigdelsetmask(&set, ~_BLOCKABLE);
226 spin_lock_irq(¤t->sighand->siglock);
227 current->blocked = set;
228 recalc_sigpending();
229 spin_unlock_irq(¤t->sighand->siglock);
230
231 if (restore_sigcontext(regs, &frame->uc.uc_mcontext))
232 goto badframe;
233
234 if (do_sigaltstack(&frame->uc.uc_stack, NULL, rdusp()) == -EFAULT)
235 goto badframe;
236
237 return regs->r10;
238
239badframe:
240 force_sig(SIGSEGV, current);
241 return 0;
242}
243
244
245
246
247
248static int setup_sigcontext(struct sigcontext __user *sc,
249 struct pt_regs *regs, unsigned long mask)
250{
251 int err = 0;
252 unsigned long usp = rdusp();
253
254
255
256 err |= __copy_to_user(sc, regs, sizeof(struct pt_regs));
257
258
259
260
261 regs->frametype = CRIS_FRAME_NORMAL;
262
263
264
265 err |= __put_user(mask, &sc->oldmask);
266
267 err |= __put_user(usp, &sc->usp);
268
269 return err;
270}
271
272
273
274
275static inline void __user *
276get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size)
277{
278 unsigned long sp = rdusp();
279
280
281 if (ka->sa.sa_flags & SA_ONSTACK) {
282 if (! on_sig_stack(sp))
283 sp = current->sas_ss_sp + current->sas_ss_size;
284 }
285
286
287
288 sp &= ~3;
289
290 return (void __user*)(sp - frame_size);
291}
292
293
294
295
296
297
298
299
300
301static int setup_frame(int sig, struct k_sigaction *ka,
302 sigset_t *set, struct pt_regs *regs)
303{
304 struct sigframe __user *frame;
305 unsigned long return_ip;
306 int err = 0;
307
308 frame = get_sigframe(ka, regs, sizeof(*frame));
309
310 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
311 goto give_sigsegv;
312
313 err |= setup_sigcontext(&frame->sc, regs, set->sig[0]);
314 if (err)
315 goto give_sigsegv;
316
317 if (_NSIG_WORDS > 1) {
318 err |= __copy_to_user(frame->extramask, &set->sig[1],
319 sizeof(frame->extramask));
320 }
321 if (err)
322 goto give_sigsegv;
323
324
325
326 if (ka->sa.sa_flags & SA_RESTORER) {
327 return_ip = (unsigned long)ka->sa.sa_restorer;
328 } else {
329
330 return_ip = (unsigned long)&frame->retcode;
331
332 err |= __put_user(0x9c5f, (short __user*)(frame->retcode+0));
333 err |= __put_user(__NR_sigreturn, (short __user*)(frame->retcode+2));
334 err |= __put_user(0xe93d, (short __user*)(frame->retcode+4));
335 }
336
337 if (err)
338 goto give_sigsegv;
339
340
341
342 regs->irp = (unsigned long) ka->sa.sa_handler;
343 regs->srp = return_ip;
344 regs->r10 = sig;
345
346
347
348 wrusp((unsigned long)frame);
349
350 return 0;
351
352give_sigsegv:
353 force_sigsegv(sig, current);
354 return -EFAULT;
355}
356
357static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
358 sigset_t *set, struct pt_regs *regs)
359{
360 struct rt_sigframe __user *frame;
361 unsigned long return_ip;
362 int err = 0;
363
364 frame = get_sigframe(ka, regs, sizeof(*frame));
365
366 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
367 goto give_sigsegv;
368
369 err |= __put_user(&frame->info, &frame->pinfo);
370 err |= __put_user(&frame->uc, &frame->puc);
371 err |= copy_siginfo_to_user(&frame->info, info);
372 if (err)
373 goto give_sigsegv;
374
375
376 err |= __clear_user(&frame->uc, offsetof(struct ucontext, uc_mcontext));
377
378 err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, set->sig[0]);
379
380 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
381
382 if (err)
383 goto give_sigsegv;
384
385
386
387 if (ka->sa.sa_flags & SA_RESTORER) {
388 return_ip = (unsigned long)ka->sa.sa_restorer;
389 } else {
390
391 return_ip = (unsigned long)&frame->retcode;
392
393 err |= __put_user(0x9c5f, (short __user *)(frame->retcode+0));
394 err |= __put_user(__NR_rt_sigreturn,
395 (short __user *)(frame->retcode+2));
396 err |= __put_user(0xe93d, (short __user *)(frame->retcode+4));
397 }
398
399 if (err)
400 goto give_sigsegv;
401
402
403
404
405
406
407 regs->irp = (unsigned long) ka->sa.sa_handler;
408
409 regs->srp = return_ip;
410
411 regs->r10 = sig;
412
413 regs->r11 = (unsigned long)&frame->info;
414
415 regs->r12 = 0;
416
417
418 wrusp((unsigned long)frame);
419
420 return 0;
421
422give_sigsegv:
423 force_sigsegv(sig, current);
424 return -EFAULT;
425}
426
427
428
429
430
431static inline int handle_signal(int canrestart, unsigned long sig,
432 siginfo_t *info, struct k_sigaction *ka,
433 sigset_t *oldset, struct pt_regs *regs)
434{
435 int ret;
436
437
438 if (canrestart) {
439
440 switch (regs->r10) {
441 case -ERESTART_RESTARTBLOCK:
442 case -ERESTARTNOHAND:
443
444
445
446
447 regs->r10 = -EINTR;
448 break;
449 case -ERESTARTSYS:
450
451
452
453 if (!(ka->sa.sa_flags & SA_RESTART)) {
454 regs->r10 = -EINTR;
455 break;
456 }
457
458 case -ERESTARTNOINTR:
459
460
461 RESTART_CRIS_SYS(regs);
462 }
463 }
464
465
466 if (ka->sa.sa_flags & SA_SIGINFO)
467 ret = setup_rt_frame(sig, ka, info, oldset, regs);
468 else
469 ret = setup_frame(sig, ka, oldset, regs);
470
471 if (ret == 0) {
472 spin_lock_irq(¤t->sighand->siglock);
473 sigorsets(¤t->blocked, ¤t->blocked,
474 &ka->sa.sa_mask);
475 if (!(ka->sa.sa_flags & SA_NODEFER))
476 sigaddset(¤t->blocked, sig);
477 recalc_sigpending();
478 spin_unlock_irq(¤t->sighand->siglock);
479 }
480 return ret;
481}
482
483
484
485
486
487
488
489
490
491
492
493
494
495void do_signal(int canrestart, struct pt_regs *regs)
496{
497 siginfo_t info;
498 int signr;
499 struct k_sigaction ka;
500 sigset_t *oldset;
501
502
503
504
505
506
507
508 if (!user_mode(regs))
509 return;
510
511 if (test_thread_flag(TIF_RESTORE_SIGMASK))
512 oldset = ¤t->saved_sigmask;
513 else
514 oldset = ¤t->blocked;
515
516 signr = get_signal_to_deliver(&info, &ka, regs, NULL);
517 if (signr > 0) {
518
519 if (handle_signal(canrestart, signr, &info, &ka,
520 oldset, regs)) {
521
522
523
524
525 if (test_thread_flag(TIF_RESTORE_SIGMASK))
526 clear_thread_flag(TIF_RESTORE_SIGMASK);
527 }
528 return;
529 }
530
531
532 if (canrestart) {
533
534 if (regs->r10 == -ERESTARTNOHAND ||
535 regs->r10 == -ERESTARTSYS ||
536 regs->r10 == -ERESTARTNOINTR) {
537 RESTART_CRIS_SYS(regs);
538 }
539 if (regs->r10 == -ERESTART_RESTARTBLOCK) {
540 regs->r10 = __NR_restart_syscall;
541 regs->irp -= 2;
542 }
543 }
544
545
546
547 if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
548 clear_thread_flag(TIF_RESTORE_SIGMASK);
549 sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL);
550 }
551}
552