From mboxrd@z Thu Jan 1 00:00:00 1970 From: Oleg Nesterov Subject: [PATCH 09/13] ptrace/x86: ptrace_write_dr7() should create bp if !disabled Date: Mon, 13 May 2013 17:17:29 +0200 Message-ID: <20130513151729.GA6283@redhat.com> References: <20130513151631.GA6215@redhat.com> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Return-path: Content-Disposition: inline In-Reply-To: <20130513151631.GA6215@redhat.com> Sender: linux-kernel-owner@vger.kernel.org To: Andrew Morton Cc: Benjamin Herrenschmidt , Frederic Weisbecker , Ingo Molnar , Jan Kratochvil , Michael Neuling , Paul Mackerras , Paul Mundt , Prasad , Russell King , Will Deacon , linux-arch@vger.kernel.org, linux-kernel@vger.kernel.org List-Id: linux-arch.vger.kernel.org 24f1e32c "hw-breakpoints: Rewrite the hw-breakpoints layer on top of perf events" introduced the minor regression. Before this commit PTRACE_POKEUSER DR7, enableDR0 PTRACE_POKEUSER DR0, address was perfectly valid, now PTRACE_POKEUSER(DR7) fails if DR0 was not previously initialized by PTRACE_POKEUSER(DR0). Change ptrace_write_dr7() to do ptrace_register_breakpoint(addr => 0) if !bp && !disabled. This fixes watchpoint-zeroaddr from ptrace-tests, see https://bugzilla.redhat.com/show_bug.cgi?id=660204. Reported-by: Jan Kratochvil Signed-off-by: Oleg Nesterov Acked-by: Frederic Weisbecker --- arch/x86/kernel/ptrace.c | 17 ++++++++++------- 1 files changed, 10 insertions(+), 7 deletions(-) diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c index 0526368..5c387b3 100644 --- a/arch/x86/kernel/ptrace.c +++ b/arch/x86/kernel/ptrace.c @@ -670,13 +670,16 @@ restore: if (!bp) { if (disabled) continue; - /* - * We should have at least an inactive breakpoint at - * this slot. It means the user is writing dr7 without - * having written the address register first. - */ - rc = -EINVAL; - break; + + bp = ptrace_register_breakpoint(tsk, + len, type, 0, disabled); + if (IS_ERR(bp)) { + rc = PTR_ERR(bp); + break; + } + + thread->ptrace_bps[i] = bp; + continue; } rc = ptrace_modify_breakpoint(bp, len, type, disabled); -- 1.5.5.1 From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mx1.redhat.com ([209.132.183.28]:6662 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754855Ab3EMPVN (ORCPT ); Mon, 13 May 2013 11:21:13 -0400 Date: Mon, 13 May 2013 17:17:29 +0200 From: Oleg Nesterov Subject: [PATCH 09/13] ptrace/x86: ptrace_write_dr7() should create bp if !disabled Message-ID: <20130513151729.GA6283@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20130513151631.GA6215@redhat.com> Sender: linux-arch-owner@vger.kernel.org List-ID: To: Andrew Morton Cc: Benjamin Herrenschmidt , Frederic Weisbecker , Ingo Molnar , Jan Kratochvil , Michael Neuling , Paul Mackerras , Paul Mundt , Prasad , Russell King , Will Deacon , linux-arch@vger.kernel.org, linux-kernel@vger.kernel.org Message-ID: <20130513151729.B5Df1b-X6wBEW9N9_WJ_-Wp5qI93k8bCKYn4FvuEh5Y@z> 24f1e32c "hw-breakpoints: Rewrite the hw-breakpoints layer on top of perf events" introduced the minor regression. Before this commit PTRACE_POKEUSER DR7, enableDR0 PTRACE_POKEUSER DR0, address was perfectly valid, now PTRACE_POKEUSER(DR7) fails if DR0 was not previously initialized by PTRACE_POKEUSER(DR0). Change ptrace_write_dr7() to do ptrace_register_breakpoint(addr => 0) if !bp && !disabled. This fixes watchpoint-zeroaddr from ptrace-tests, see https://bugzilla.redhat.com/show_bug.cgi?id=660204. Reported-by: Jan Kratochvil Signed-off-by: Oleg Nesterov Acked-by: Frederic Weisbecker --- arch/x86/kernel/ptrace.c | 17 ++++++++++------- 1 files changed, 10 insertions(+), 7 deletions(-) diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c index 0526368..5c387b3 100644 --- a/arch/x86/kernel/ptrace.c +++ b/arch/x86/kernel/ptrace.c @@ -670,13 +670,16 @@ restore: if (!bp) { if (disabled) continue; - /* - * We should have at least an inactive breakpoint at - * this slot. It means the user is writing dr7 without - * having written the address register first. - */ - rc = -EINVAL; - break; + + bp = ptrace_register_breakpoint(tsk, + len, type, 0, disabled); + if (IS_ERR(bp)) { + rc = PTR_ERR(bp); + break; + } + + thread->ptrace_bps[i] = bp; + continue; } rc = ptrace_modify_breakpoint(bp, len, type, disabled); -- 1.5.5.1