From patchwork Fri Jul 13 10:16:44 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Anton Vorontsov X-Patchwork-Id: 9982 Return-Path: X-Original-To: patchwork@peony.canonical.com Delivered-To: patchwork@peony.canonical.com Received: from fiordland.canonical.com (fiordland.canonical.com [91.189.94.145]) by peony.canonical.com (Postfix) with ESMTP id 1C4B123E1B for ; Fri, 13 Jul 2012 10:19:19 +0000 (UTC) Received: from mail-yx0-f180.google.com (mail-yx0-f180.google.com [209.85.213.180]) by fiordland.canonical.com (Postfix) with ESMTP id CA30FA18238 for ; Fri, 13 Jul 2012 10:19:18 +0000 (UTC) Received: by yenq6 with SMTP id q6so3667522yen.11 for ; Fri, 13 Jul 2012 03:19:18 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=x-forwarded-to:x-forwarded-for:delivered-to:received-spf:from:to:cc :subject:date:message-id:x-mailer:in-reply-to:references :mime-version:content-type:content-transfer-encoding :x-gm-message-state; bh=sE4os/s8Lw50zDwSMY6exodPloaSxWc1HQxezD+qvvE=; b=ku4sjMHnVLOdrI5t6y+LZwkTEk6OqAtQlC5ZvqYZmf7xyUbgMWRJ4ZD0lWyFDQ6Tsg DQykb9KJ8YSu9nZKQrpNfKapnVNTzkqQxIMcpV/MYWin5ls6Iwi2A2qgHKWaKAAQZJOv EDRAdOVSK3B0noJ3gZDlhhhpt1ENFKZ8ByogaJCWEdnuY0SZCB1DzPOVr5l6i053WJrx 3jo4o9GQayzyCBl7hPjeKiZ9xuN4Qcs5foXikL/xDnUAMjdY0N5ojRNlq7yMfsCIJ8oe tMfShCX5IhP1uIwMnYNQwFsmgp3QkagitWmdaSRoXY/uka9MAIFgZLMlS8jxcKTeDRQv 5OrQ== Received: by 10.50.87.227 with SMTP id bb3mr374413igb.57.1342174757906; Fri, 13 Jul 2012 03:19:17 -0700 (PDT) X-Forwarded-To: linaro-patchwork@canonical.com X-Forwarded-For: patch@linaro.org linaro-patchwork@canonical.com Delivered-To: patches@linaro.org Received: by 10.231.241.2 with SMTP id lc2csp13696ibb; Fri, 13 Jul 2012 03:19:17 -0700 (PDT) Received: by 10.236.91.48 with SMTP id g36mr494465yhf.53.1342174757037; Fri, 13 Jul 2012 03:19:17 -0700 (PDT) Received: from mail-yw0-f50.google.com (mail-yw0-f50.google.com [209.85.213.50]) by mx.google.com with ESMTPS id k67si6727203yhj.110.2012.07.13.03.19.16 (version=TLSv1/SSLv3 cipher=OTHER); Fri, 13 Jul 2012 03:19:17 -0700 (PDT) Received-SPF: neutral (google.com: 209.85.213.50 is neither permitted nor denied by best guess record for domain of anton.vorontsov@linaro.org) client-ip=209.85.213.50; Authentication-Results: mx.google.com; spf=neutral (google.com: 209.85.213.50 is neither permitted nor denied by best guess record for domain of anton.vorontsov@linaro.org) smtp.mail=anton.vorontsov@linaro.org Received: by mail-yw0-f50.google.com with SMTP id j63so3726888yhj.37 for ; Fri, 13 Jul 2012 03:19:16 -0700 (PDT) Received: by 10.66.9.2 with SMTP id v2mr1003345paa.65.1342174756349; Fri, 13 Jul 2012 03:19:16 -0700 (PDT) Received: from localhost (c-71-204-165-222.hsd1.ca.comcast.net. [71.204.165.222]) by mx.google.com with ESMTPS id gl1sm5747579pbc.71.2012.07.13.03.19.14 (version=TLSv1/SSLv3 cipher=OTHER); Fri, 13 Jul 2012 03:19:15 -0700 (PDT) From: Anton Vorontsov To: Russell King , Jason Wessel Cc: =?UTF-8?q?Arve=20Hj=C3=B8nnev=C3=A5g?= , Colin Cross , John Stultz , linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linaro-kernel@lists.linaro.org, patches@linaro.org, kernel-team@android.com, kgdb-bugreport@lists.sourceforge.net Subject: =?UTF-8?q?=5BPATCH=204/8=5D=20ARM=3A=20Add=20KGDB/KDB=20FIQ=20debugger=20generic=20code?= Date: Fri, 13 Jul 2012 03:16:44 -0700 Message-Id: <1342174608-22407-4-git-send-email-anton.vorontsov@linaro.org> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <20120713101605.GA16139@lizard> References: <20120713101605.GA16139@lizard> MIME-Version: 1.0 X-Gm-Message-State: ALoCoQnmQeelfkzm9v8OGrWIUmiFeBxrS5nQ/b1eBTeiAFJsLPNIg+b7of7TivSX+GCR141KqOkj 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. Signed-off-by: Anton Vorontsov --- arch/arm/Kconfig | 18 ++++++++ arch/arm/include/asm/kgdb.h | 8 ++++ arch/arm/kernel/Makefile | 1 + arch/arm/kernel/kgdb_fiq.c | 93 ++++++++++++++++++++++++++++++++++++++ arch/arm/kernel/kgdb_fiq_entry.S | 79 ++++++++++++++++++++++++++++++++ 5 files changed, 199 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 a91009c..ae6ddf1 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -172,6 +172,24 @@ config GENERIC_ISA_DMA config FIQ bool +config ARCH_MIGHT_HAVE_FIQ + bool + +config KGDB_FIQ + bool "KGDB/KDB FIQ debugger" + depends on KGDB_KDB && ARCH_MIGHT_HAVE_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..807e547 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,12 @@ 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(unsigned int mach_kgdb_fiq, + void (*mach_kgdb_enable_fiq)(unsigned int irq, bool on), + bool (*mach_is_kgdb_fiq)(unsigned int irq)); #endif /* !__ASSEMBLY__ */ /* diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile index 7ad2d5c..5aa079b 100644 --- a/arch/arm/kernel/Makefile +++ b/arch/arm/kernel/Makefile @@ -56,6 +56,7 @@ obj-$(CONFIG_ATAGS_PROC) += atags.o 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..7ec9979 --- /dev/null +++ b/arch/arm/kernel/kgdb_fiq.c @@ -0,0 +1,93 @@ +/* + * KGDB FIQ entry + * + * 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 + +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 unsigned int kgdb_fiq; +static void (*kgdb_enable_fiq)(unsigned int irq, bool on); +static bool (*is_kgdb_fiq)(unsigned int irq); + +asmlinkage void __exception_irq_entry kgdb_fiq_do_handle(struct pt_regs *regs) +{ + if (!is_kgdb_fiq(kgdb_fiq)) + 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; +} + +void kgdb_arch_enable_nmi(bool on) +{ + kgdb_enable_fiq(kgdb_fiq, on); +} + +int __init kgdb_register_fiq(unsigned int mach_kgdb_fiq, + void (*mach_kgdb_enable_fiq)(unsigned int irq, bool on), + bool (*mach_is_kgdb_fiq)(unsigned int irq)) +{ + int err; + int cpu; + + if (!kgdb_fiq_enabled) + return -ENODEV; + if (kgdb_fiq) + return -EBUSY; + + kgdb_fiq = mach_kgdb_fiq; + 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); + + kgdb_arch_enable_nmi(1); + 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..7be3726 --- /dev/null +++ b/arch/arm/kernel/kgdb_fiq_entry.S @@ -0,0 +1,79 @@ +/* + * 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 + svc_exit r5 @ return from exception + 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: