From patchwork Thu Sep 20 16:57:40 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stephen Boyd X-Patchwork-Id: 1486671 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork1.kernel.org Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) by patchwork1.kernel.org (Postfix) with ESMTP id 98F8C3FD40 for ; Thu, 20 Sep 2012 16:59:54 +0000 (UTC) Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.76 #1 (Red Hat Linux)) id 1TEk4S-0006np-3K; Thu, 20 Sep 2012 16:57:48 +0000 Received: from wolverine02.qualcomm.com ([199.106.114.251]) by merlin.infradead.org with esmtps (Exim 4.76 #1 (Red Hat Linux)) id 1TEk4P-0006nT-A2 for linux-arm-kernel@lists.infradead.org; Thu, 20 Sep 2012 16:57:45 +0000 X-IronPort-AV: E=McAfee;i="5400,1158,6841"; a="236931875" Received: from pdmz-ns-snip_115_219.qualcomm.com (HELO mostmsg01.qualcomm.com) ([199.106.115.219]) by wolverine02.qualcomm.com with ESMTP/TLS/DHE-RSA-AES256-SHA; 20 Sep 2012 09:57:42 -0700 Received: from sboyd-linux.qualcomm.com (pdmz-ns-snip_218_1.qualcomm.com [192.168.218.1]) by mostmsg01.qualcomm.com (Postfix) with ESMTPA id 476F610004A2; Thu, 20 Sep 2012 09:57:42 -0700 (PDT) From: Stephen Boyd To: Will Deacon Subject: [PATCH] ARM: hw_breakpoint: Clear breakpoints before enabling monitor mode Date: Thu, 20 Sep 2012 09:57:40 -0700 Message-Id: <1348160260-19486-1-git-send-email-sboyd@codeaurora.org> X-Mailer: git-send-email 1.7.12.1.382.gb0576a6 X-Spam-Note: CRM114 invocation failed X-Spam-Score: -4.2 (----) X-Spam-Report: SpamAssassin version 3.3.2 on merlin.infradead.org summary: Content analysis details: (-4.2 points) pts rule name description ---- ---------------------- -------------------------------------------------- -2.3 RCVD_IN_DNSWL_MED RBL: Sender listed at http://www.dnswl.org/, medium trust [199.106.114.251 listed in list.dnswl.org] -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] Cc: linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: linux-arm-kernel-bounces@lists.infradead.org Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org The reset value of the BCR, BVR, WCR, and WVR registers are all UNKNOWN on ARMv7. Unfortunately, reset_ctrl_regs() clears these registers *after* enabling monitor mode, not before, and so some implementations may experience UNPREDICTABLE behavior if the reset values of these registers are non-zero. Clear the breakpoints before enabling monitor mode so that we don't experience boot hangs/loops due to breakpoints being enabled out of reset. Signed-off-by: Stephen Boyd --- arch/arm/kernel/hw_breakpoint.c | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/arch/arm/kernel/hw_breakpoint.c b/arch/arm/kernel/hw_breakpoint.c index ba386bd..9eac571 100644 --- a/arch/arm/kernel/hw_breakpoint.c +++ b/arch/arm/kernel/hw_breakpoint.c @@ -216,6 +216,20 @@ static int get_num_brps(void) return core_has_mismatch_brps() ? brps - 1 : brps; } +/* Determine if halting mode is enabled */ +static int halting_mode_enabled(void) +{ + u32 dscr; + + ARM_DBG_READ(c1, 0, dscr); + + if (WARN_ONCE(dscr & ARM_DSCR_HDBGEN, + "halting debug mode enabled. Unable to access hardware resources.\n")) { + return -EPERM; + } + return 0; +} + /* * In order to access the breakpoint/watchpoint control registers, * we must be running in debug monitor mode. Unfortunately, we can @@ -225,16 +239,13 @@ static int get_num_brps(void) static int enable_monitor_mode(void) { u32 dscr; - int ret = 0; + int ret; ARM_DBG_READ(c1, 0, dscr); /* Ensure that halting mode is disabled. */ - if (WARN_ONCE(dscr & ARM_DSCR_HDBGEN, - "halting debug mode enabled. Unable to access hardware resources.\n")) { - ret = -EPERM; + if ((ret = halting_mode_enabled())) goto out; - } /* If monitor mode is already enabled, just return. */ if (dscr & ARM_DSCR_MDBGEN) @@ -935,7 +946,7 @@ static void reset_ctrl_regs(void *unused) isb(); reset_regs: - if (enable_monitor_mode()) + if (halting_mode_enabled()) return; /* We must also reset any reserved registers. */ @@ -949,6 +960,7 @@ reset_regs: write_wb_reg(ARM_BASE_WCR + i, 0UL); write_wb_reg(ARM_BASE_WVR + i, 0UL); } + enable_monitor_mode(); } static int __cpuinit dbg_reset_notify(struct notifier_block *self,