sh: update defconfigs.
[safe/jmp/linux-2.6] / arch / powerpc / kernel / signal.c
index dee2750..00b5078 100644 (file)
@@ -9,36 +9,29 @@
  * this archive for more details.
  */
 
-#include <linux/ptrace.h>
+#include <linux/tracehook.h>
 #include <linux/signal.h>
 #include <asm/uaccess.h>
 #include <asm/unistd.h>
 
 #include "signal.h"
 
+/* Log an error when sending an unhandled signal to a process. Controlled
+ * through debug.exception-trace sysctl.
+ */
 
-#ifdef CONFIG_PPC64
-static inline int is_32bit_task(void)
-{
-       return test_thread_flag(TIF_32BIT);
-}
-#else
-static inline int is_32bit_task(void)
-{
-       return 1;
-}
-#endif
+int show_unhandled_signals = 0;
 
 /*
  * Allocate space for the signal frame
  */
 void __user * get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
-                          size_t frame_size)
+                          size_t frame_size, int is_32)
 {
         unsigned long oldsp, newsp;
 
         /* Default to using normal stack */
-        oldsp = regs->gpr[1];
+        oldsp = get_clean_sp(regs, is_32);
 
        /* Check for alt stack */
        if ((ka->sa.sa_flags & SA_ONSTACK) &&
@@ -119,7 +112,7 @@ static void check_syscall_restart(struct pt_regs *regs, struct k_sigaction *ka,
        }
 }
 
-int do_signal(sigset_t *oldset, struct pt_regs *regs)
+static int do_signal_pending(sigset_t *oldset, struct pt_regs *regs)
 {
        siginfo_t info;
        int signr;
@@ -127,7 +120,7 @@ int do_signal(sigset_t *oldset, struct pt_regs *regs)
        int ret;
        int is32 = is_32bit_task();
 
-       if (test_thread_flag(TIF_RESTORE_SIGMASK))
+       if (current_thread_info()->local_flags & _TLF_RESTORE_SIGMASK)
                oldset = &current->saved_sigmask;
        else if (!oldset)
                oldset = &current->blocked;
@@ -138,23 +131,26 @@ int do_signal(sigset_t *oldset, struct pt_regs *regs)
        check_syscall_restart(regs, &ka, signr > 0);
 
        if (signr <= 0) {
+               struct thread_info *ti = current_thread_info();
                /* No signal to deliver -- put the saved sigmask back */
-               if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
-                       clear_thread_flag(TIF_RESTORE_SIGMASK);
+               if (ti->local_flags & _TLF_RESTORE_SIGMASK) {
+                       ti->local_flags &= ~_TLF_RESTORE_SIGMASK;
                        sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
                }
                return 0;               /* no signals delivered */
        }
 
-#ifdef CONFIG_PPC64
         /*
         * Reenable the DABR before delivering the signal to
         * user space. The DABR will have been cleared if it
         * triggered inside the kernel.
         */
-       if (current->thread.dabr)
+       if (current->thread.dabr) {
                set_dabr(current->thread.dabr);
+#if defined(CONFIG_BOOKE)
+               mtspr(SPRN_DBCR0, current->thread.dbcr0);
 #endif
+       }
 
        if (is32) {
                if (ka.sa.sa_flags & SA_SIGINFO)
@@ -163,10 +159,8 @@ int do_signal(sigset_t *oldset, struct pt_regs *regs)
                else
                        ret = handle_signal32(signr, &ka, &info, oldset,
                                        regs);
-#ifdef CONFIG_PPC64
        } else {
                ret = handle_rt_signal64(signr, &ka, &info, oldset, regs);
-#endif
        }
 
        if (ret) {
@@ -180,15 +174,31 @@ int do_signal(sigset_t *oldset, struct pt_regs *regs)
 
                /*
                 * A signal was successfully delivered; the saved sigmask is in
-                * its frame, and we can clear the TIF_RESTORE_SIGMASK flag.
+                * its frame, and we can clear the TLF_RESTORE_SIGMASK flag.
                 */
-               if (test_thread_flag(TIF_RESTORE_SIGMASK))
-                       clear_thread_flag(TIF_RESTORE_SIGMASK);
+               current_thread_info()->local_flags &= ~_TLF_RESTORE_SIGMASK;
+
+               /*
+                * Let tracing know that we've done the handler setup.
+                */
+               tracehook_signal_handler(signr, &info, &ka, regs,
+                                        test_thread_flag(TIF_SINGLESTEP));
        }
 
        return ret;
 }
 
+void do_signal(struct pt_regs *regs, unsigned long thread_info_flags)
+{
+       if (thread_info_flags & _TIF_SIGPENDING)
+               do_signal_pending(NULL, regs);
+
+       if (thread_info_flags & _TIF_NOTIFY_RESUME) {
+               clear_thread_flag(TIF_NOTIFY_RESUME);
+               tracehook_notify_resume(regs);
+       }
+}
+
 long sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss,
                unsigned long r5, unsigned long r6, unsigned long r7,
                unsigned long r8, struct pt_regs *regs)