From patchwork Fri Sep 26 11:54:13 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: AKASHI Takahiro X-Patchwork-Id: 37959 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-wi0-f197.google.com (mail-wi0-f197.google.com [209.85.212.197]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id E67D720F2E for ; Fri, 26 Sep 2014 11:55:03 +0000 (UTC) Received: by mail-wi0-f197.google.com with SMTP id ho1sf5584869wib.8 for ; Fri, 26 Sep 2014 04:55:03 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:delivered-to:from:to:cc:subject :date:message-id:sender:precedence:list-id:x-original-sender :x-original-authentication-results:mailing-list:list-post:list-help :list-archive:list-unsubscribe; bh=5BDZ0+1+fKxZc/RbWHBOpumhCpZgk0YEPM6a6RSJhm0=; b=kbVmHgh213Sx3TEJGR6FLOFvSYtNGbnIccPn41O3wiyZXkbwQDFMog7jBUMjEsY4VW ag4c8bGJjDyJy16aD0JpQ8hlnAWLekWbwwa/eODO5F/5mDisyiTRGPd22oQk/fY+tLsl B96m/n7il4iQ4J0npXxfbBanu5PIm3gwvS1mjY6WiBkNUkcHqZMFe44c9uuFwfG9nyl2 BoS9EyngPBwU4OuJ3zzw1ZURG5D3ZVn7A9qYbaubf0UdqcKbgdG/TcIcnsQqJNYSlMRl X2W7GmUXZClvwum1sIvucJ45xwNg72cjW9LHy3kyf247h830Zg4V+WQPmkFfrbZ9n6Xa q39w== X-Gm-Message-State: ALoCoQnbhXiknin9+GDDI6V6uEuLxREtCEiSX3jhg1Kx9gabAMWRa01IgE1o/4k8kllXX2mY8W1W X-Received: by 10.194.7.199 with SMTP id l7mr3021061wja.2.1411732503073; Fri, 26 Sep 2014 04:55:03 -0700 (PDT) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.152.23.227 with SMTP id p3ls161236laf.39.gmail; Fri, 26 Sep 2014 04:55:02 -0700 (PDT) X-Received: by 10.152.22.200 with SMTP id g8mr19925994laf.1.1411732502753; Fri, 26 Sep 2014 04:55:02 -0700 (PDT) Received: from mail-la0-f43.google.com (mail-la0-f43.google.com [209.85.215.43]) by mx.google.com with ESMTPS id m4si6817972lbd.106.2014.09.26.04.55.02 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Fri, 26 Sep 2014 04:55:02 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.215.43 as permitted sender) client-ip=209.85.215.43; Received: by mail-la0-f43.google.com with SMTP id gb8so4788169lab.16 for ; Fri, 26 Sep 2014 04:55:02 -0700 (PDT) X-Received: by 10.112.130.226 with SMTP id oh2mr2467874lbb.100.1411732502641; Fri, 26 Sep 2014 04:55:02 -0700 (PDT) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patch@linaro.org Received: by 10.112.130.169 with SMTP id of9csp47008lbb; Fri, 26 Sep 2014 04:55:01 -0700 (PDT) X-Received: by 10.66.191.200 with SMTP id ha8mr29591618pac.107.1411732501003; Fri, 26 Sep 2014 04:55:01 -0700 (PDT) Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id i14si9023392pdl.61.2014.09.26.04.55.00 for ; Fri, 26 Sep 2014 04:55:00 -0700 (PDT) Received-SPF: none (google.com: linux-kernel-owner@vger.kernel.org does not designate permitted sender hosts) client-ip=209.132.180.67; Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754474AbaIZLyy (ORCPT + 27 others); Fri, 26 Sep 2014 07:54:54 -0400 Received: from mail-pd0-f172.google.com ([209.85.192.172]:36134 "EHLO mail-pd0-f172.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753326AbaIZLyx (ORCPT ); Fri, 26 Sep 2014 07:54:53 -0400 Received: by mail-pd0-f172.google.com with SMTP id g10so865093pdj.31 for ; Fri, 26 Sep 2014 04:54:52 -0700 (PDT) X-Received: by 10.70.123.136 with SMTP id ma8mr40028519pdb.139.1411732492546; Fri, 26 Sep 2014 04:54:52 -0700 (PDT) Received: from localhost.localdomain (KD182249092252.au-net.ne.jp. [182.249.92.252]) by mx.google.com with ESMTPSA id ps7sm4736288pbb.73.2014.09.26.04.54.47 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 26 Sep 2014 04:54:51 -0700 (PDT) From: AKASHI Takahiro To: catalin.marinas@arm.com, will.deacon@arm.com Cc: dsaxena@linaro.org, Vijaya.Kumar@caviumnetworks.com, linux-arm-kernel@lists.infradead.org, linaro-kernel@lists.linaro.org, linux-kernel@vger.kernel.org, AKASHI Takahiro Subject: [RFC v2] arm64: kgdb: fix single stepping Date: Fri, 26 Sep 2014 20:54:13 +0900 Message-Id: <1411732453-5437-1-git-send-email-takahiro.akashi@linaro.org> X-Mailer: git-send-email 1.9.1 Sender: linux-kernel-owner@vger.kernel.org Precedence: list List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: takahiro.akashi@linaro.org X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.215.43 as permitted sender) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org X-Google-Group-Id: 836684582541 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , I tried to verify kgdb in vanilla kernel on fast model, but it seems that the single stepping with kgdb doesn't work correctly since its first appearance at v3.15. On v3.15, 'stepi' command after breaking the kernel at some breakpoint steps forward to the next instruction, but the succeeding 'stepi' never goes beyond that. On v3.16, 'stepi' moves forward and stops at the next instruction just after enable_dbg in el1_dbg, and never goes beyond that. This variance of behavior seems to come in with the following patch in v3.16: commit 2a2830703a23 ("arm64: debug: avoid accessing mdscr_el1 on fault paths where possible") This patch (1) moves kgdb_disable_single_step() from 'c' command handling to single step handler. This makes sure that single stepping gets effective at every 's' command. Please note that, under the current implementation, single step bit in spsr, which is cleared by the first single stepping, will not be set again for the consecutive 's' commands because single step bit in mdscr is still kept on (that is, kernel_active_single_step() in kgdb_arch_handle_exception() is true). (2) removes 'enable_dbg' in el1_dbg. Single step bit in mdscr is turned on in do_handle_exception()-> kgdb_handle_expection() before returning to debugged context, and if debug exception is enabled in el1_dbg, we will see unexpected single- stepping in el1_dbg. (3) masks interrupts while single-stepping one instruction. If an interrupt is caught during processing a single-stepping, debug exception is unintentionally enabled by el1_irq's 'enable_dbg' before returning to debugged context. Thus, like in (2), we will see unexpected single-stepping in el1_irq. Basically (1) is for v3.15, (2) and (3) with (1) for v3.16. With those changes, we will see another problem if a breakpoint is set at interrupt-sensible places, like gic_handle_irq(): KGDB: re-enter error: breakpoint removed ffffffc000081258 ------------[ cut here ]------------ WARNING: CPU: 0 PID: 650 at kernel/debug/debug_core.c:435 kgdb_handle_exception+0x1dc/0x1f4() Modules linked in: CPU: 0 PID: 650 Comm: sh Not tainted 3.17.0-rc2+ #177 Call trace: [] dump_backtrace+0x0/0x130 [] show_stack+0x10/0x1c [] dump_stack+0x74/0xb8 [] warn_slowpath_common+0x8c/0xb4 [] warn_slowpath_null+0x14/0x20 [] kgdb_handle_exception+0x1d8/0x1f4 [] kgdb_brk_fn+0x18/0x28 [] brk_handler+0x9c/0xe8 [] do_debug_exception+0x3c/0xac Exception stack(0xffffffc07e027650 to 0xffffffc07e027770) ... [] el1_dbg+0x14/0x68 [] kgdb_cpu_enter+0x464/0x5c0 [] kgdb_handle_exception+0x190/0x1f4 [] kgdb_brk_fn+0x18/0x28 [] brk_handler+0x9c/0xe8 [] do_debug_exception+0x3c/0xac Exception stack(0xffffffc07e027ac0 to 0xffffffc07e027be0) ... [] el1_dbg+0x14/0x68 [] __handle_sysrq+0x11c/0x190 [] write_sysrq_trigger+0x4c/0x60 [] proc_reg_write+0x54/0x84 [] vfs_write+0x98/0x1c8 [] SyS_write+0x40/0xa0 Once some interrupt occurs, a breakpoint at gic_handle_irq() triggers kgdb. Kgdb then calls kgdb_roundup_cpus() to sync with other cpus. Current kgdb_roundup_cpus() unmasks interrupts temporarily to use smp_call_function(). This eventually allows another interrupt to occur and likely results in hitting a breakpoint at gic_handle_irq() again since debug exception is always enabled in el1_irq. We can avoid this issue by specifying "nokgdbroundup" in kernel parameter, but this will also leave other cpus be in unknown state in terms of kgdb, and may result in interfering with kgdb activity. Signed-off-by: AKASHI Takahiro --- arch/arm64/kernel/entry.S | 1 - arch/arm64/kernel/kgdb.c | 29 +++++++++++++++++++---------- 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S index fdd6eae..a935d5f 100644 --- a/arch/arm64/kernel/entry.S +++ b/arch/arm64/kernel/entry.S @@ -325,7 +325,6 @@ el1_dbg: mrs x0, far_el1 mov x2, sp // struct pt_regs bl do_debug_exception - enable_dbg kernel_exit 1 el1_inv: // TODO: add support for undefined instructions in kernel mode diff --git a/arch/arm64/kernel/kgdb.c b/arch/arm64/kernel/kgdb.c index 75c9cf1..f1fc1d8 100644 --- a/arch/arm64/kernel/kgdb.c +++ b/arch/arm64/kernel/kgdb.c @@ -22,6 +22,7 @@ #include #include #include +#include #include struct dbg_reg_def_t dbg_reg_def[DBG_MAX_REG_NUM] = { @@ -95,6 +96,8 @@ struct dbg_reg_def_t dbg_reg_def[DBG_MAX_REG_NUM] = { { "fpcr", 4, -1 }, }; +static DEFINE_PER_CPU(unsigned int, kgdb_pstate); + char *dbg_get_reg(int regno, void *mem, struct pt_regs *regs) { if (regno >= DBG_MAX_REG_NUM || regno < 0) @@ -176,18 +179,14 @@ int kgdb_arch_handle_exception(int exception_vector, int signo, * over and over again. */ kgdb_arch_update_addr(linux_regs, remcom_in_buffer); - atomic_set(&kgdb_cpu_doing_single_step, -1); - kgdb_single_step = 0; - - /* - * Received continue command, disable single step - */ - if (kernel_active_single_step()) - kernel_disable_single_step(); err = 0; break; case 's': + /* mask interrupts while single stepping */ + __this_cpu_write(kgdb_pstate, linux_regs->pstate); + linux_regs->pstate |= (1 << 7); + /* * Update step address value with address passed * with step packet. @@ -198,8 +197,6 @@ int kgdb_arch_handle_exception(int exception_vector, int signo, */ kgdb_arch_update_addr(linux_regs, remcom_in_buffer); atomic_set(&kgdb_cpu_doing_single_step, raw_smp_processor_id()); - kgdb_single_step = 1; - /* * Enable single step handling */ @@ -229,6 +226,18 @@ static int kgdb_compiled_brk_fn(struct pt_regs *regs, unsigned int esr) static int kgdb_step_brk_fn(struct pt_regs *regs, unsigned int esr) { + unsigned int pstate; + + kernel_disable_single_step(); + atomic_set(&kgdb_cpu_doing_single_step, -1); + + /* restore interrupt mask status */ + pstate = __this_cpu_read(kgdb_pstate); + if (pstate & (1 << 7)) + regs->pstate |= (1 << 7); + else + regs->pstate &= ~(1 << 7); + kgdb_handle_exception(1, SIGTRAP, 0, regs); return 0; }