tracing: Fix stacktrace of latency tracers (irqsoff and friends)
[linux-flexiantxendom0-3.2.10.git] / kernel / ptrace.c
index 9acd07a..ee8d49b 100644 (file)
@@ -231,26 +231,22 @@ bool ptrace_may_access(struct task_struct *task, unsigned int mode)
 }
 
 static int ptrace_attach(struct task_struct *task, long request,
+                        unsigned long addr,
                         unsigned long flags)
 {
        bool seize = (request == PTRACE_SEIZE);
        int retval;
 
-       /*
-        * SEIZE will enable new ptrace behaviors which will be implemented
-        * gradually.  SEIZE_DEVEL is used to prevent applications
-        * expecting full SEIZE behaviors trapping on kernel commits which
-        * are still in the process of implementing them.
-        *
-        * Only test programs for new ptrace behaviors being implemented
-        * should set SEIZE_DEVEL.  If unset, SEIZE will fail with -EIO.
-        *
-        * Once SEIZE behaviors are completely implemented, this flag and
-        * the following test will be removed.
-        */
        retval = -EIO;
-       if (seize && !(flags & PTRACE_SEIZE_DEVEL))
-               goto out;
+       if (seize) {
+               if (addr != 0)
+                       goto out;
+               if (flags & ~(unsigned long)PTRACE_O_MASK)
+                       goto out;
+               flags = PT_PTRACED | PT_SEIZED | (flags << PT_OPT_FLAG_SHIFT);
+       } else {
+               flags = PT_PTRACED;
+       }
 
        audit_ptrace(task);
 
@@ -282,11 +278,11 @@ static int ptrace_attach(struct task_struct *task, long request,
        if (task->ptrace)
                goto unlock_tasklist;
 
-       task->ptrace = PT_PTRACED;
        if (seize)
-               task->ptrace |= PT_SEIZED;
+               flags |= PT_SEIZED;
        if (ns_capable(task_user_ns(task), CAP_SYS_PTRACE))
-               task->ptrace |= PT_PTRACE_CAP;
+               flags |= PT_PTRACE_CAP;
+       task->ptrace = flags;
 
        __ptrace_link(task, current);
 
@@ -879,7 +875,7 @@ SYSCALL_DEFINE4(ptrace, long, request, long, pid, unsigned long, addr,
        }
 
        if (request == PTRACE_ATTACH || request == PTRACE_SEIZE) {
-               ret = ptrace_attach(child, request, data);
+               ret = ptrace_attach(child, request, addr, data);
                /*
                 * Some architectures need to do book-keeping after
                 * a ptrace attach.
@@ -1022,7 +1018,7 @@ asmlinkage long compat_sys_ptrace(compat_long_t request, compat_long_t pid,
        }
 
        if (request == PTRACE_ATTACH || request == PTRACE_SEIZE) {
-               ret = ptrace_attach(child, request, data);
+               ret = ptrace_attach(child, request, addr, data);
                /*
                 * Some architectures need to do book-keeping after
                 * a ptrace attach.