aboutsummaryrefslogtreecommitdiffstats
path: root/arch/frv/kernel
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2006-01-06 03:11:45 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2006-01-06 11:33:33 -0500
commitfef2b580eb50281ae1d2413ab340f677f6722281 (patch)
treea0cd5204a30a06e72123b7030a8279e1239255da /arch/frv/kernel
parent8efc0ab50edbac5c65191b8a58dfdab3741b7901 (diff)
[PATCH] frv: improve signal handling
The attached patch improves the signal handling: (1) It makes do_signal() static as it isn't called from anywhere outside of the arch code. (2) It removes the regs argument to all the static functions within that file, using __frame instead (which is the same thing held in a global register). Signed-off-by: David Howells <dhowells@redhat.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch/frv/kernel')
-rw-r--r--arch/frv/kernel/signal.c102
1 files changed, 50 insertions, 52 deletions
diff --git a/arch/frv/kernel/signal.c b/arch/frv/kernel/signal.c
index 89a1cf5c076a..5b7146f54fd5 100644
--- a/arch/frv/kernel/signal.c
+++ b/arch/frv/kernel/signal.c
@@ -35,7 +35,7 @@ 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); 38static int do_signal(sigset_t *oldset);
39 39
40/* 40/*
41 * Atomically swap in the new signal mask, and wait for a signal. 41 * Atomically swap in the new signal mask, and wait for a signal.
@@ -55,7 +55,7 @@ asmlinkage int sys_sigsuspend(int history0, int history1, old_sigset_t mask)
55 while (1) { 55 while (1) {
56 current->state = TASK_INTERRUPTIBLE; 56 current->state = TASK_INTERRUPTIBLE;
57 schedule(); 57 schedule();
58 if (do_signal(__frame, &saveset)) 58 if (do_signal(&saveset))
59 /* return the signal number as the return value of this function 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() 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 61 * as entry.S sets regs->gr8 to the return value of the system call
@@ -91,7 +91,7 @@ asmlinkage int sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize)
91 while (1) { 91 while (1) {
92 current->state = TASK_INTERRUPTIBLE; 92 current->state = TASK_INTERRUPTIBLE;
93 schedule(); 93 schedule();
94 if (do_signal(__frame, &saveset)) 94 if (do_signal(&saveset))
95 /* return the signal number as the return value of this function 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() 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 97 * as entry.S sets regs->gr8 to the return value of the system call
@@ -276,13 +276,12 @@ static int setup_sigcontext(struct sigcontext __user *sc, unsigned long mask)
276 * Determine which stack to use.. 276 * Determine which stack to use..
277 */ 277 */
278static inline void __user *get_sigframe(struct k_sigaction *ka, 278static inline void __user *get_sigframe(struct k_sigaction *ka,
279 struct pt_regs *regs,
280 size_t frame_size) 279 size_t frame_size)
281{ 280{
282 unsigned long sp; 281 unsigned long sp;
283 282
284 /* Default to using normal stack */ 283 /* Default to using normal stack */
285 sp = regs->sp; 284 sp = __frame->sp;
286 285
287 /* This is the X/Open sanctioned signal stack switching. */ 286 /* This is the X/Open sanctioned signal stack switching. */
288 if (ka->sa.sa_flags & SA_ONSTACK) { 287 if (ka->sa.sa_flags & SA_ONSTACK) {
@@ -291,19 +290,19 @@ static inline void __user *get_sigframe(struct k_sigaction *ka,
291 } 290 }
292 291
293 return (void __user *) ((sp - frame_size) & ~7UL); 292 return (void __user *) ((sp - frame_size) & ~7UL);
293
294} /* end get_sigframe() */ 294} /* end get_sigframe() */
295 295
296/*****************************************************************************/ 296/*****************************************************************************/
297/* 297/*
298 * 298 *
299 */ 299 */
300static int setup_frame(int sig, struct k_sigaction *ka, sigset_t *set, 300static int setup_frame(int sig, struct k_sigaction *ka, sigset_t *set)
301 struct pt_regs *regs)
302{ 301{
303 struct sigframe __user *frame; 302 struct sigframe __user *frame;
304 int rsig; 303 int rsig;
305 304
306 frame = get_sigframe(ka, regs, sizeof(*frame)); 305 frame = get_sigframe(ka, sizeof(*frame));
307 306
308 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) 307 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
309 goto give_sigsegv; 308 goto give_sigsegv;
@@ -347,18 +346,18 @@ static int setup_frame(int sig, struct k_sigaction *ka, sigset_t *set,
347 } 346 }
348 347
349 /* set up registers for signal handler */ 348 /* set up registers for signal handler */
350 regs->sp = (unsigned long) frame; 349 __frame->sp = (unsigned long) frame;
351 regs->lr = (unsigned long) &frame->retcode; 350 __frame->lr = (unsigned long) &frame->retcode;
352 regs->gr8 = sig; 351 __frame->gr8 = sig;
353 352
354 if (get_personality & FDPIC_FUNCPTRS) { 353 if (get_personality & FDPIC_FUNCPTRS) {
355 struct fdpic_func_descriptor __user *funcptr = 354 struct fdpic_func_descriptor __user *funcptr =
356 (struct fdpic_func_descriptor *) ka->sa.sa_handler; 355 (struct fdpic_func_descriptor *) ka->sa.sa_handler;
357 __get_user(regs->pc, &funcptr->text); 356 __get_user(__frame->pc, &funcptr->text);
358 __get_user(regs->gr15, &funcptr->GOT); 357 __get_user(__frame->gr15, &funcptr->GOT);
359 } else { 358 } else {
360 regs->pc = (unsigned long) ka->sa.sa_handler; 359 __frame->pc = (unsigned long) ka->sa.sa_handler;
361 regs->gr15 = 0; 360 __frame->gr15 = 0;
362 } 361 }
363 362
364 set_fs(USER_DS); 363 set_fs(USER_DS);
@@ -369,7 +368,7 @@ static int setup_frame(int sig, struct k_sigaction *ka, sigset_t *set,
369 368
370#if DEBUG_SIG 369#if DEBUG_SIG
371 printk("SIG deliver %d (%s:%d): sp=%p pc=%lx ra=%p\n", 370 printk("SIG deliver %d (%s:%d): sp=%p pc=%lx ra=%p\n",
372 sig, current->comm, current->pid, frame, regs->pc, 371 sig, current->comm, current->pid, frame, __frame->pc,
373 frame->pretcode); 372 frame->pretcode);
374#endif 373#endif
375 374
@@ -386,12 +385,12 @@ give_sigsegv:
386 * 385 *
387 */ 386 */
388static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, 387static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
389 sigset_t *set, struct pt_regs * regs) 388 sigset_t *set)
390{ 389{
391 struct rt_sigframe __user *frame; 390 struct rt_sigframe __user *frame;
392 int rsig; 391 int rsig;
393 392
394 frame = get_sigframe(ka, regs, sizeof(*frame)); 393 frame = get_sigframe(ka, sizeof(*frame));
395 394
396 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) 395 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
397 goto give_sigsegv; 396 goto give_sigsegv;
@@ -414,7 +413,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
414 if (__put_user(0, &frame->uc.uc_flags) || 413 if (__put_user(0, &frame->uc.uc_flags) ||
415 __put_user(0, &frame->uc.uc_link) || 414 __put_user(0, &frame->uc.uc_link) ||
416 __put_user((void*)current->sas_ss_sp, &frame->uc.uc_stack.ss_sp) || 415 __put_user((void*)current->sas_ss_sp, &frame->uc.uc_stack.ss_sp) ||
417 __put_user(sas_ss_flags(regs->sp), &frame->uc.uc_stack.ss_flags) || 416 __put_user(sas_ss_flags(__frame->sp), &frame->uc.uc_stack.ss_flags) ||
418 __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size)) 417 __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size))
419 goto give_sigsegv; 418 goto give_sigsegv;
420 419
@@ -445,19 +444,19 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
445 } 444 }
446 445
447 /* Set up registers for signal handler */ 446 /* Set up registers for signal handler */
448 regs->sp = (unsigned long) frame; 447 __frame->sp = (unsigned long) frame;
449 regs->lr = (unsigned long) &frame->retcode; 448 __frame->lr = (unsigned long) &frame->retcode;
450 regs->gr8 = sig; 449 __frame->gr8 = sig;
451 regs->gr9 = (unsigned long) &frame->info; 450 __frame->gr9 = (unsigned long) &frame->info;
452 451
453 if (get_personality & FDPIC_FUNCPTRS) { 452 if (get_personality & FDPIC_FUNCPTRS) {
454 struct fdpic_func_descriptor *funcptr = 453 struct fdpic_func_descriptor *funcptr =
455 (struct fdpic_func_descriptor __user *) ka->sa.sa_handler; 454 (struct fdpic_func_descriptor __user *) ka->sa.sa_handler;
456 __get_user(regs->pc, &funcptr->text); 455 __get_user(__frame->pc, &funcptr->text);
457 __get_user(regs->gr15, &funcptr->GOT); 456 __get_user(__frame->gr15, &funcptr->GOT);
458 } else { 457 } else {
459 regs->pc = (unsigned long) ka->sa.sa_handler; 458 __frame->pc = (unsigned long) ka->sa.sa_handler;
460 regs->gr15 = 0; 459 __frame->gr15 = 0;
461 } 460 }
462 461
463 set_fs(USER_DS); 462 set_fs(USER_DS);
@@ -468,7 +467,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
468 467
469#if DEBUG_SIG 468#if DEBUG_SIG
470 printk("SIG deliver %d (%s:%d): sp=%p pc=%lx ra=%p\n", 469 printk("SIG deliver %d (%s:%d): sp=%p pc=%lx ra=%p\n",
471 sig, current->comm, current->pid, frame, regs->pc, 470 sig, current->comm, current->pid, frame, __frame->pc,
472 frame->pretcode); 471 frame->pretcode);
473#endif 472#endif
474 473
@@ -485,38 +484,37 @@ give_sigsegv:
485 * OK, we're invoking a handler 484 * OK, we're invoking a handler
486 */ 485 */
487static int handle_signal(unsigned long sig, siginfo_t *info, 486static int handle_signal(unsigned long sig, siginfo_t *info,
488 struct k_sigaction *ka, sigset_t *oldset, 487 struct k_sigaction *ka, sigset_t *oldset)
489 struct pt_regs *regs)
490{ 488{
491 int ret; 489 int ret;
492 490
493 /* Are we from a system call? */ 491 /* Are we from a system call? */
494 if (in_syscall(regs)) { 492 if (in_syscall(__frame)) {
495 /* If so, check system call restarting.. */ 493 /* If so, check system call restarting.. */
496 switch (regs->gr8) { 494 switch (__frame->gr8) {
497 case -ERESTART_RESTARTBLOCK: 495 case -ERESTART_RESTARTBLOCK:
498 case -ERESTARTNOHAND: 496 case -ERESTARTNOHAND:
499 regs->gr8 = -EINTR; 497 __frame->gr8 = -EINTR;
500 break; 498 break;
501 499
502 case -ERESTARTSYS: 500 case -ERESTARTSYS:
503 if (!(ka->sa.sa_flags & SA_RESTART)) { 501 if (!(ka->sa.sa_flags & SA_RESTART)) {
504 regs->gr8 = -EINTR; 502 __frame->gr8 = -EINTR;
505 break; 503 break;
506 } 504 }
507 505
508 /* fallthrough */ 506 /* fallthrough */
509 case -ERESTARTNOINTR: 507 case -ERESTARTNOINTR:
510 regs->gr8 = regs->orig_gr8; 508 __frame->gr8 = __frame->orig_gr8;
511 regs->pc -= 4; 509 __frame->pc -= 4;
512 } 510 }
513 } 511 }
514 512
515 /* Set up the stack frame */ 513 /* Set up the stack frame */
516 if (ka->sa.sa_flags & SA_SIGINFO) 514 if (ka->sa.sa_flags & SA_SIGINFO)
517 ret = setup_rt_frame(sig, ka, info, oldset, regs); 515 ret = setup_rt_frame(sig, ka, info, oldset);
518 else 516 else
519 ret = setup_frame(sig, ka, oldset, regs); 517 ret = setup_frame(sig, ka, oldset);
520 518
521 if (ret) { 519 if (ret) {
522 spin_lock_irq(&current->sighand->siglock); 520 spin_lock_irq(&current->sighand->siglock);
@@ -538,7 +536,7 @@ static int handle_signal(unsigned long sig, siginfo_t *info,
538 * want to handle. Thus you cannot kill init even with a SIGKILL even by 536 * want to handle. Thus you cannot kill init even with a SIGKILL even by
539 * mistake. 537 * mistake.
540 */ 538 */
541int do_signal(struct pt_regs *regs, sigset_t *oldset) 539static int do_signal(sigset_t *oldset)
542{ 540{
543 struct k_sigaction ka; 541 struct k_sigaction ka;
544 siginfo_t info; 542 siginfo_t info;
@@ -550,7 +548,7 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset)
550 * kernel mode. Just return without doing anything 548 * kernel mode. Just return without doing anything
551 * if so. 549 * if so.
552 */ 550 */
553 if (!user_mode(regs)) 551 if (!user_mode(__frame))
554 return 1; 552 return 1;
555 553
556 if (try_to_freeze()) 554 if (try_to_freeze())
@@ -559,24 +557,24 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset)
559 if (!oldset) 557 if (!oldset)
560 oldset = &current->blocked; 558 oldset = &current->blocked;
561 559
562 signr = get_signal_to_deliver(&info, &ka, regs, NULL); 560 signr = get_signal_to_deliver(&info, &ka, __frame, NULL);
563 if (signr > 0) 561 if (signr > 0)
564 return handle_signal(signr, &info, &ka, oldset, regs); 562 return handle_signal(signr, &info, &ka, oldset);
565 563
566no_signal: 564no_signal:
567 /* Did we come from a system call? */ 565 /* Did we come from a system call? */
568 if (regs->syscallno >= 0) { 566 if (__frame->syscallno >= 0) {
569 /* Restart the system call - no handlers present */ 567 /* Restart the system call - no handlers present */
570 if (regs->gr8 == -ERESTARTNOHAND || 568 if (__frame->gr8 == -ERESTARTNOHAND ||
571 regs->gr8 == -ERESTARTSYS || 569 __frame->gr8 == -ERESTARTSYS ||
572 regs->gr8 == -ERESTARTNOINTR) { 570 __frame->gr8 == -ERESTARTNOINTR) {
573 regs->gr8 = regs->orig_gr8; 571 __frame->gr8 = __frame->orig_gr8;
574 regs->pc -= 4; 572 __frame->pc -= 4;
575 } 573 }
576 574
577 if (regs->gr8 == -ERESTART_RESTARTBLOCK){ 575 if (__frame->gr8 == -ERESTART_RESTARTBLOCK){
578 regs->gr8 = __NR_restart_syscall; 576 __frame->gr8 = __NR_restart_syscall;
579 regs->pc -= 4; 577 __frame->pc -= 4;
580 } 578 }
581 } 579 }
582 580
@@ -597,6 +595,6 @@ asmlinkage void do_notify_resume(__u32 thread_info_flags)
597 595
598 /* deal with pending signal delivery */ 596 /* deal with pending signal delivery */
599 if (thread_info_flags & _TIF_SIGPENDING) 597 if (thread_info_flags & _TIF_SIGPENDING)
600 do_signal(__frame, NULL); 598 do_signal(NULL);
601 599
602} /* end do_notify_resume() */ 600} /* end do_notify_resume() */