From patchwork Fri May 10 00:10:50 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: John Stultz X-Patchwork-Id: 16810 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-qc0-f200.google.com (mail-qc0-f200.google.com [209.85.216.200]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 37A4224AAB for ; Fri, 10 May 2013 00:11:50 +0000 (UTC) Received: by mail-qc0-f200.google.com with SMTP id s10sf4266135qcv.7 for ; Thu, 09 May 2013 17:11:25 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=x-received:x-beenthere:x-received:received-spf:x-received :x-forwarded-to:x-forwarded-for:delivered-to:x-received:received-spf :x-received:from:to:cc:subject:date:message-id:x-mailer:in-reply-to :references:mime-version:x-gm-message-state:x-original-sender :x-original-authentication-results:precedence:mailing-list:list-id :x-google-group-id:list-post:list-help:list-archive:list-unsubscribe :content-type:content-transfer-encoding; bh=fzT41BDkcnoTL7LImvE+UVmOAQd7Va8QiVe+yy0RWkU=; b=FQRba/ZxVlxpR+GWkMKNDzpHHTEkPv0krjisqmh3b8ACIkRCArQEO2URviecaATcTF 59jzJhY0xbRuk/EN8fwZl/zDJc+qdqYUIuigHQxvgrAvtFZ6lhfKxSvdzXT6ZANSkh1o 1+c1jNo/uHgSBD1fotSDwIWu+YZx03TBLVQJ9PX0iVzp0lArecJhvYglY4Egf7UJgh69 PCqnopMMl9RD3jMpgoirmfKyvrfMj02F3qycquaXSFbnj5luJ8ORse4Ps0trK5J/IRT+ sZrFcGydWy5rF/umwm6+YdCg4fKjwzaFa0a1huHGVM3freBsxlCojRISuXvGzhRksKQY 0QEA== X-Received: by 10.224.217.195 with SMTP id hn3mr10891979qab.5.1368144685429; Thu, 09 May 2013 17:11:25 -0700 (PDT) X-BeenThere: patchwork-forward@linaro.org Received: by 10.49.51.40 with SMTP id h8ls1609354qeo.33.gmail; Thu, 09 May 2013 17:11:25 -0700 (PDT) X-Received: by 10.220.75.210 with SMTP id z18mr9661999vcj.64.1368144685230; Thu, 09 May 2013 17:11:25 -0700 (PDT) Received: from mail-ve0-x234.google.com (mail-ve0-x234.google.com [2607:f8b0:400c:c01::234]) by mx.google.com with ESMTPS id b4si149468vdw.135.2013.05.09.17.11.25 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Thu, 09 May 2013 17:11:25 -0700 (PDT) Received-SPF: neutral (google.com: 2607:f8b0:400c:c01::234 is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) client-ip=2607:f8b0:400c:c01::234; Received: by mail-ve0-f180.google.com with SMTP id pa12so3363560veb.39 for ; Thu, 09 May 2013 17:11:25 -0700 (PDT) X-Received: by 10.52.36.115 with SMTP id p19mr2563837vdj.8.1368144684959; Thu, 09 May 2013 17:11:24 -0700 (PDT) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patches@linaro.org Received: by 10.58.170.105 with SMTP id al9csp17523vec; Thu, 9 May 2013 17:11:24 -0700 (PDT) X-Received: by 10.68.176.133 with SMTP id ci5mr14769643pbc.21.1368144683652; Thu, 09 May 2013 17:11:23 -0700 (PDT) Received: from mail-pb0-x229.google.com (mail-pb0-x229.google.com [2607:f8b0:400e:c01::229]) by mx.google.com with ESMTPS id sk3si245702pab.29.2013.05.09.17.11.23 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Thu, 09 May 2013 17:11:23 -0700 (PDT) Received-SPF: neutral (google.com: 2607:f8b0:400e:c01::229 is neither permitted nor denied by best guess record for domain of john.stultz@linaro.org) client-ip=2607:f8b0:400e:c01::229; Received: by mail-pb0-f41.google.com with SMTP id jt11so458259pbb.0 for ; Thu, 09 May 2013 17:11:23 -0700 (PDT) X-Received: by 10.66.248.228 with SMTP id yp4mr15160167pac.158.1368144683062; Thu, 09 May 2013 17:11:23 -0700 (PDT) Received: from localhost.localdomain (c-24-21-54-107.hsd1.or.comcast.net. [24.21.54.107]) by mx.google.com with ESMTPSA id aa8sm355657pad.14.2013.05.09.17.11.21 for (version=TLSv1.1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Thu, 09 May 2013 17:11:21 -0700 (PDT) From: John Stultz To: linux-kernel@vger.kernel.org Cc: Anton Vorontsov , Russell King , Nicolas Pitre , Arnd Bergmann , Jason Wessel , Andrew Morton , linux-arm-kernel@lists.infradead.org, kernel-team@android.com, John Stultz Subject: [PATCH 2/3] ARM: Add KGDB/KDB FIQ debugger generic code Date: Thu, 9 May 2013 17:10:50 -0700 Message-Id: <1368144651-11250-3-git-send-email-john.stultz@linaro.org> X-Mailer: git-send-email 1.8.1.2 In-Reply-To: <1368144651-11250-1-git-send-email-john.stultz@linaro.org> References: <1368144651-11250-1-git-send-email-john.stultz@linaro.org> MIME-Version: 1.0 X-Gm-Message-State: ALoCoQn+ceUwwSkwHM58UsceZ7IHNGv+w8Dkiv02RYb2+nxE8wYFueb3hj4S3SZtq8A5zAFCwT1V X-Original-Sender: john.stultz@linaro.org X-Original-Authentication-Results: mx.google.com; spf=neutral (google.com: 2607:f8b0:400c:c01::234 is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Precedence: list Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org List-ID: X-Google-Group-Id: 836684582541 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , From: Anton Vorontsov The FIQ debugger may be used to debug situations when the kernel stuck in uninterruptable sections, e.g. the kernel infinitely loops or deadlocked in an interrupt or with interrupts disabled. By default KGDB FIQ is disabled in runtime, but can be enabled with kgdb_fiq.enable=1 kernel command line option. Cc: Anton Vorontsov Cc: Russell King Cc: Nicolas Pitre Cc: Arnd Bergmann Cc: Jason Wessel Cc: Andrew Morton Cc: linux-arm-kernel@lists.infradead.org Cc: kernel-team@android.com Signed-off-by: Anton Vorontsov Signed-off-by: John Stultz --- arch/arm/Kconfig | 18 ++++++ arch/arm/include/asm/kgdb.h | 7 +++ arch/arm/kernel/Makefile | 1 + arch/arm/kernel/kgdb_fiq.c | 118 +++++++++++++++++++++++++++++++++++++++ arch/arm/kernel/kgdb_fiq_entry.S | 87 +++++++++++++++++++++++++++++ 5 files changed, 231 insertions(+) create mode 100644 arch/arm/kernel/kgdb_fiq.c create mode 100644 arch/arm/kernel/kgdb_fiq_entry.S diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 1e31dac..66a9076 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -203,6 +203,24 @@ config GENERIC_ISA_DMA config FIQ bool +config ARCH_MIGHT_HAVE_KGDB_FIQ + bool + +config KGDB_FIQ + bool "KGDB/KDB FIQ debugger" + depends on KGDB_KDB && ARCH_MIGHT_HAVE_KGDB_FIQ && !THUMB2_KERNEL + select FIQ + help + The FIQ debugger may be used to debug situations when the + kernel stuck in uninterruptable sections, e.g. the kernel + infinitely loops or deadlocked in an interrupt or with + interrupts disabled. + + By default KGDB FIQ is disabled in runtime, but can be + enabled with kgdb_fiq.enable=1 kernel command line option. + + If unsure, say N. + config NEED_RET_TO_USER bool diff --git a/arch/arm/include/asm/kgdb.h b/arch/arm/include/asm/kgdb.h index 48066ce..75019984 100644 --- a/arch/arm/include/asm/kgdb.h +++ b/arch/arm/include/asm/kgdb.h @@ -11,6 +11,8 @@ #define __ARM_KGDB_H__ #include +#include +#include /* * GDB assumes that we're a user process being debugged, so @@ -47,6 +49,11 @@ static inline void arch_kgdb_breakpoint(void) extern void kgdb_handle_bus_error(void); extern int kgdb_fault_expected; +extern char kgdb_fiq_handler; +extern char kgdb_fiq_handler_end; +asmlinkage void __exception_irq_entry kgdb_fiq_do_handle(struct pt_regs *regs); +extern int __init kgdb_register_fiq(void (*mach_kgdb_enable_fiq)(bool on), + bool (*mach_is_kgdb_fiq)(void)); #endif /* !__ASSEMBLY__ */ /* diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile index 5f3338e..863d266 100644 --- a/arch/arm/kernel/Makefile +++ b/arch/arm/kernel/Makefile @@ -56,6 +56,7 @@ endif obj-$(CONFIG_OABI_COMPAT) += sys_oabi-compat.o obj-$(CONFIG_ARM_THUMBEE) += thumbee.o obj-$(CONFIG_KGDB) += kgdb.o +obj-$(CONFIG_KGDB_FIQ) += kgdb_fiq_entry.o kgdb_fiq.o obj-$(CONFIG_ARM_UNWIND) += unwind.o obj-$(CONFIG_HAVE_TCM) += tcm.o obj-$(CONFIG_OF) += devtree.o diff --git a/arch/arm/kernel/kgdb_fiq.c b/arch/arm/kernel/kgdb_fiq.c new file mode 100644 index 0000000..bede9be --- /dev/null +++ b/arch/arm/kernel/kgdb_fiq.c @@ -0,0 +1,118 @@ +/* + * KGDB FIQ + * + * Copyright 2010 Google, Inc. + * Arve Hjønnevåg + * Colin Cross + * Copyright 2012 Linaro Ltd. + * Anton Vorontsov + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static int kgdb_fiq_enabled; +module_param_named(enable, kgdb_fiq_enabled, int, 0600); +MODULE_PARM_DESC(enable, "set to 1 to enable FIQ KGDB"); + +static bool (*is_kgdb_fiq)(void); +static void (*kgdb_enable_fiq)(bool on); + +asmlinkage void __exception_irq_entry kgdb_fiq_do_handle(struct pt_regs *regs) +{ + if (!is_kgdb_fiq()) + return; + if (!kgdb_nmi_poll_knock()) + return; + + nmi_enter(); + kgdb_handle_exception(1, 0, 0, regs); + nmi_exit(); +} + +static struct fiq_handler kgdb_fiq_desc = { + .name = "kgdb", +}; + +static long kgdb_fiq_setup_stack(void *info) +{ + struct pt_regs regs; + + regs.ARM_sp = __get_free_pages(GFP_KERNEL, THREAD_SIZE_ORDER) + + THREAD_START_SP; + WARN_ON(!regs.ARM_sp); + + set_fiq_regs(®s); + return 0; +} + +/** + * kgdb_fiq_enable_nmi - Manage NMI-triggered entry to KGDB + * @on: Flag to either enable or disable an NMI + * + * This function manages NMIs that usually cause KGDB to enter. That is, not + * all NMIs should be enabled or disabled, but only those that issue + * kgdb_handle_exception(). + * + * The call counts disable requests, and thus allows to nest disables. But + * trying to enable already enabled NMI is an error. + */ +static void kgdb_fiq_enable_nmi(bool on) +{ + static atomic_t cnt; + int ret; + + ret = atomic_add_return(on ? 1 : -1, &cnt); + if (ret > 1 && on) { + /* + * There should be only one instance that calls this function + * in "enable, disable" order. All other users must call + * disable first, then enable. If not, something is wrong. + */ + WARN_ON(1); + return; + } + + kgdb_enable_fiq(ret > 0); +} + +int __init kgdb_register_fiq(void (*mach_kgdb_enable_fiq)(bool on), + bool (*mach_is_kgdb_fiq)(void)) +{ + int err; + int cpu; + + if (!kgdb_fiq_enabled) + return -ENODEV; + + kgdb_enable_fiq = mach_kgdb_enable_fiq; + is_kgdb_fiq = mach_is_kgdb_fiq; + + err = claim_fiq(&kgdb_fiq_desc); + if (err) { + pr_warn("%s: unable to claim fiq", __func__); + return err; + } + + for_each_possible_cpu(cpu) + work_on_cpu(cpu, kgdb_fiq_setup_stack, NULL); + + set_fiq_handler(&kgdb_fiq_handler, + &kgdb_fiq_handler_end - &kgdb_fiq_handler); + + arch_kgdb_ops.enable_nmi = kgdb_fiq_enable_nmi; + return 0; +} diff --git a/arch/arm/kernel/kgdb_fiq_entry.S b/arch/arm/kernel/kgdb_fiq_entry.S new file mode 100644 index 0000000..d6becca --- /dev/null +++ b/arch/arm/kernel/kgdb_fiq_entry.S @@ -0,0 +1,87 @@ +/* + * KGDB FIQ entry + * + * Copyright 1996,1997,1998 Russell King. + * Copyright 2012 Linaro Ltd. + * Anton Vorontsov + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include "entry-header.S" + + .text + +@ This is needed for usr_entry/alignment_trap +.LCcralign: + .long cr_alignment +.LCdohandle: + .long kgdb_fiq_do_handle + + .macro fiq_handler + ldr r1, =.LCdohandle + mov r0, sp + adr lr, BSYM(9997f) + ldr pc, [r1] +9997: + .endm + + .align 5 +__fiq_svc: + svc_entry + fiq_handler + mov r0, sp + ldmib r0, {r1 - r14} + msr cpsr_c, #FIQ_MODE | PSR_I_BIT | PSR_F_BIT + add r8, r0, #S_PC + ldr r9, [r0, #S_PSR] + msr spsr_cxsf, r9 + ldr r0, [r0, #S_R0] + ldmia r8, {pc}^ + + UNWIND(.fnend ) +ENDPROC(__fiq_svc) + .ltorg + + .align 5 +__fiq_usr: + usr_entry + kuser_cmpxchg_check + fiq_handler + get_thread_info tsk + mov why, #0 + b ret_to_user_from_irq + UNWIND(.fnend ) +ENDPROC(__fiq_usr) + .ltorg + + .global kgdb_fiq_handler +kgdb_fiq_handler: + + vector_stub fiq, FIQ_MODE, 4 + + .long __fiq_usr @ 0 (USR_26 / USR_32) + .long __fiq_svc @ 1 (FIQ_26 / FIQ_32) + .long __fiq_svc @ 2 (IRQ_26 / IRQ_32) + .long __fiq_svc @ 3 (SVC_26 / SVC_32) + .long __fiq_svc @ 4 + .long __fiq_svc @ 5 + .long __fiq_svc @ 6 + .long __fiq_svc @ 7 + .long __fiq_svc @ 8 + .long __fiq_svc @ 9 + .long __fiq_svc @ a + .long __fiq_svc @ b + .long __fiq_svc @ c + .long __fiq_svc @ d + .long __fiq_svc @ e + .long __fiq_svc @ f + + .global kgdb_fiq_handler_end +kgdb_fiq_handler_end: