aboutsummaryrefslogtreecommitdiffstats
path: root/arch/frv/kernel/signal.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/frv/kernel/signal.c')
-rw-r--r--arch/frv/kernel/signal.c239
1 files changed, 111 insertions, 128 deletions
diff --git a/arch/frv/kernel/signal.c b/arch/frv/kernel/signal.c
index d4ccc0728df..679c1d5cc95 100644
--- a/arch/frv/kernel/signal.c
+++ b/arch/frv/kernel/signal.c
@@ -35,74 +35,22 @@ struct fdpic_func_descriptor {
35 unsigned long GOT; 35 unsigned long GOT;
36}; 36};
37 37
38asmlinkage int do_signal(struct pt_regs *regs, sigset_t *oldset);
39
40/* 38/*
41 * Atomically swap in the new signal mask, and wait for a signal. 39 * Atomically swap in the new signal mask, and wait for a signal.
42 */ 40 */
43asmlinkage int sys_sigsuspend(int history0, int history1, old_sigset_t mask) 41asmlinkage int sys_sigsuspend(int history0, int history1, old_sigset_t mask)
44{ 42{
45 sigset_t saveset;
46
47 mask &= _BLOCKABLE; 43 mask &= _BLOCKABLE;
48 spin_lock_irq(&current->sighand->siglock); 44 spin_lock_irq(&current->sighand->siglock);
49 saveset = current->blocked; 45 current->saved_sigmask = current->blocked;
50 siginitset(&current->blocked, mask); 46 siginitset(&current->blocked, mask);
51 recalc_sigpending(); 47 recalc_sigpending();
52 spin_unlock_irq(&current->sighand->siglock); 48 spin_unlock_irq(&current->sighand->siglock);
53 49
54 __frame->gr8 = -EINTR; 50 current->state = TASK_INTERRUPTIBLE;
55 while (1) { 51 schedule();
56 current->state = TASK_INTERRUPTIBLE; 52 set_thread_flag(TIF_RESTORE_SIGMASK);
57 schedule(); 53 return -ERESTARTNOHAND;
58 if (do_signal(__frame, &saveset))
59 /* return the signal number as the return value of this function
60 * - this is an utterly evil hack. syscalls should not invoke do_signal()
61 * as entry.S sets regs->gr8 to the return value of the system call
62 * - we can't just use sigpending() as we'd have to discard SIG_IGN signals
63 * and call waitpid() if SIGCHLD needed discarding
64 * - this only works on the i386 because it passes arguments to the signal
65 * handler on the stack, and the return value in EAX is effectively
66 * discarded
67 */
68 return __frame->gr8;
69 }
70}
71
72asmlinkage int sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize)
73{
74 sigset_t saveset, newset;
75
76 /* XXX: Don't preclude handling different sized sigset_t's. */
77 if (sigsetsize != sizeof(sigset_t))
78 return -EINVAL;
79
80 if (copy_from_user(&newset, unewset, sizeof(newset)))
81 return -EFAULT;
82 sigdelsetmask(&newset, ~_BLOCKABLE);
83
84 spin_lock_irq(&current->sighand->siglock);
85 saveset = current->blocked;
86 current->blocked = newset;
87 recalc_sigpending();
88 spin_unlock_irq(&current->sighand->siglock);
89
90 __frame->gr8 = -EINTR;
91 while (1) {
92 current->state = TASK_INTERRUPTIBLE;
93 schedule();
94 if (do_signal(__frame, &saveset))
95 /* return the signal number as the return value of this function
96 * - this is an utterly evil hack. syscalls should not invoke do_signal()
97 * as entry.S sets regs->gr8 to the return value of the system call
98 * - we can't just use sigpending() as we'd have to discard SIG_IGN signals
99 * and call waitpid() if SIGCHLD needed discarding
100 * - this only works on the i386 because it passes arguments to the signal
101 * handler on the stack, and the return value in EAX is effectively
102 * discarded
103 */
104 return __frame->gr8;
105 }
106} 54}
107 55
108asmlinkage int sys_sigaction(int sig, 56asmlinkage int sys_sigaction(int sig,
@@ -276,13 +224,12 @@ static int setup_sigcontext(struct sigcontext __user *sc, unsigned long mask)
276 * Determine which stack to use.. 224 * Determine which stack to use..
277 */ 225 */
278static inline void __user *get_sigframe(struct k_sigaction *ka, 226static inline void __user *get_sigframe(struct k_sigaction *ka,
279 struct pt_regs *regs,
280 size_t frame_size) 227 size_t frame_size)
281{ 228{
282 unsigned long sp; 229 unsigned long sp;
283 230
284 /* Default to using normal stack */ 231 /* Default to using normal stack */
285 sp = regs->sp; 232 sp = __frame->sp;
286 233
287 /* This is the X/Open sanctioned signal stack switching. */ 234 /* This is the X/Open sanctioned signal stack switching. */
288 if (ka->sa.sa_flags & SA_ONSTACK) { 235 if (ka->sa.sa_flags & SA_ONSTACK) {
@@ -291,18 +238,19 @@ static inline void __user *get_sigframe(struct k_sigaction *ka,
291 } 238 }
292 239
293 return (void __user *) ((sp - frame_size) & ~7UL); 240 return (void __user *) ((sp - frame_size) & ~7UL);
241
294} /* end get_sigframe() */ 242} /* end get_sigframe() */
295 243
296/*****************************************************************************/ 244/*****************************************************************************/
297/* 245/*
298 * 246 *
299 */ 247 */
300static void setup_frame(int sig, struct k_sigaction *ka, sigset_t *set, struct pt_regs * regs) 248static int setup_frame(int sig, struct k_sigaction *ka, sigset_t *set)
301{ 249{
302 struct sigframe __user *frame; 250 struct sigframe __user *frame;
303 int rsig; 251 int rsig;
304 252
305 frame = get_sigframe(ka, regs, sizeof(*frame)); 253 frame = get_sigframe(ka, sizeof(*frame));
306 254
307 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) 255 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
308 goto give_sigsegv; 256 goto give_sigsegv;
@@ -346,47 +294,51 @@ static void setup_frame(int sig, struct k_sigaction *ka, sigset_t *set, struct p
346 } 294 }
347 295
348 /* set up registers for signal handler */ 296 /* set up registers for signal handler */
349 regs->sp = (unsigned long) frame; 297 __frame->sp = (unsigned long) frame;
350 regs->lr = (unsigned long) &frame->retcode; 298 __frame->lr = (unsigned long) &frame->retcode;
351 regs->gr8 = sig; 299 __frame->gr8 = sig;
352 300
353 if (get_personality & FDPIC_FUNCPTRS) { 301 if (get_personality & FDPIC_FUNCPTRS) {
354 struct fdpic_func_descriptor __user *funcptr = 302 struct fdpic_func_descriptor __user *funcptr =
355 (struct fdpic_func_descriptor *) ka->sa.sa_handler; 303 (struct fdpic_func_descriptor *) ka->sa.sa_handler;
356 __get_user(regs->pc, &funcptr->text); 304 __get_user(__frame->pc, &funcptr->text);
357 __get_user(regs->gr15, &funcptr->GOT); 305 __get_user(__frame->gr15, &funcptr->GOT);
358 } else { 306 } else {
359 regs->pc = (unsigned long) ka->sa.sa_handler; 307 __frame->pc = (unsigned long) ka->sa.sa_handler;
360 regs->gr15 = 0; 308 __frame->gr15 = 0;
361 } 309 }
362 310
363 set_fs(USER_DS); 311 set_fs(USER_DS);
364 312
313 /* the tracer may want to single-step inside the handler */
314 if (test_thread_flag(TIF_SINGLESTEP))
315 ptrace_notify(SIGTRAP);
316
365#if DEBUG_SIG 317#if DEBUG_SIG
366 printk("SIG deliver %d (%s:%d): sp=%p pc=%lx ra=%p\n", 318 printk("SIG deliver %d (%s:%d): sp=%p pc=%lx ra=%p\n",
367 sig, current->comm, current->pid, frame, regs->pc, frame->pretcode); 319 sig, current->comm, current->pid, frame, __frame->pc,
320 frame->pretcode);
368#endif 321#endif
369 322
370 return; 323 return 0;
371 324
372give_sigsegv: 325give_sigsegv:
373 if (sig == SIGSEGV)
374 ka->sa.sa_handler = SIG_DFL;
375
376 force_sig(SIGSEGV, current); 326 force_sig(SIGSEGV, current);
327 return -EFAULT;
328
377} /* end setup_frame() */ 329} /* end setup_frame() */
378 330
379/*****************************************************************************/ 331/*****************************************************************************/
380/* 332/*
381 * 333 *
382 */ 334 */
383static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, 335static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
384 sigset_t *set, struct pt_regs * regs) 336 sigset_t *set)
385{ 337{
386 struct rt_sigframe __user *frame; 338 struct rt_sigframe __user *frame;
387 int rsig; 339 int rsig;
388 340
389 frame = get_sigframe(ka, regs, sizeof(*frame)); 341 frame = get_sigframe(ka, sizeof(*frame));
390 342
391 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) 343 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
392 goto give_sigsegv; 344 goto give_sigsegv;
@@ -409,7 +361,7 @@ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
409 if (__put_user(0, &frame->uc.uc_flags) || 361 if (__put_user(0, &frame->uc.uc_flags) ||
410 __put_user(0, &frame->uc.uc_link) || 362 __put_user(0, &frame->uc.uc_link) ||
411 __put_user((void*)current->sas_ss_sp, &frame->uc.uc_stack.ss_sp) || 363 __put_user((void*)current->sas_ss_sp, &frame->uc.uc_stack.ss_sp) ||
412 __put_user(sas_ss_flags(regs->sp), &frame->uc.uc_stack.ss_flags) || 364 __put_user(sas_ss_flags(__frame->sp), &frame->uc.uc_stack.ss_flags) ||
413 __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size)) 365 __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size))
414 goto give_sigsegv; 366 goto give_sigsegv;
415 367
@@ -440,34 +392,38 @@ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
440 } 392 }
441 393
442 /* Set up registers for signal handler */ 394 /* Set up registers for signal handler */
443 regs->sp = (unsigned long) frame; 395 __frame->sp = (unsigned long) frame;
444 regs->lr = (unsigned long) &frame->retcode; 396 __frame->lr = (unsigned long) &frame->retcode;
445 regs->gr8 = sig; 397 __frame->gr8 = sig;
446 regs->gr9 = (unsigned long) &frame->info; 398 __frame->gr9 = (unsigned long) &frame->info;
447 399
448 if (get_personality & FDPIC_FUNCPTRS) { 400 if (get_personality & FDPIC_FUNCPTRS) {
449 struct fdpic_func_descriptor *funcptr = 401 struct fdpic_func_descriptor *funcptr =
450 (struct fdpic_func_descriptor __user *) ka->sa.sa_handler; 402 (struct fdpic_func_descriptor __user *) ka->sa.sa_handler;
451 __get_user(regs->pc, &funcptr->text); 403 __get_user(__frame->pc, &funcptr->text);
452 __get_user(regs->gr15, &funcptr->GOT); 404 __get_user(__frame->gr15, &funcptr->GOT);
453 } else { 405 } else {
454 regs->pc = (unsigned long) ka->sa.sa_handler; 406 __frame->pc = (unsigned long) ka->sa.sa_handler;
455 regs->gr15 = 0; 407 __frame->gr15 = 0;
456 } 408 }
457 409
458 set_fs(USER_DS); 410 set_fs(USER_DS);
459 411
412 /* the tracer may want to single-step inside the handler */
413 if (test_thread_flag(TIF_SINGLESTEP))
414 ptrace_notify(SIGTRAP);
415
460#if DEBUG_SIG 416#if DEBUG_SIG
461 printk("SIG deliver %d (%s:%d): sp=%p pc=%lx ra=%p\n", 417 printk("SIG deliver %d (%s:%d): sp=%p pc=%lx ra=%p\n",
462 sig, current->comm, current->pid, frame, regs->pc, frame->pretcode); 418 sig, current->comm, current->pid, frame, __frame->pc,
419 frame->pretcode);
463#endif 420#endif
464 421
465 return; 422 return 0;
466 423
467give_sigsegv: 424give_sigsegv:
468 if (sig == SIGSEGV)
469 ka->sa.sa_handler = SIG_DFL;
470 force_sig(SIGSEGV, current); 425 force_sig(SIGSEGV, current);
426 return -EFAULT;
471 427
472} /* end setup_rt_frame() */ 428} /* end setup_rt_frame() */
473 429
@@ -475,43 +431,51 @@ give_sigsegv:
475/* 431/*
476 * OK, we're invoking a handler 432 * OK, we're invoking a handler
477 */ 433 */
478static void handle_signal(unsigned long sig, siginfo_t *info, 434static int handle_signal(unsigned long sig, siginfo_t *info,
479 struct k_sigaction *ka, sigset_t *oldset, 435 struct k_sigaction *ka, sigset_t *oldset)
480 struct pt_regs *regs)
481{ 436{
437 int ret;
438
482 /* Are we from a system call? */ 439 /* Are we from a system call? */
483 if (in_syscall(regs)) { 440 if (in_syscall(__frame)) {
484 /* If so, check system call restarting.. */ 441 /* If so, check system call restarting.. */
485 switch (regs->gr8) { 442 switch (__frame->gr8) {
486 case -ERESTART_RESTARTBLOCK: 443 case -ERESTART_RESTARTBLOCK:
487 case -ERESTARTNOHAND: 444 case -ERESTARTNOHAND:
488 regs->gr8 = -EINTR; 445 __frame->gr8 = -EINTR;
489 break; 446 break;
490 447
491 case -ERESTARTSYS: 448 case -ERESTARTSYS:
492 if (!(ka->sa.sa_flags & SA_RESTART)) { 449 if (!(ka->sa.sa_flags & SA_RESTART)) {
493 regs->gr8 = -EINTR; 450 __frame->gr8 = -EINTR;
494 break; 451 break;
495 } 452 }
453
496 /* fallthrough */ 454 /* fallthrough */
497 case -ERESTARTNOINTR: 455 case -ERESTARTNOINTR:
498 regs->gr8 = regs->orig_gr8; 456 __frame->gr8 = __frame->orig_gr8;
499 regs->pc -= 4; 457 __frame->pc -= 4;
500 } 458 }
501 } 459 }
502 460
503 /* Set up the stack frame */ 461 /* Set up the stack frame */
504 if (ka->sa.sa_flags & SA_SIGINFO) 462 if (ka->sa.sa_flags & SA_SIGINFO)
505 setup_rt_frame(sig, ka, info, oldset, regs); 463 ret = setup_rt_frame(sig, ka, info, oldset);
506 else 464 else
507 setup_frame(sig, ka, oldset, regs); 465 ret = setup_frame(sig, ka, oldset);
466
467 if (ret == 0) {
468 spin_lock_irq(&current->sighand->siglock);
469 sigorsets(&current->blocked, &current->blocked,
470 &ka->sa.sa_mask);
471 if (!(ka->sa.sa_flags & SA_NODEFER))
472 sigaddset(&current->blocked, sig);
473 recalc_sigpending();
474 spin_unlock_irq(&current->sighand->siglock);
475 }
476
477 return ret;
508 478
509 spin_lock_irq(&current->sighand->siglock);
510 sigorsets(&current->blocked, &current->blocked, &ka->sa.sa_mask);
511 if (!(ka->sa.sa_flags & SA_NODEFER))
512 sigaddset(&current->blocked, sig);
513 recalc_sigpending();
514 spin_unlock_irq(&current->sighand->siglock);
515} /* end handle_signal() */ 479} /* end handle_signal() */
516 480
517/*****************************************************************************/ 481/*****************************************************************************/
@@ -520,10 +484,11 @@ static void handle_signal(unsigned long sig, siginfo_t *info,
520 * want to handle. Thus you cannot kill init even with a SIGKILL even by 484 * want to handle. Thus you cannot kill init even with a SIGKILL even by
521 * mistake. 485 * mistake.
522 */ 486 */
523int do_signal(struct pt_regs *regs, sigset_t *oldset) 487static void do_signal(void)
524{ 488{
525 struct k_sigaction ka; 489 struct k_sigaction ka;
526 siginfo_t info; 490 siginfo_t info;
491 sigset_t *oldset;
527 int signr; 492 int signr;
528 493
529 /* 494 /*
@@ -532,45 +497,63 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset)
532 * kernel mode. Just return without doing anything 497 * kernel mode. Just return without doing anything
533 * if so. 498 * if so.
534 */ 499 */
535 if (!user_mode(regs)) 500 if (!user_mode(__frame))
536 return 1; 501 return;
537 502
538 if (try_to_freeze()) 503 if (try_to_freeze())
539 goto no_signal; 504 goto no_signal;
540 505
541 if (!oldset) 506 if (test_thread_flag(TIF_RESTORE_SIGMASK))
507 oldset = &current->saved_sigmask;
508 else
542 oldset = &current->blocked; 509 oldset = &current->blocked;
543 510
544 signr = get_signal_to_deliver(&info, &ka, regs, NULL); 511 signr = get_signal_to_deliver(&info, &ka, __frame, NULL);
545 if (signr > 0) { 512 if (signr > 0) {
546 handle_signal(signr, &info, &ka, oldset, regs); 513 if (handle_signal(signr, &info, &ka, oldset) == 0) {
547 return 1; 514 /* a signal was successfully delivered; the saved
515 * sigmask will have been stored in the signal frame,
516 * and will be restored by sigreturn, so we can simply
517 * clear the TIF_RESTORE_SIGMASK flag */
518 if (test_thread_flag(TIF_RESTORE_SIGMASK))
519 clear_thread_flag(TIF_RESTORE_SIGMASK);
520 }
521
522 return;
548 } 523 }
549 524
550 no_signal: 525no_signal:
551 /* Did we come from a system call? */ 526 /* Did we come from a system call? */
552 if (regs->syscallno >= 0) { 527 if (__frame->syscallno >= 0) {
553 /* Restart the system call - no handlers present */ 528 /* Restart the system call - no handlers present */
554 if (regs->gr8 == -ERESTARTNOHAND || 529 switch (__frame->gr8) {
555 regs->gr8 == -ERESTARTSYS || 530 case -ERESTARTNOHAND:
556 regs->gr8 == -ERESTARTNOINTR) { 531 case -ERESTARTSYS:
557 regs->gr8 = regs->orig_gr8; 532 case -ERESTARTNOINTR:
558 regs->pc -= 4; 533 __frame->gr8 = __frame->orig_gr8;
559 } 534 __frame->pc -= 4;
535 break;
560 536
561 if (regs->gr8 == -ERESTART_RESTARTBLOCK){ 537 case -ERESTART_RESTARTBLOCK:
562 regs->gr8 = __NR_restart_syscall; 538 __frame->gr8 = __NR_restart_syscall;
563 regs->pc -= 4; 539 __frame->pc -= 4;
540 break;
564 } 541 }
565 } 542 }
566 543
567 return 0; 544 /* if there's no signal to deliver, we just put the saved sigmask
545 * back */
546 if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
547 clear_thread_flag(TIF_RESTORE_SIGMASK);
548 sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
549 }
550
568} /* end do_signal() */ 551} /* end do_signal() */
569 552
570/*****************************************************************************/ 553/*****************************************************************************/
571/* 554/*
572 * notification of userspace execution resumption 555 * notification of userspace execution resumption
573 * - triggered by current->work.notify_resume 556 * - triggered by the TIF_WORK_MASK flags
574 */ 557 */
575asmlinkage void do_notify_resume(__u32 thread_info_flags) 558asmlinkage void do_notify_resume(__u32 thread_info_flags)
576{ 559{
@@ -579,7 +562,7 @@ asmlinkage void do_notify_resume(__u32 thread_info_flags)
579 clear_thread_flag(TIF_SINGLESTEP); 562 clear_thread_flag(TIF_SINGLESTEP);
580 563
581 /* deal with pending signal delivery */ 564 /* deal with pending signal delivery */
582 if (thread_info_flags & _TIF_SIGPENDING) 565 if (thread_info_flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK))
583 do_signal(__frame, NULL); 566 do_signal();
584 567
585} /* end do_notify_resume() */ 568} /* end do_notify_resume() */