From patchwork Fri Sep 23 07:33:26 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: AKASHI Takahiro X-Patchwork-Id: 76829 Delivered-To: patch@linaro.org Received: by 10.140.106.72 with SMTP id d66csp425265qgf; Fri, 23 Sep 2016 00:27:07 -0700 (PDT) X-Received: by 10.66.177.193 with SMTP id cs1mr10186880pac.140.1474615627005; Fri, 23 Sep 2016 00:27:07 -0700 (PDT) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id sq10si6552364pab.73.2016.09.23.00.27.06; Fri, 23 Sep 2016 00:27:06 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of stable-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org; spf=pass (google.com: best guess record for domain of stable-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=stable-owner@vger.kernel.org; dmarc=fail (p=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S934461AbcIWH1G (ORCPT + 3 others); Fri, 23 Sep 2016 03:27:06 -0400 Received: from mail-pa0-f52.google.com ([209.85.220.52]:34274 "EHLO mail-pa0-f52.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S934103AbcIWH1F (ORCPT ); Fri, 23 Sep 2016 03:27:05 -0400 Received: by mail-pa0-f52.google.com with SMTP id wk8so37591450pab.1 for ; Fri, 23 Sep 2016 00:27:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=n8tUYl52WewDPYJjmQGlnd03JAoznAMeRCUoQtQum9w=; b=cXPkQpyF75YEaOvsUCleKq27OMM8ZXjCNAhpK9/xgkjGmYjxuNtgINxFvb1PF3OFXX Rh3TQnzTMg0fjcAJKn12ZWKjlc1ycb6NJ2uVihjGNIqJvuI5PjCpY8h6mKripzII7nQu +6yK7Fg9U2obHJmC5kDopEwirrwAnswmqsk8g= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=n8tUYl52WewDPYJjmQGlnd03JAoznAMeRCUoQtQum9w=; b=gdtfcyL8FtiTukuNbICJdtL9Oaq3vPgmk3Uj+wTdtJQQP0CnfPvvz4TwqPw9+G+/80 B8ZnIJZWcRffEX+j6lwDaOilJ65HEwZXJ+35nmvYYua5bX6gU7OYMndhi+tukQ1LWcc7 psi4AYnhLcSe8UL7ccGoaafrbCYRtlNZjOdYDOKqXZqOzSeHLjq92kl5S+h8vC0KKfge 7HloxpDqMSXBxv+H3y2yJhAJ7SGordKtMYnIHdg06x2FJmXdRVGh/KaONs+ydgpM+b5x Hi9qAw1AegNQJ6EfcxrloQu6AHQ3WZLH4nRi5iTj6bualsIEF+4gxB7BNn6ASEczhSx9 wB1A== X-Gm-Message-State: AE9vXwMAwouj148G5R4gBYNIbJNvvGPREeXwXNIq0KtIlALXL74q27kK9EDP7X3t18CS4c9V X-Received: by 10.66.27.137 with SMTP id t9mr10079348pag.11.1474615624394; Fri, 23 Sep 2016 00:27:04 -0700 (PDT) Received: from linaro.org ([121.95.100.191]) by smtp.googlemail.com with ESMTPSA id s12sm8847143pfj.73.2016.09.23.00.27.03 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 23 Sep 2016 00:27:03 -0700 (PDT) From: AKASHI Takahiro To: catalin.marinas@arm.com, will.deacon@arm.com, jason.wessel@windriver.com Cc: linux-arm-kernel@lists.infradead.org, kgdb-bugreport@lists.sourceforge.net, stable@vger.kernel.org, AKASHI Takahiro Subject: [PATCH v2 2/3] arm64: kgdb: prevent kgdb from being invoked recursively Date: Fri, 23 Sep 2016 16:33:26 +0900 Message-Id: <20160923073327.9657-3-takahiro.akashi@linaro.org> X-Mailer: git-send-email 2.10.0 In-Reply-To: <20160923073327.9657-1-takahiro.akashi@linaro.org> References: <20160923073327.9657-1-takahiro.akashi@linaro.org> Sender: stable-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: stable@vger.kernel.org If a breakpoint is set in an interrupt-sensitive place, like gic_handle_irq(), a debug exception can be triggerred recursively. We will see the following message: 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 When some interrupt occurs, a breakpoint at gic_handle_irq() invokes 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 a debug exception is always enabled in el1_irq. We can avoid this issue by specifying "nokgdbroundup" in a kernel command line, but this will also leave other cpus be in unknown state in terms of kgdb, and may result in interfering with kgdb. This patch re-implements kgdb_roundup_cpus() so that we won't have to enable interrupts there by using irq_work. Signed-off-by: AKASHI Takahiro Cc: Catalin Marinas Cc: Will Deacon Cc: Jason Wessel Cc: # 3.15- --- arch/arm64/kernel/kgdb.c | 32 ++++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) -- 2.10.0 -- To unsubscribe from this list: send the line "unsubscribe stable" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/arch/arm64/kernel/kgdb.c b/arch/arm64/kernel/kgdb.c index afe5f90..59c4aec 100644 --- a/arch/arm64/kernel/kgdb.c +++ b/arch/arm64/kernel/kgdb.c @@ -19,10 +19,13 @@ * along with this program. If not, see . */ +#include #include +#include #include #include #include +#include #include struct dbg_reg_def_t dbg_reg_def[DBG_MAX_REG_NUM] = { @@ -106,6 +109,8 @@ struct dbg_reg_def_t dbg_reg_def[DBG_MAX_REG_NUM] = { { "fpcr", 4, -1 }, }; +static DEFINE_PER_CPU(struct irq_work, kgdb_irq_work); + char *dbg_get_reg(int regno, void *mem, struct pt_regs *regs) { if (regno >= DBG_MAX_REG_NUM || regno < 0) @@ -258,16 +263,27 @@ static struct step_hook kgdb_step_hook = { .fn = kgdb_step_brk_fn }; -static void kgdb_call_nmi_hook(void *ignored) +static void kgdb_roundup_hook(struct irq_work *work) { kgdb_nmicallback(raw_smp_processor_id(), get_irq_regs()); } void kgdb_roundup_cpus(unsigned long flags) { - local_irq_enable(); - smp_call_function(kgdb_call_nmi_hook, NULL, 0); - local_irq_disable(); + int cpu; + struct cpumask mask; + struct irq_work *work; + + mask = *cpu_online_mask; + cpumask_clear_cpu(smp_processor_id(), &mask); + cpu = cpumask_first(&mask); + if (cpu >= nr_cpu_ids) + return; + + for_each_cpu(cpu, &mask) { + work = per_cpu_ptr(&kgdb_irq_work, cpu); + irq_work_queue_on(work, cpu); + } } static int __kgdb_notify(struct die_args *args, unsigned long cmd) @@ -308,6 +324,8 @@ static struct notifier_block kgdb_notifier = { int kgdb_arch_init(void) { int ret = register_die_notifier(&kgdb_notifier); + int cpu; + struct irq_work *work; if (ret != 0) return ret; @@ -315,6 +333,12 @@ int kgdb_arch_init(void) register_break_hook(&kgdb_brkpt_hook); register_break_hook(&kgdb_compiled_brkpt_hook); register_step_hook(&kgdb_step_hook); + + for_each_possible_cpu(cpu) { + work = per_cpu_ptr(&kgdb_irq_work, cpu); + init_irq_work(work, kgdb_roundup_hook); + } + return 0; }