[PATCH] frv: improve signal handling
authorDavid Howells <dhowells@redhat.com>
Fri, 6 Jan 2006 08:11:45 +0000 (00:11 -0800)
committerLinus Torvalds <torvalds@g5.osdl.org>
Fri, 6 Jan 2006 16:33:33 +0000 (08:33 -0800)
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>
arch/frv/kernel/signal.c
include/asm-frv/signal.h

index 89a1cf5c076af5949738c9c92273893907058e36..5b7146f54fd5814f4ba00447c04d676b4dd945cf 100644 (file)
@@ -35,7 +35,7 @@ struct fdpic_func_descriptor {
        unsigned long   GOT;
 };
 
-asmlinkage int do_signal(struct pt_regs *regs, sigset_t *oldset);
+static int do_signal(sigset_t *oldset);
 
 /*
  * 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)
        while (1) {
                current->state = TASK_INTERRUPTIBLE;
                schedule();
-               if (do_signal(__frame, &saveset))
+               if (do_signal(&saveset))
                        /* return the signal number as the return value of this function
                         * - this is an utterly evil hack. syscalls should not invoke do_signal()
                         *   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)
        while (1) {
                current->state = TASK_INTERRUPTIBLE;
                schedule();
-               if (do_signal(__frame, &saveset))
+               if (do_signal(&saveset))
                        /* return the signal number as the return value of this function
                         * - this is an utterly evil hack. syscalls should not invoke do_signal()
                         *   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)
  * Determine which stack to use..
  */
 static inline void __user *get_sigframe(struct k_sigaction *ka,
-                                       struct pt_regs *regs,
                                        size_t frame_size)
 {
        unsigned long sp;
 
        /* Default to using normal stack */
-       sp = regs->sp;
+       sp = __frame->sp;
 
        /* This is the X/Open sanctioned signal stack switching.  */
        if (ka->sa.sa_flags & SA_ONSTACK) {
@@ -291,19 +290,19 @@ static inline void __user *get_sigframe(struct k_sigaction *ka,
        }
 
        return (void __user *) ((sp - frame_size) & ~7UL);
+
 } /* end get_sigframe() */
 
 /*****************************************************************************/
 /*
  *
  */
-static int setup_frame(int sig, struct k_sigaction *ka, sigset_t *set,
-                      struct pt_regs *regs)
+static int setup_frame(int sig, struct k_sigaction *ka, sigset_t *set)
 {
        struct sigframe __user *frame;
        int rsig;
 
-       frame = get_sigframe(ka, regs, sizeof(*frame));
+       frame = get_sigframe(ka, sizeof(*frame));
 
        if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
                goto give_sigsegv;
@@ -347,18 +346,18 @@ static int setup_frame(int sig, struct k_sigaction *ka, sigset_t *set,
        }
 
        /* set up registers for signal handler */
-       regs->sp   = (unsigned long) frame;
-       regs->lr   = (unsigned long) &frame->retcode;
-       regs->gr8  = sig;
+       __frame->sp   = (unsigned long) frame;
+       __frame->lr   = (unsigned long) &frame->retcode;
+       __frame->gr8  = sig;
 
        if (get_personality & FDPIC_FUNCPTRS) {
                struct fdpic_func_descriptor __user *funcptr =
                        (struct fdpic_func_descriptor *) ka->sa.sa_handler;
-               __get_user(regs->pc, &funcptr->text);
-               __get_user(regs->gr15, &funcptr->GOT);
+               __get_user(__frame->pc, &funcptr->text);
+               __get_user(__frame->gr15, &funcptr->GOT);
        } else {
-               regs->pc   = (unsigned long) ka->sa.sa_handler;
-               regs->gr15 = 0;
+               __frame->pc   = (unsigned long) ka->sa.sa_handler;
+               __frame->gr15 = 0;
        }
 
        set_fs(USER_DS);
@@ -369,7 +368,7 @@ static int setup_frame(int sig, struct k_sigaction *ka, sigset_t *set,
 
 #if DEBUG_SIG
        printk("SIG deliver %d (%s:%d): sp=%p pc=%lx ra=%p\n",
-              sig, current->comm, current->pid, frame, regs->pc,
+              sig, current->comm, current->pid, frame, __frame->pc,
               frame->pretcode);
 #endif
 
@@ -386,12 +385,12 @@ give_sigsegv:
  *
  */
 static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
-                         sigset_t *set, struct pt_regs * regs)
+                         sigset_t *set)
 {
        struct rt_sigframe __user *frame;
        int rsig;
 
-       frame = get_sigframe(ka, regs, sizeof(*frame));
+       frame = get_sigframe(ka, sizeof(*frame));
 
        if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
                goto give_sigsegv;
@@ -414,7 +413,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
        if (__put_user(0, &frame->uc.uc_flags) ||
            __put_user(0, &frame->uc.uc_link) ||
            __put_user((void*)current->sas_ss_sp, &frame->uc.uc_stack.ss_sp) ||
-           __put_user(sas_ss_flags(regs->sp), &frame->uc.uc_stack.ss_flags) ||
+           __put_user(sas_ss_flags(__frame->sp), &frame->uc.uc_stack.ss_flags) ||
            __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size))
                goto give_sigsegv;
 
@@ -445,19 +444,19 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
        }
 
        /* Set up registers for signal handler */
