diff options
author | David Howells <dhowells@redhat.com> | 2006-01-06 03:11:45 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-01-06 11:33:33 -0500 |
commit | fef2b580eb50281ae1d2413ab340f677f6722281 (patch) | |
tree | a0cd5204a30a06e72123b7030a8279e1239255da /arch/frv/kernel/signal.c | |
parent | 8efc0ab50edbac5c65191b8a58dfdab3741b7901 (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/signal.c')
-rw-r--r-- | arch/frv/kernel/signal.c | 102 |
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 | ||
38 | asmlinkage int do_signal(struct pt_regs *regs, sigset_t *oldset); | 38 | static 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 | */ |
278 | static inline void __user *get_sigframe(struct k_sigaction *ka, | 278 | static 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 | */ |
300 | static int setup_frame(int sig, struct k_sigaction *ka, sigset_t *set, | 300 | static 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 | */ |
388 | static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | 387 | static 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 | */ |
487 | static int handle_signal(unsigned long sig, siginfo_t *info, | 486 | static 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(¤t->sighand->siglock); | 520 | spin_lock_irq(¤t->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 | */ |
541 | int do_signal(struct pt_regs *regs, sigset_t *oldset) | 539 | static 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 = ¤t->blocked; | 558 | oldset = ¤t->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 | ||
566 | no_signal: | 564 | no_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() */ |