]> git.karo-electronics.de Git - mv-sheeva.git/blobdiff - arch/x86/kernel/signal_64.c
Merge branches 'x86/alternatives', 'x86/cleanups', 'x86/commandline', 'x86/crashdump...
[mv-sheeva.git] / arch / x86 / kernel / signal_64.c
index 162da796a323d2140ca2236984cc7b8816f507cf..694aa888bb1993d7d7a38f8fe09b15a607867c7c 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/errno.h>
 #include <linux/wait.h>
 #include <linux/ptrace.h>
+#include <linux/tracehook.h>
 #include <linux/unistd.h>
 #include <linux/stddef.h>
 #include <linux/personality.h>
@@ -27,6 +28,8 @@
 #include <asm/proto.h>
 #include <asm/ia32_unistd.h>
 #include <asm/mce.h>
+#include <asm/syscall.h>
+#include <asm/syscalls.h>
 #include "sigframe.h"
 
 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
@@ -351,35 +354,6 @@ give_sigsegv:
        return -EFAULT;
 }
 
-/*
- * Return -1L or the syscall number that @regs is executing.
- */
-static long current_syscall(struct pt_regs *regs)
-{
-       /*
-        * We always sign-extend a -1 value being set here,
-        * so this is always either -1L or a syscall number.
-        */
-       return regs->orig_ax;
-}
-
-/*
- * Return a value that is -EFOO if the system call in @regs->orig_ax
- * returned an error.  This only works for @regs from @current.
- */
-static long current_syscall_ret(struct pt_regs *regs)
-{
-#ifdef CONFIG_IA32_EMULATION
-       if (test_thread_flag(TIF_IA32))
-               /*
-                * Sign-extend the value so (int)-EFOO becomes (long)-EFOO
-                * and will match correctly in comparisons.
-                */
-               return (int) regs->ax;
-#endif
-       return regs->ax;
-}
-
 /*
  * OK, we're invoking a handler
  */
@@ -391,9 +365,9 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
        int ret;
 
        /* Are we from a system call? */
-       if (current_syscall(regs) >= 0) {
+       if (syscall_get_nr(current, regs) >= 0) {
                /* If so, check system call restarting.. */
-               switch (current_syscall_ret(regs)) {
+               switch (syscall_get_error(current, regs)) {
                case -ERESTART_RESTARTBLOCK:
                case -ERESTARTNOHAND:
                        regs->ax = -EINTR;
@@ -450,8 +424,6 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
                 * handler too.
                 */
                regs->flags &= ~X86_EFLAGS_TF;
-               if (test_thread_flag(TIF_SINGLESTEP))
-                       ptrace_notify(SIGTRAP);
 
                spin_lock_irq(&current->sighand->siglock);
                sigorsets(&current->blocked, &current->blocked, &ka->sa.sa_mask);
@@ -459,6 +431,9 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
                        sigaddset(&current->blocked, sig);
                recalc_sigpending();
                spin_unlock_irq(&current->sighand->siglock);
+
+               tracehook_signal_handler(sig, info, ka, regs,
+                                        test_thread_flag(TIF_SINGLESTEP));
        }
 
        return ret;
@@ -515,9 +490,9 @@ static void do_signal(struct pt_regs *regs)
        }
 
        /* Did we come from a system call? */
-       if (current_syscall(regs) >= 0) {
+       if (syscall_get_nr(current, regs) >= 0) {
                /* Restart the system call - no handlers present */
-               switch (current_syscall_ret(regs)) {
+               switch (syscall_get_error(current, regs)) {
                case -ERESTARTNOHAND:
                case -ERESTARTSYS:
                case -ERESTARTNOINTR:
@@ -555,6 +530,11 @@ void do_notify_resume(struct pt_regs *regs, void *unused,
        /* deal with pending signal delivery */
        if (thread_info_flags & _TIF_SIGPENDING)
                do_signal(regs);
+
+       if (thread_info_flags & _TIF_NOTIFY_RESUME) {
+               clear_thread_flag(TIF_NOTIFY_RESUME);
+               tracehook_notify_resume(regs);
+       }
 }
 
 void signal_fault(struct pt_regs *regs, void __user *frame, char *where)