-       regs->sp  = (unsigned long) frame;
-       regs->lr   = (unsigned long) &frame->retcode;
-       regs->gr8 = sig;
-       regs->gr9 = (unsigned long) &frame->info;
+       __frame->sp  = (unsigned long) frame;
+       __frame->lr   = (unsigned long) &frame->retcode;
+       __frame->gr8 = sig;
+       __frame->gr9 = (unsigned long) &frame->info;
 
        if (get_personality & FDPIC_FUNCPTRS) {
                struct fdpic_func_descriptor *funcptr =
                        (struct fdpic_func_descriptor __user *) ka->sa.sa_handler;
-               __get_user(regs->pc, &funcptr->text);
-               __get_user(regs->gr15, &funcptr->GOT);
+               __get_user(__frame->pc, &funcptr->text);
+               __get_user(__frame->gr15, &funcptr->GOT);
        } else {
-               regs->pc   = (unsigned long) ka->sa.sa_handler;
-               regs->gr15 = 0;
+               __frame->pc   = (unsigned long) ka->sa.sa_handler;
+               __frame->gr15 = 0;
        }
 
        set_fs(USER_DS);
@@ -468,7 +467,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
 
 #if DEBUG_SIG
        printk("SIG deliver %d (%s:%d): sp=%p pc=%lx ra=%p\n",
-               sig, current->comm, current->pid, frame, regs->pc,
+              sig, current->comm, current->pid, frame, __frame->pc,
               frame->pretcode);
 #endif
 
@@ -485,38 +484,37 @@ give_sigsegv:
  * OK, we're invoking a handler
  */
 static int handle_signal(unsigned long sig, siginfo_t *info,
-                        struct k_sigaction *ka, sigset_t *oldset,
-                        struct pt_regs *regs)
+                        struct k_sigaction *ka, sigset_t *oldset)
 {
        int ret;
 
        /* Are we from a system call? */
-       if (in_syscall(regs)) {
+       if (in_syscall(__frame)) {
                /* If so, check system call restarting.. */
-               switch (regs->gr8) {
+               switch (__frame->gr8) {
                case -ERESTART_RESTARTBLOCK:
                case -ERESTARTNOHAND:
-                       regs->gr8 = -EINTR;
+                       __frame->gr8 = -EINTR;
                        break;
 
                case -ERESTARTSYS:
                        if (!(ka->sa.sa_flags & SA_RESTART)) {
-                               regs->gr8 = -EINTR;
+                               __frame->gr8 = -EINTR;
                                break;
                        }
 
                        /* fallthrough */
                case -ERESTARTNOINTR:
-                       regs->gr8 = regs->orig_gr8;
-                       regs->pc -= 4;
+                       __frame->gr8 = __frame->orig_gr8;
+                       __frame->pc -= 4;
                }
        }
 
        /* Set up the stack frame */
        if (ka->sa.sa_flags & SA_SIGINFO)
-               ret = setup_rt_frame(sig, ka, info, oldset, regs);
+               ret = setup_rt_frame(sig, ka, info, oldset);
        else
-               ret = setup_frame(sig, ka, oldset, regs);
+               ret = setup_frame(sig, ka, oldset);
 
        if (ret) {
                spin_lock_irq(&current->sighand->siglock);
@@ -538,7 +536,7 @@ static int handle_signal(unsigned long sig, siginfo_t *info,
  * want to handle. Thus you cannot kill init even with a SIGKILL even by
  * mistake.
  */
-int do_signal(struct pt_regs *regs, sigset_t *oldset)
+static int do_signal(sigset_t *oldset)
 {
        struct k_sigaction ka;
        siginfo_t info;
@@ -550,7 +548,7 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset)
         * kernel mode. Just return without doing anything
         * if so.
         */
-       if (!user_mode(regs))
+       if (!user_mode(__frame))
                return 1;
 
        if (try_to_freeze())
@@ -559,24 +557,24 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset)
        if (!oldset)
                oldset = &current->blocked;
 
-       signr = get_signal_to_deliver(&info, &ka, regs, NULL);
+       signr = get_signal_to_deliver(&info, &ka, __frame, NULL);
        if (signr > 0)
-               return handle_signal(signr, &info, &ka, oldset, regs);
+               return handle_signal(signr, &info, &ka, oldset);
 
 no_signal:
        /* Did we come from a system call? */
-       if (regs->syscallno >= 0) {
+       if (__frame->syscallno >= 0) {
                /* Restart the system call - no handlers present */
-               if (regs->gr8 == -ERESTARTNOHAND ||
-                   regs->gr8 == -ERESTARTSYS ||
-                   regs->gr8 == -ERESTARTNOINTR) {
-                       regs->gr8 = regs->orig_gr8;
-                       regs->pc -= 4;
+               if (__frame->gr8 == -ERESTARTNOHAND ||
+                   __frame->gr8 == -ERESTARTSYS ||
+                   __frame->gr8 == -ERESTARTNOINTR) {
+                       __frame->gr8 = __frame->orig_gr8;
+                       __frame->pc -= 4;
                }
 
-               if (regs->gr8 == -ERESTART_RESTARTBLOCK){
-                       regs->gr8 = __NR_restart_syscall;
-                       regs->pc -= 4;
+               if (__frame->gr8 == -ERESTART_RESTARTBLOCK){
+                       __frame->gr8 = __NR_restart_syscall;
+                       __frame->pc -= 4;
                }
        }
 
@@ -597,6 +595,6 @@ asmlinkage void do_notify_resume(__u32 thread_info_flags)
 
        /* deal with pending signal delivery */
        if (thread_info_flags & _TIF_SIGPENDING)
-               do_signal(__frame, NULL);
+               do_signal(NULL);
 
 } /* end do_notify_resume() */
index d407bde57ecaaf6f56e812731bf3c7072d55fd5b..67366894780f95825dc9f1996c4205b8e34bce4d 100644 (file)
@@ -151,7 +151,6 @@ typedef struct sigaltstack {
        size_t ss_size;
 } stack_t;
 
-extern int do_signal(struct pt_regs *regs, sigset_t *oldset);
 #define ptrace_signal_deliver(regs, cookie) do { } while (0)
 
 #ifdef __KERNEL__