]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - arch/sparc64/kernel/signal.c
Merge branch 'for-linus' of git://git390.osdl.marist.edu/pub/scm/linux-2.6
[linux-2.6-omap-h63xx.git] / arch / sparc64 / kernel / signal.c
index 94a9d64208eee17126fb2ef996ad07f3ece660fd..45d6bf632daa6a6e4fe5c6826629c3ff9eb1f732 100644 (file)
@@ -8,7 +8,7 @@
  *  Copyright (C) 1997,1998 Jakub Jelinek   (jj@sunsite.mff.cuni.cz)
  */
 
-#ifdef CONFIG_SPARC32_COMPAT
+#ifdef CONFIG_COMPAT
 #include <linux/compat.h>      /* for compat_old_sigset_t */
 #endif
 #include <linux/sched.h>
@@ -25,7 +25,6 @@
 
 #include <asm/uaccess.h>
 #include <asm/ptrace.h>
-#include <asm/svr4.h>
 #include <asm/pgtable.h>
 #include <asm/fpumacro.h>
 #include <asm/uctx.h>
@@ -237,9 +236,6 @@ struct rt_signal_frame {
        __siginfo_fpu_t         fpu_state;
 };
 
-/* Align macros */
-#define RT_ALIGNEDSZ  (((sizeof(struct rt_signal_frame) + 7) & (~7)))
-
 static long _sigpause_common(old_sigset_t set)
 {
        set &= _BLOCKABLE;
@@ -336,6 +332,9 @@ void do_rt_sigreturn(struct pt_regs *regs)
        regs->tpc = tpc;
        regs->tnpc = tnpc;
 
+       /* Prevent syscall restart.  */
+       pt_regs_clear_trap_type(regs);
+
        sigdelsetmask(&set, ~_BLOCKABLE);
        spin_lock_irq(&current->sighand->siglock);
        current->blocked = set;
@@ -357,7 +356,7 @@ static int invalid_frame_pointer(void __user *fp, int fplen)
 static inline int
 save_fpu_state(struct pt_regs *regs, __siginfo_fpu_t __user *fpu)
 {
-       unsigned long *fpregs = (unsigned long *)(regs+1);
+       unsigned long *fpregs = current_thread_info()->fpregs;
        unsigned long fprs;
        int err = 0;
        
@@ -401,7 +400,7 @@ setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs,
        synchronize_user_stack();
        save_and_clear_fpu();
        
-       sigframe_size = RT_ALIGNEDSZ;
+       sigframe_size = sizeof(struct rt_signal_frame);
        if (!(current_thread_info()->fpsaved[0] & FPRS_FEF))
                sigframe_size -= sizeof(__siginfo_fpu_t);
 
@@ -511,15 +510,20 @@ static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs,
  * want to handle. Thus you cannot kill init even with a SIGKILL even by
  * mistake.
  */
-static void do_signal(struct pt_regs *regs, unsigned long orig_i0, int restart_syscall)
+static void do_signal(struct pt_regs *regs, unsigned long orig_i0)
 {
-       siginfo_t info;
        struct signal_deliver_cookie cookie;
        struct k_sigaction ka;
-       int signr;
        sigset_t *oldset;
+       siginfo_t info;
+       int signr;
        
-       cookie.restart_syscall = restart_syscall;
+       if (pt_regs_is_syscall(regs) &&
+           (regs->tstate & (TSTATE_XCARRY | TSTATE_ICARRY))) {
+               pt_regs_clear_trap_type(regs);
+               cookie.restart_syscall = 1;
+       } else
+               cookie.restart_syscall = 0;
        cookie.orig_i0 = orig_i0;
 
        if (test_thread_flag(TIF_RESTORE_SIGMASK))
@@ -527,12 +531,11 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0, int restart_s
        else
                oldset = &current->blocked;
 
-#ifdef CONFIG_SPARC32_COMPAT
+#ifdef CONFIG_COMPAT
        if (test_thread_flag(TIF_32BIT)) {
                extern void do_signal32(sigset_t *, struct pt_regs *,
-                                       unsigned long, int);
-               do_signal32(oldset, regs, orig_i0,
-                           cookie.restart_syscall);
+                                       struct signal_deliver_cookie *);
+               do_signal32(oldset, regs, &cookie);
                return;
        }
 #endif 
@@ -540,7 +543,7 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0, int restart_s
        signr = get_signal_to_deliver(&info, &ka, regs, &cookie);
        if (signr > 0) {
                if (cookie.restart_syscall)
-                       syscall_restart(orig_i0, regs, &ka.sa);
+                       syscall_restart(cookie.orig_i0, regs, &ka.sa);
                handle_signal(signr, &ka, &info, oldset, regs);
 
                /* a signal was successfully delivered; the saved
@@ -577,11 +580,10 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0, int restart_s
        }
 }
 
-void do_notify_resume(struct pt_regs *regs, unsigned long orig_i0, int restart_syscall,
-                     unsigned long thread_info_flags)
+void do_notify_resume(struct pt_regs *regs, unsigned long orig_i0, unsigned long thread_info_flags)
 {
        if (thread_info_flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK))
-               do_signal(regs, orig_i0, restart_syscall);
+               do_signal(regs, orig_i0);
 }
 
 void ptrace_signal_deliver(struct pt_regs *regs, void *cookie)