]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
ptrace/powerpc: revert "hw_breakpoints: Fix racy access to ptrace breakpoints"
authorOleg Nesterov <oleg@redhat.com>
Wed, 19 Jun 2013 00:08:13 +0000 (10:08 +1000)
committerStephen Rothwell <sfr@canb.auug.org.au>
Wed, 19 Jun 2013 07:27:37 +0000 (17:27 +1000)
This reverts commit 07fa7a0a8a586 ("hw_breakpoints: Fix racy access to
ptrace breakpoints") and removes ptrace_get/put_breakpoints() added by
other commits.

The patch was fine but we can no longer race with SIGKILL after 9899d11f
("ptrace: ensure arch_ptrace/ptrace_request can never race with SIGKILL"),
the __TASK_TRACED tracee can't be woken up and ->ptrace_bps[] can't go
away.

Signed-off-by: Oleg Nesterov <oleg@redhat.com>
Acked-by: Michael Neuling <mikey@neuling.org>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Jan Kratochvil <jan.kratochvil@redhat.com>
Cc: Paul Mundt <lethal@linux-sh.org>
Cc: Will Deacon <will.deacon@arm.com>
Cc: Prasad <prasad@linux.vnet.ibm.com>
Cc: Russell King <linux@arm.linux.org.uk>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
arch/powerpc/kernel/ptrace.c

index 98c2fc198712aabe3f90055e24d653df604be78e..6645e573c44c34f50a7a634a9d67daaa9467ff69 100644 (file)
@@ -975,16 +975,12 @@ int ptrace_set_debugreg(struct task_struct *task, unsigned long addr,
        hw_brk.type = (data & HW_BRK_TYPE_DABR) | HW_BRK_TYPE_PRIV_ALL;
        hw_brk.len = 8;
 #ifdef CONFIG_HAVE_HW_BREAKPOINT
-       if (ptrace_get_breakpoints(task) < 0)
-               return -ESRCH;
-
        bp = thread->ptrace_bps[0];
        if ((!data) || !(hw_brk.type & HW_BRK_TYPE_RDWR)) {
                if (bp) {
                        unregister_hw_breakpoint(bp);
                        thread->ptrace_bps[0] = NULL;
                }
-               ptrace_put_breakpoints(task);
                return 0;
        }
        if (bp) {
@@ -997,11 +993,9 @@ int ptrace_set_debugreg(struct task_struct *task, unsigned long addr,
 
                ret =  modify_user_hw_breakpoint(bp, &attr);
                if (ret) {
-                       ptrace_put_breakpoints(task);
                        return ret;
                }
                thread->ptrace_bps[0] = bp;
-               ptrace_put_breakpoints(task);
                thread->hw_brk = hw_brk;
                return 0;
        }
@@ -1016,12 +1010,9 @@ int ptrace_set_debugreg(struct task_struct *task, unsigned long addr,
                                               ptrace_triggered, NULL, task);
        if (IS_ERR(bp)) {
                thread->ptrace_bps[0] = NULL;
-               ptrace_put_breakpoints(task);
                return PTR_ERR(bp);
        }
 
-       ptrace_put_breakpoints(task);
-
 #endif /* CONFIG_HAVE_HW_BREAKPOINT */
        task->thread.hw_brk = hw_brk;
 #else /* CONFIG_PPC_ADV_DEBUG_REGS */
@@ -1440,9 +1431,6 @@ static long ppc_set_hwdebug(struct task_struct *child,
        if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_WRITE)
                brk.type |= HW_BRK_TYPE_WRITE;
 #ifdef CONFIG_HAVE_HW_BREAKPOINT
-       if (ptrace_get_breakpoints(child) < 0)
-               return -ESRCH;
-
        /*
         * Check if the request is for 'range' breakpoints. We can
         * support it if range < 8 bytes.
@@ -1450,12 +1438,10 @@ static long ppc_set_hwdebug(struct task_struct *child,
        if (bp_info->addr_mode == PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE) {
                len = bp_info->addr2 - bp_info->addr;
        } else if (bp_info->addr_mode != PPC_BREAKPOINT_MODE_EXACT) {
-               ptrace_put_breakpoints(child);
                return -EINVAL;
        }
        bp = thread->ptrace_bps[0];
        if (bp) {
-               ptrace_put_breakpoints(child);
                return -ENOSPC;
        }
 
@@ -1469,11 +1455,9 @@ static long ppc_set_hwdebug(struct task_struct *child,
                                               ptrace_triggered, NULL, child);
        if (IS_ERR(bp)) {
                thread->ptrace_bps[0] = NULL;
-               ptrace_put_breakpoints(child);
                return PTR_ERR(bp);
        }
 
-       ptrace_put_breakpoints(child);
        return 1;
 #endif /* CONFIG_HAVE_HW_BREAKPOINT */
 
@@ -1517,16 +1501,12 @@ static long ppc_del_hwdebug(struct task_struct *child, long data)
                return -EINVAL;
 
 #ifdef CONFIG_HAVE_HW_BREAKPOINT
-       if (ptrace_get_breakpoints(child) < 0)
-               return -ESRCH;
-
        bp = thread->ptrace_bps[0];
        if (bp) {
                unregister_hw_breakpoint(bp);
                thread->ptrace_bps[0] = NULL;
        } else
                ret = -ENOENT;
-       ptrace_put_breakpoints(child);
        return ret;
 #else /* CONFIG_HAVE_HW_BREAKPOINT */
        if (child->thread.hw_brk.address == 0)