Merge branch 'exec_rm_compat' of git://git.kernel.org/pub/scm/linux/kernel/git/oleg...
[pandora-kernel.git] / arch / x86 / kernel / ptrace.c
index 45892dc..f65e5b5 100644 (file)
@@ -608,6 +608,9 @@ static int ptrace_write_dr7(struct task_struct *tsk, unsigned long data)
        unsigned len, type;
        struct perf_event *bp;
 
+       if (ptrace_get_breakpoints(tsk) < 0)
+               return -ESRCH;
+
        data &= ~DR_CONTROL_RESERVED;
        old_dr7 = ptrace_get_dr7(thread->ptrace_bps);
 restore:
@@ -655,6 +658,9 @@ restore:
                }
                goto restore;
        }
+
+       ptrace_put_breakpoints(tsk);
+
        return ((orig_ret < 0) ? orig_ret : rc);
 }
 
@@ -668,10 +674,17 @@ static unsigned long ptrace_get_debugreg(struct task_struct *tsk, int n)
 
        if (n < HBP_NUM) {
                struct perf_event *bp;
+
+               if (ptrace_get_breakpoints(tsk) < 0)
+                       return -ESRCH;
+
                bp = thread->ptrace_bps[n];
                if (!bp)
-                       return 0;
-               val = bp->hw.info.address;
+                       val = 0;
+               else
+                       val = bp->hw.info.address;
+
+               ptrace_put_breakpoints(tsk);
        } else if (n == 6) {
                val = thread->debugreg6;
         } else if (n == 7) {
@@ -686,6 +699,10 @@ static int ptrace_set_breakpoint_addr(struct task_struct *tsk, int nr,
        struct perf_event *bp;
        struct thread_struct *t = &tsk->thread;
        struct perf_event_attr attr;
+       int err = 0;
+
+       if (ptrace_get_breakpoints(tsk) < 0)
+               return -ESRCH;
 
        if (!t->ptrace_bps[nr]) {
                ptrace_breakpoint_init(&attr);
@@ -709,24 +726,23 @@ static int ptrace_set_breakpoint_addr(struct task_struct *tsk, int nr,
                 * writing for the user. And anyway this is the previous
                 * behaviour.
                 */
-               if (IS_ERR(bp))
-                       return PTR_ERR(bp);
+               if (IS_ERR(bp)) {
+                       err = PTR_ERR(bp);
+                       goto put;
+               }
 
                t->ptrace_bps[nr] = bp;
        } else {
-               int err;
-
                bp = t->ptrace_bps[nr];
 
                attr = bp->attr;
                attr.bp_addr = addr;
                err = modify_user_hw_breakpoint(bp, &attr);
-               if (err)
-                       return err;
        }
 
-
-       return 0;
+put:
+       ptrace_put_breakpoints(tsk);
+       return err;
 }
 
 /*