* [GIT PULL] kgdb/kdb tree for 2.6.37
@ 2010-10-29 18:43 Jason Wessel
2010-10-29 18:43 ` [PATCH 1/7] kdb: Add kdb kernel module sample Jason Wessel
` (6 more replies)
0 siblings, 7 replies; 8+ messages in thread
From: Jason Wessel @ 2010-10-29 18:43 UTC (permalink / raw)
To: torvalds; +Cc: linux-kernel, kgdb-bugreport
Linus, please pull the for_linus branch to pick up the final updates
for the 2.6.37 merge window for kgdb/kdb.
git://git.kernel.org/pub/scm/linux/kernel/git/jwessel/linux-2.6-kgdb.git for_linus
This second pull request for the merge window contains mainly
regression fixes and cleanups. The 2 non fix/cleanup things in this
patch series are:
* Added a kdb_hello module for the samples/ dir which shows how
to dynamically add kdb shell commands
* Converted the arch specific powerpc kgdb stub to the individual
register access, joining x86, arm, and mips
Thanks,
Jason.
---
The following changes since commit 12ba8d1e9262ce81a695795410bd9ee5c9407ba1:
Al Viro (1):
fix braino in fs: do not assign default i_ino in new_inode
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/jwessel/linux-2.6-kgdb.git for_linus
Dongdong Deng (3):
debug_core,x86,blackfin: Clean up hw debug disable API
kgdbts: prevent re-entry to kgdbts before it unregisters
kgdb,ppc: Individual register get/set for ppc
Jason Wessel (3):
kdb: Add kdb kernel module sample
kdb: fix per_cpu command to remove supress mask
kdb: Fix early debugging crash regression
Rabin Vincent (1):
kgdb,arm: fix register dump
Documentation/DocBook/kgdb.tmpl | 13 +++-
arch/arm/include/asm/kgdb.h | 5 +-
arch/arm/kernel/kgdb.c | 2 +-
arch/blackfin/kernel/kgdb.c | 3 +-
arch/powerpc/include/asm/kgdb.h | 1 +
arch/powerpc/kernel/kgdb.c | 188 ++++++++++++++++++++++++++-------------
arch/x86/kernel/kgdb.c | 3 +-
drivers/misc/kgdbts.c | 16 +---
include/linux/kgdb.h | 13 +--
kernel/debug/debug_core.c | 16 +---
kernel/debug/kdb/kdb_main.c | 48 +++--------
samples/Kconfig | 7 ++
samples/Makefile | 2 +-
samples/kdb/Makefile | 1 +
samples/kdb/kdb_hello.c | 60 ++++++++++++
15 files changed, 235 insertions(+), 143 deletions(-)
create mode 100644 samples/kdb/Makefile
create mode 100644 samples/kdb/kdb_hello.c
^ permalink raw reply [flat|nested] 8+ messages in thread* [PATCH 1/7] kdb: Add kdb kernel module sample 2010-10-29 18:43 [GIT PULL] kgdb/kdb tree for 2.6.37 Jason Wessel @ 2010-10-29 18:43 ` Jason Wessel 2010-10-29 18:43 ` [PATCH 2/7] kdb: fix per_cpu command to remove supress mask Jason Wessel ` (5 subsequent siblings) 6 siblings, 0 replies; 8+ messages in thread From: Jason Wessel @ 2010-10-29 18:43 UTC (permalink / raw) To: torvalds; +Cc: linux-kernel, kgdb-bugreport, Jason Wessel Add an example of how to add a dynamic kdb shell command via a kernel module. Signed-off-by: Jason Wessel <jason.wessel@windriver.com> --- Documentation/DocBook/kgdb.tmpl | 13 ++++++++- samples/Kconfig | 7 ++++ samples/Makefile | 2 +- samples/kdb/Makefile | 1 + samples/kdb/kdb_hello.c | 60 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 81 insertions(+), 2 deletions(-) create mode 100644 samples/kdb/Makefile create mode 100644 samples/kdb/kdb_hello.c diff --git a/Documentation/DocBook/kgdb.tmpl b/Documentation/DocBook/kgdb.tmpl index 490d862..d71b57f 100644 --- a/Documentation/DocBook/kgdb.tmpl +++ b/Documentation/DocBook/kgdb.tmpl @@ -710,7 +710,18 @@ Task Addr Pid Parent [*] cpu State Thread Command <listitem><para>A simple shell</para></listitem> <listitem><para>The kdb core command set</para></listitem> <listitem><para>A registration API to register additional kdb shell commands.</para> - <para>A good example of a self-contained kdb module is the "ftdump" command for dumping the ftrace buffer. See: kernel/trace/trace_kdb.c</para></listitem> + <itemizedlist> + <listitem><para>A good example of a self-contained kdb module + is the "ftdump" command for dumping the ftrace buffer. See: + kernel/trace/trace_kdb.c</para></listitem> + <listitem><para>For an example of how to dynamically register + a new kdb command you can build the kdb_hello.ko kernel module + from samples/kdb/kdb_hello.c. To build this example you can + set CONFIG_SAMPLES=y and CONFIG_SAMPLE_KDB=m in your kernel + config. Later run "modprobe kdb_hello" and the next time you + enter the kdb shell, you can run the "hello" + command.</para></listitem> + </itemizedlist></listitem> <listitem><para>The implementation for kdb_printf() which emits messages directly to I/O drivers, bypassing the kernel log.</para></listitem> diff --git a/samples/Kconfig b/samples/Kconfig index 954a1d5..e03cf0e 100644 --- a/samples/Kconfig +++ b/samples/Kconfig @@ -54,4 +54,11 @@ config SAMPLE_KFIFO If in doubt, say "N" here. +config SAMPLE_KDB + tristate "Build kdb command exmaple -- loadable modules only" + depends on KGDB_KDB && m + help + Build an example of how to dynamically add the hello + command to the kdb shell. + endif # SAMPLES diff --git a/samples/Makefile b/samples/Makefile index 76b3c34..f26c095 100644 --- a/samples/Makefile +++ b/samples/Makefile @@ -1,4 +1,4 @@ # Makefile for Linux samples code obj-$(CONFIG_SAMPLES) += kobject/ kprobes/ tracepoints/ trace_events/ \ - hw_breakpoint/ kfifo/ + hw_breakpoint/ kfifo/ kdb/ diff --git a/samples/kdb/Makefile b/samples/kdb/Makefile new file mode 100644 index 0000000..fbedf39 --- /dev/null +++ b/samples/kdb/Makefile @@ -0,0 +1 @@ +obj-$(CONFIG_SAMPLE_KDB) += kdb_hello.o diff --git a/samples/kdb/kdb_hello.c b/samples/kdb/kdb_hello.c new file mode 100644 index 0000000..c1c2fa0 --- /dev/null +++ b/samples/kdb/kdb_hello.c @@ -0,0 +1,60 @@ +/* + * Created by: Jason Wessel <jason.wessel@windriver.com> + * + * Copyright (c) 2010 Wind River Systems, Inc. All Rights Reserved. + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#include <linux/module.h> +#include <linux/kdb.h> + +/* + * All kdb shell command call backs receive argc and argv, where + * argv[0] is the command the end user typed + */ +static int kdb_hello_cmd(int argc, const char **argv) +{ + if (argc > 1) + return KDB_ARGCOUNT; + + if (argc) + kdb_printf("Hello %s.\n", argv[1]); + else + kdb_printf("Hello world!\n"); + + return 0; +} + + +static int __init kdb_hello_cmd_init(void) +{ + /* + * Registration of a dynamically added kdb command is done with + * kdb_register() with the arguments being: + * 1: The name of the shell command + * 2: The function that processes the command + * 3: Description of the usage of any arguments + * 4: Descriptive text when you run help + * 5: Number of characters to complete the command + * 0 == type the whole command + * 1 == match both "g" and "go" for example + */ + kdb_register("hello", kdb_hello_cmd, "[string]", + "Say Hello World or Hello [string]", 0); + return 0; +} + +static void __exit kdb_hello_cmd_exit(void) +{ + kdb_unregister("hello"); +} + +module_init(kdb_hello_cmd_init); +module_exit(kdb_hello_cmd_exit); + +MODULE_AUTHOR("WindRiver"); +MODULE_DESCRIPTION("KDB example to add a hello command"); +MODULE_LICENSE("GPL"); -- 1.6.3.3 ^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 2/7] kdb: fix per_cpu command to remove supress mask 2010-10-29 18:43 [GIT PULL] kgdb/kdb tree for 2.6.37 Jason Wessel 2010-10-29 18:43 ` [PATCH 1/7] kdb: Add kdb kernel module sample Jason Wessel @ 2010-10-29 18:43 ` Jason Wessel 2010-10-29 18:43 ` [PATCH 3/7] kgdb,arm: fix register dump Jason Wessel ` (4 subsequent siblings) 6 siblings, 0 replies; 8+ messages in thread From: Jason Wessel @ 2010-10-29 18:43 UTC (permalink / raw) To: torvalds; +Cc: linux-kernel, kgdb-bugreport, Jason Wessel Rusty pointed out that the per_cpu command uses up lots of space on the stack and the cpu supress mask is probably not needed. This patch removes the need for the supress mask as well as fixing up the following problems with the kdb per_cpu command: * The per_cpu command should allow an address as an argument * When you have more data than can be displayed on one screen allow the user to break out of the print loop. Reported-by: Rusty Russell <rusty@rustcorp.com.au> Signed-off-by: Jason Wessel <jason.wessel@windriver.com> --- kernel/debug/kdb/kdb_main.c | 46 ++++++++++-------------------------------- 1 files changed, 11 insertions(+), 35 deletions(-) diff --git a/kernel/debug/kdb/kdb_main.c b/kernel/debug/kdb/kdb_main.c index d7bda21..9755ac0 100644 --- a/kernel/debug/kdb/kdb_main.c +++ b/kernel/debug/kdb/kdb_main.c @@ -2603,20 +2603,17 @@ static int kdb_summary(int argc, const char **argv) */ static int kdb_per_cpu(int argc, const char **argv) { - char buf[256], fmtstr[64]; - kdb_symtab_t symtab; - cpumask_t suppress = CPU_MASK_NONE; - int cpu, diag; - unsigned long addr, val, bytesperword = 0, whichcpu = ~0UL; + char fmtstr[64]; + int cpu, diag, nextarg = 1; + unsigned long addr, symaddr, val, bytesperword = 0, whichcpu = ~0UL; if (argc < 1 || argc > 3) return KDB_ARGCOUNT; - snprintf(buf, sizeof(buf), "per_cpu__%s", argv[1]); - if (!kdbgetsymval(buf, &symtab)) { - kdb_printf("%s is not a per_cpu variable\n", argv[1]); - return KDB_BADADDR; - } + diag = kdbgetaddrarg(argc, argv, &nextarg, &symaddr, NULL, NULL); + if (diag) + return diag; + if (argc >= 2) { diag = kdbgetularg(argv[2], &bytesperword); if (diag) @@ -2649,46 +2646,25 @@ static int kdb_per_cpu(int argc, const char **argv) #define KDB_PCU(cpu) 0 #endif #endif - for_each_online_cpu(cpu) { + if (KDB_FLAG(CMD_INTERRUPT)) + return 0; + if (whichcpu != ~0UL && whichcpu != cpu) continue; - addr = symtab.sym_start + KDB_PCU(cpu); + addr = symaddr + KDB_PCU(cpu); diag = kdb_getword(&val, addr, bytesperword); if (diag) { kdb_printf("%5d " kdb_bfd_vma_fmt0 " - unable to " "read, diag=%d\n", cpu, addr, diag); continue; } -#ifdef CONFIG_SMP - if (!val) { - cpu_set(cpu, suppress); - continue; - } -#endif /* CONFIG_SMP */ kdb_printf("%5d ", cpu); kdb_md_line(fmtstr, addr, bytesperword == KDB_WORD_SIZE, 1, bytesperword, 1, 1, 0); } - if (cpus_weight(suppress) == 0) - return 0; - kdb_printf("Zero suppressed cpu(s):"); - for (cpu = first_cpu(suppress); cpu < num_possible_cpus(); - cpu = next_cpu(cpu, suppress)) { - kdb_printf(" %d", cpu); - if (cpu == num_possible_cpus() - 1 || - next_cpu(cpu, suppress) != cpu + 1) - continue; - while (cpu < num_possible_cpus() && - next_cpu(cpu, suppress) == cpu + 1) - ++cpu; - kdb_printf("-%d", cpu); - } - kdb_printf("\n"); - #undef KDB_PCU - return 0; } -- 1.6.3.3 ^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 3/7] kgdb,arm: fix register dump 2010-10-29 18:43 [GIT PULL] kgdb/kdb tree for 2.6.37 Jason Wessel 2010-10-29 18:43 ` [PATCH 1/7] kdb: Add kdb kernel module sample Jason Wessel 2010-10-29 18:43 ` [PATCH 2/7] kdb: fix per_cpu command to remove supress mask Jason Wessel @ 2010-10-29 18:43 ` Jason Wessel 2010-10-29 18:43 ` [PATCH 4/7] kdb: Fix early debugging crash regression Jason Wessel ` (3 subsequent siblings) 6 siblings, 0 replies; 8+ messages in thread From: Jason Wessel @ 2010-10-29 18:43 UTC (permalink / raw) To: torvalds Cc: linux-kernel, kgdb-bugreport, Rabin Vincent, stable, Jason Wessel From: Rabin Vincent <rabin@rab.in> DBG_MAX_REG_NUM incorrectly had the number of indices in the GDB regs array rather than the number of registers, leading to an oops when the "rd" command is used in KDB. Cc: stable@kernel.org Signed-off-by: Rabin Vincent <rabin@rab.in> Signed-off-by: Jason Wessel <jason.wessel@windriver.com> --- arch/arm/include/asm/kgdb.h | 5 +++-- arch/arm/kernel/kgdb.c | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/arch/arm/include/asm/kgdb.h b/arch/arm/include/asm/kgdb.h index 0826599..48066ce 100644 --- a/arch/arm/include/asm/kgdb.h +++ b/arch/arm/include/asm/kgdb.h @@ -70,7 +70,8 @@ extern int kgdb_fault_expected; #define _GP_REGS 16 #define _FP_REGS 8 #define _EXTRA_REGS 2 -#define DBG_MAX_REG_NUM (_GP_REGS + (_FP_REGS * 3) + _EXTRA_REGS) +#define GDB_MAX_REGS (_GP_REGS + (_FP_REGS * 3) + _EXTRA_REGS) +#define DBG_MAX_REG_NUM (_GP_REGS + _FP_REGS + _EXTRA_REGS) #define KGDB_MAX_NO_CPUS 1 #define BUFMAX 400 @@ -93,7 +94,7 @@ extern int kgdb_fault_expected; #define _SPT 13 #define _LR 14 #define _PC 15 -#define _CPSR (DBG_MAX_REG_NUM - 1) +#define _CPSR (GDB_MAX_REGS - 1) /* * So that we can denote the end of a frame for tracing, diff --git a/arch/arm/kernel/kgdb.c b/arch/arm/kernel/kgdb.c index d6e8b4d..778c2f7 100644 --- a/arch/arm/kernel/kgdb.c +++ b/arch/arm/kernel/kgdb.c @@ -79,7 +79,7 @@ sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *task) return; /* Initialize to zero */ - for (regno = 0; regno < DBG_MAX_REG_NUM; regno++) + for (regno = 0; regno < GDB_MAX_REGS; regno++) gdb_regs[regno] = 0; /* Otherwise, we have only some registers from switch_to() */ -- 1.6.3.3 ^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 4/7] kdb: Fix early debugging crash regression 2010-10-29 18:43 [GIT PULL] kgdb/kdb tree for 2.6.37 Jason Wessel ` (2 preceding siblings ...) 2010-10-29 18:43 ` [PATCH 3/7] kgdb,arm: fix register dump Jason Wessel @ 2010-10-29 18:43 ` Jason Wessel 2010-10-29 18:43 ` [PATCH 5/7] debug_core,x86,blackfin: Clean up hw debug disable API Jason Wessel ` (2 subsequent siblings) 6 siblings, 0 replies; 8+ messages in thread From: Jason Wessel @ 2010-10-29 18:43 UTC (permalink / raw) To: torvalds; +Cc: linux-kernel, kgdb-bugreport, Jason Wessel The kdb_current legally be equal to NULL in the early boot of the x86 arch. The problem pcan be observed by booting with the kernel arguments: earlyprintk=vga ekgdboc=kbd kgdbwait The kdb shell will oops on entry and recursively fault because it cannot get past the final stage of shell initialization. Signed-off-by: Jason Wessel <jason.wessel@windriver.com> --- kernel/debug/kdb/kdb_main.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/kernel/debug/kdb/kdb_main.c b/kernel/debug/kdb/kdb_main.c index 9755ac0..37755d6 100644 --- a/kernel/debug/kdb/kdb_main.c +++ b/kernel/debug/kdb/kdb_main.c @@ -1127,7 +1127,7 @@ static int kdb_local(kdb_reason_t reason, int error, struct pt_regs *regs, /* special case below */ } else { kdb_printf("\nEntering kdb (current=0x%p, pid %d) ", - kdb_current, kdb_current->pid); + kdb_current, kdb_current ? kdb_current->pid : 0); #if defined(CONFIG_SMP) kdb_printf("on processor %d ", raw_smp_processor_id()); #endif -- 1.6.3.3 ^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 5/7] debug_core,x86,blackfin: Clean up hw debug disable API 2010-10-29 18:43 [GIT PULL] kgdb/kdb tree for 2.6.37 Jason Wessel ` (3 preceding siblings ...) 2010-10-29 18:43 ` [PATCH 4/7] kdb: Fix early debugging crash regression Jason Wessel @ 2010-10-29 18:43 ` Jason Wessel 2010-10-29 18:43 ` [PATCH 6/7] kgdbts: prevent re-entry to kgdbts before it unregisters Jason Wessel 2010-10-29 18:43 ` [PATCH 7/7] kgdb,ppc: Individual register get/set for ppc Jason Wessel 6 siblings, 0 replies; 8+ messages in thread From: Jason Wessel @ 2010-10-29 18:43 UTC (permalink / raw) To: torvalds; +Cc: linux-kernel, kgdb-bugreport, Dongdong Deng, Jason Wessel From: Dongdong Deng <dongdong.deng@windriver.com> The kgdb_disable_hw_debug() was an architecture specific function for disabling all hardware breakpoints on a per cpu basis when entering the debug core. This patch will remove the weak function kdbg_disable_hw_debug() and change it into a call back which lives with the rest of hw breakpoint call backs in struct kgdb_arch. Signed-off-by: Dongdong Deng <dongdong.deng@windriver.com> Signed-off-by: Jason Wessel <jason.wessel@windriver.com> --- arch/blackfin/kernel/kgdb.c | 3 ++- arch/x86/kernel/kgdb.c | 3 ++- include/linux/kgdb.h | 13 +++---------- kernel/debug/debug_core.c | 16 +++------------- 4 files changed, 10 insertions(+), 25 deletions(-) diff --git a/arch/blackfin/kernel/kgdb.c b/arch/blackfin/kernel/kgdb.c index 08bc44e..edae461 100644 --- a/arch/blackfin/kernel/kgdb.c +++ b/arch/blackfin/kernel/kgdb.c @@ -320,7 +320,7 @@ static void bfin_correct_hw_break(void) } } -void kgdb_disable_hw_debug(struct pt_regs *regs) +static void bfin_disable_hw_debug(struct pt_regs *regs) { /* Disable hardware debugging while we are in kgdb */ bfin_write_WPIACTL(0); @@ -406,6 +406,7 @@ struct kgdb_arch arch_kgdb_ops = { #endif .set_hw_breakpoint = bfin_set_hw_break, .remove_hw_breakpoint = bfin_remove_hw_break, + .disable_hw_break = bfin_disable_hw_debug, .remove_all_hw_break = bfin_remove_all_hw_break, .correct_hw_break = bfin_correct_hw_break, }; diff --git a/arch/x86/kernel/kgdb.c b/arch/x86/kernel/kgdb.c index d81cfeb..ec592ca 100644 --- a/arch/x86/kernel/kgdb.c +++ b/arch/x86/kernel/kgdb.c @@ -387,7 +387,7 @@ kgdb_set_hw_break(unsigned long addr, int len, enum kgdb_bptype bptype) * disable hardware debugging while it is processing gdb packets or * handling exception. */ -void kgdb_disable_hw_debug(struct pt_regs *regs) +static void kgdb_disable_hw_debug(struct pt_regs *regs) { int i; int cpu = raw_smp_processor_id(); @@ -724,6 +724,7 @@ struct kgdb_arch arch_kgdb_ops = { .flags = KGDB_HW_BREAKPOINT, .set_hw_breakpoint = kgdb_set_hw_break, .remove_hw_breakpoint = kgdb_remove_hw_break, + .disable_hw_break = kgdb_disable_hw_debug, .remove_all_hw_break = kgdb_remove_all_hw_break, .correct_hw_break = kgdb_correct_hw_break, }; diff --git a/include/linux/kgdb.h b/include/linux/kgdb.h index cc96f0f..092e425 100644 --- a/include/linux/kgdb.h +++ b/include/linux/kgdb.h @@ -35,16 +35,6 @@ struct pt_regs; */ extern int kgdb_skipexception(int exception, struct pt_regs *regs); -/** - * kgdb_disable_hw_debug - (optional) Disable hardware debugging hook - * @regs: Current &struct pt_regs. - * - * This function will be called if the particular architecture must - * disable hardware debugging while it is processing gdb packets or - * handling exception. - */ -extern void kgdb_disable_hw_debug(struct pt_regs *regs); - struct tasklet_struct; struct task_struct; struct uart_port; @@ -243,6 +233,8 @@ extern void kgdb_arch_late(void); * breakpoint. * @remove_hw_breakpoint: Allow an architecture to specify how to remove a * hardware breakpoint. + * @disable_hw_break: Allow an architecture to specify how to disable + * hardware breakpoints for a single cpu. * @remove_all_hw_break: Allow an architecture to specify how to remove all * hardware breakpoints. * @correct_hw_break: Allow an architecture to specify how to correct the @@ -256,6 +248,7 @@ struct kgdb_arch { int (*remove_breakpoint)(unsigned long, char *); int (*set_hw_breakpoint)(unsigned long, int, enum kgdb_bptype); int (*remove_hw_breakpoint)(unsigned long, int, enum kgdb_bptype); + void (*disable_hw_break)(struct pt_regs *regs); void (*remove_all_hw_break)(void); void (*correct_hw_break)(void); }; diff --git a/kernel/debug/debug_core.c b/kernel/debug/debug_core.c index fec596d..cefd4a1 100644 --- a/kernel/debug/debug_core.c +++ b/kernel/debug/debug_core.c @@ -209,18 +209,6 @@ int __weak kgdb_skipexception(int exception, struct pt_regs *regs) return 0; } -/** - * kgdb_disable_hw_debug - Disable hardware debugging while we in kgdb. - * @regs: Current &struct pt_regs. - * - * This function will be called if the particular architecture must - * disable hardware debugging while it is processing gdb packets or - * handling exception. - */ -void __weak kgdb_disable_hw_debug(struct pt_regs *regs) -{ -} - /* * Some architectures need cache flushes when we set/clear a * breakpoint: @@ -484,7 +472,9 @@ static int kgdb_cpu_enter(struct kgdb_state *ks, struct pt_regs *regs, atomic_inc(&masters_in_kgdb); else atomic_inc(&slaves_in_kgdb); - kgdb_disable_hw_debug(ks->linux_regs); + + if (arch_kgdb_ops.disable_hw_break) + arch_kgdb_ops.disable_hw_break(regs); acquirelock: /* -- 1.6.3.3 ^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 6/7] kgdbts: prevent re-entry to kgdbts before it unregisters 2010-10-29 18:43 [GIT PULL] kgdb/kdb tree for 2.6.37 Jason Wessel ` (4 preceding siblings ...) 2010-10-29 18:43 ` [PATCH 5/7] debug_core,x86,blackfin: Clean up hw debug disable API Jason Wessel @ 2010-10-29 18:43 ` Jason Wessel 2010-10-29 18:43 ` [PATCH 7/7] kgdb,ppc: Individual register get/set for ppc Jason Wessel 6 siblings, 0 replies; 8+ messages in thread From: Jason Wessel @ 2010-10-29 18:43 UTC (permalink / raw) To: torvalds; +Cc: linux-kernel, kgdb-bugreport, Dongdong Deng, Jason Wessel From: Dongdong Deng <dongdong.deng@windriver.com> The "kgdb_connected" variable of debug_core just indicates whether or not kgdbts is connected to the debug_core. It does not completely prevent a script from trying invoke kgdbts again and possibly crashing the system (see Call Trace below). The configured variable in kgtbts can be used instead of kgdb_connected instead of kgdb_connected. The cleanup_kgdbts() can also be removed because there is no possible way to build kgdbts as a kernel module that you could unload with rmmod. Call Trace: ----------------------------------------------------------------- root:/$ echo kgdbts=V1S1000 > /sys/module/kgdbts/parameters/kgdbts kgdb: Unregistered I/O driver kgdbts, debugger disabled. ------------[ cut here ]------------ WARNING: at kernel/debug/debug_core.c:1002 kgdb_unregister_io_module+0xec/0x100() Hardware name: Moon Creek platform Modules linked in: Pid: 664, comm: sh Not tainted 2.6.34.1-WR4.0.0.0_standard #58 Call Trace: [<c103b1ed>] warn_slowpath_common+0x6d/0xa0 [<c1079fdc>] ? kgdb_unregister_io_module+0xec/0x100 [<c1079fdc>] ? kgdb_unregister_io_module+0xec/0x100 [<c10544e0>] ? param_attr_store+0x0/0x20 [<c103b235>] warn_slowpath_null+0x15/0x20 [<c1079fdc>] kgdb_unregister_io_module+0xec/0x100 [<c124e4ea>] cleanup_kgdbts+0x1a/0x20 [<c124eced>] param_set_kgdbts_var+0x6d/0xb0 [<c124ec80>] ? param_set_kgdbts_var+0x0/0xb0 [<c10544f7>] param_attr_store+0x17/0x20 [<c105457c>] module_attr_store+0x2c/0x40 [<c111fe84>] sysfs_write_file+0x94/0xf0 [<c10d42f6>] vfs_write+0x96/0x130 [<c111fdf0>] ? sysfs_write_file+0x0/0xf0 [<c10d44d6>] sys_write+0x46/0xd0 [<c13bf329>] system_call_done+0x0/0x4 ---[ end trace 4eb028c6ee43154c ]--- kgdb: Unregistered I/O driver kgdbts, debugger disabled. ----------------------------------------------------------------- [jason.wessel@windriver.com: remove cleanup_kgdbts() ] Signed-off-by: Dongdong Deng <dongdong.deng@windriver.com> Signed-off-by: Jason Wessel <jason.wessel@windriver.com> --- drivers/misc/kgdbts.c | 16 ++-------------- 1 files changed, 2 insertions(+), 14 deletions(-) diff --git a/drivers/misc/kgdbts.c b/drivers/misc/kgdbts.c index 7245023..59c118c 100644 --- a/drivers/misc/kgdbts.c +++ b/drivers/misc/kgdbts.c @@ -1044,12 +1044,6 @@ static int __init init_kgdbts(void) return configure_kgdbts(); } -static void cleanup_kgdbts(void) -{ - if (configured == 1) - kgdb_unregister_io_module(&kgdbts_io_ops); -} - static int kgdbts_get_char(void) { int val = 0; @@ -1081,10 +1075,8 @@ static int param_set_kgdbts_var(const char *kmessage, struct kernel_param *kp) return 0; } - if (kgdb_connected) { - printk(KERN_ERR - "kgdbts: Cannot reconfigure while KGDB is connected.\n"); - + if (configured == 1) { + printk(KERN_ERR "kgdbts: ERROR: Already configured and running.\n"); return -EBUSY; } @@ -1093,9 +1085,6 @@ static int param_set_kgdbts_var(const char *kmessage, struct kernel_param *kp) if (config[len - 1] == '\n') config[len - 1] = '\0'; - if (configured == 1) - cleanup_kgdbts(); - /* Go and configure with the new params. */ return configure_kgdbts(); } @@ -1123,7 +1112,6 @@ static struct kgdb_io kgdbts_io_ops = { }; module_init(init_kgdbts); -module_exit(cleanup_kgdbts); module_param_call(kgdbts, param_set_kgdbts_var, param_get_string, &kps, 0644); MODULE_PARM_DESC(kgdbts, "<A|V1|V2>[F#|S#][N#]"); MODULE_DESCRIPTION("KGDB Test Suite"); -- 1.6.3.3 ^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 7/7] kgdb,ppc: Individual register get/set for ppc 2010-10-29 18:43 [GIT PULL] kgdb/kdb tree for 2.6.37 Jason Wessel ` (5 preceding siblings ...) 2010-10-29 18:43 ` [PATCH 6/7] kgdbts: prevent re-entry to kgdbts before it unregisters Jason Wessel @ 2010-10-29 18:43 ` Jason Wessel 6 siblings, 0 replies; 8+ messages in thread From: Jason Wessel @ 2010-10-29 18:43 UTC (permalink / raw) To: torvalds Cc: linux-kernel, kgdb-bugreport, Dongdong Deng, Jason Wessel, linuxppc-dev From: Dongdong Deng <dongdong.deng@windriver.com> commit 534af1082329392bc29f6badf815e69ae2ae0f4c(kgdb,kdb: individual register set and and get API) introduce dbg_get_reg/dbg_set_reg API for individual register get and set. This patch implement those APIs for ppc. Signed-off-by: Dongdong Deng <dongdong.deng@windriver.com> Signed-off-by: Jason Wessel <jason.wessel@windriver.com> CC: linuxppc-dev@lists.ozlabs.org --- arch/powerpc/include/asm/kgdb.h | 1 + arch/powerpc/kernel/kgdb.c | 188 ++++++++++++++++++++++++++------------- 2 files changed, 126 insertions(+), 63 deletions(-) diff --git a/arch/powerpc/include/asm/kgdb.h b/arch/powerpc/include/asm/kgdb.h index edd2170..9db24e7 100644 --- a/arch/powerpc/include/asm/kgdb.h +++ b/arch/powerpc/include/asm/kgdb.h @@ -31,6 +31,7 @@ static inline void arch_kgdb_breakpoint(void) asm(".long 0x7d821008"); /* twge r2, r2 */ } #define CACHE_FLUSH_IS_SAFE 1 +#define DBG_MAX_REG_NUM 70 /* The number bytes of registers we have to save depends on a few * things. For 64bit we default to not including vector registers and diff --git a/arch/powerpc/kernel/kgdb.c b/arch/powerpc/kernel/kgdb.c index 7f61a3a..7a9db64 100644 --- a/arch/powerpc/kernel/kgdb.c +++ b/arch/powerpc/kernel/kgdb.c @@ -194,40 +194,6 @@ static int kgdb_dabr_match(struct pt_regs *regs) ptr = (unsigned long *)ptr32; \ } while (0) - -void pt_regs_to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *regs) -{ - unsigned long *ptr = gdb_regs; - int reg; - - memset(gdb_regs, 0, NUMREGBYTES); - - for (reg = 0; reg < 32; reg++) - PACK64(ptr, regs->gpr[reg]); - -#ifdef CONFIG_FSL_BOOKE -#ifdef CONFIG_SPE - for (reg = 0; reg < 32; reg++) - PACK64(ptr, current->thread.evr[reg]); -#else - ptr += 32; -#endif -#else - /* fp registers not used by kernel, leave zero */ - ptr += 32 * 8 / sizeof(long); -#endif - - PACK64(ptr, regs->nip); - PACK64(ptr, regs->msr); - PACK32(ptr, regs->ccr); - PACK64(ptr, regs->link); - PACK64(ptr, regs->ctr); - PACK32(ptr, regs->xer); - - BUG_ON((unsigned long)ptr > - (unsigned long)(((void *)gdb_regs) + NUMREGBYTES)); -} - void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *p) { struct pt_regs *regs = (struct pt_regs *)(p->thread.ksp + @@ -271,44 +237,140 @@ void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *p) (unsigned long)(((void *)gdb_regs) + NUMREGBYTES)); } -#define UNPACK64(dest, ptr) do { dest = *(ptr++); } while (0) +#define GDB_SIZEOF_REG sizeof(unsigned long) +#define GDB_SIZEOF_REG_U32 sizeof(u32) -#define UNPACK32(dest, ptr) do { \ - u32 *ptr32; \ - ptr32 = (u32 *)ptr; \ - dest = *(ptr32++); \ - ptr = (unsigned long *)ptr32; \ - } while (0) +#ifdef CONFIG_FSL_BOOKE +#define GDB_SIZEOF_FLOAT_REG sizeof(unsigned long) +#else +#define GDB_SIZEOF_FLOAT_REG sizeof(u64) +#endif -void gdb_regs_to_pt_regs(unsigned long *gdb_regs, struct pt_regs *regs) +struct dbg_reg_def_t dbg_reg_def[DBG_MAX_REG_NUM] = { - unsigned long *ptr = gdb_regs; - int reg; - - for (reg = 0; reg < 32; reg++) - UNPACK64(regs->gpr[reg], ptr); + { "r0", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[0]) }, + { "r1", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[1]) }, + { "r2", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[2]) }, + { "r3", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[3]) }, + { "r4", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[4]) }, + { "r5", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[5]) }, + { "r6", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[6]) }, + { "r7", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[7]) }, + { "r8", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[8]) }, + { "r9", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[9]) }, + { "r10", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[10]) }, + { "r11", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[11]) }, + { "r12", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[12]) }, + { "r13", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[13]) }, + { "r14", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[14]) }, + { "r15", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[15]) }, + { "r16", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[16]) }, + { "r17", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[17]) }, + { "r18", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[18]) }, + { "r19", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[19]) }, + { "r20", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[20]) }, + { "r21", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[21]) }, + { "r22", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[22]) }, + { "r23", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[23]) }, + { "r24", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[24]) }, + { "r25", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[25]) }, + { "r26", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[26]) }, + { "r27", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[27]) }, + { "r28", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[28]) }, + { "r29", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[29]) }, + { "r30", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[30]) }, + { "r31", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[31]) }, + + { "f0", GDB_SIZEOF_FLOAT_REG, 0 }, + { "f1", GDB_SIZEOF_FLOAT_REG, 1 }, + { "f2", GDB_SIZEOF_FLOAT_REG, 2 }, + { "f3", GDB_SIZEOF_FLOAT_REG, 3 }, + { "f4", GDB_SIZEOF_FLOAT_REG, 4 }, + { "f5", GDB_SIZEOF_FLOAT_REG, 5 }, + { "f6", GDB_SIZEOF_FLOAT_REG, 6 }, + { "f7", GDB_SIZEOF_FLOAT_REG, 7 }, + { "f8", GDB_SIZEOF_FLOAT_REG, 8 }, + { "f9", GDB_SIZEOF_FLOAT_REG, 9 }, + { "f10", GDB_SIZEOF_FLOAT_REG, 10 }, + { "f11", GDB_SIZEOF_FLOAT_REG, 11 }, + { "f12", GDB_SIZEOF_FLOAT_REG, 12 }, + { "f13", GDB_SIZEOF_FLOAT_REG, 13 }, + { "f14", GDB_SIZEOF_FLOAT_REG, 14 }, + { "f15", GDB_SIZEOF_FLOAT_REG, 15 }, + { "f16", GDB_SIZEOF_FLOAT_REG, 16 }, + { "f17", GDB_SIZEOF_FLOAT_REG, 17 }, + { "f18", GDB_SIZEOF_FLOAT_REG, 18 }, + { "f19", GDB_SIZEOF_FLOAT_REG, 19 }, + { "f20", GDB_SIZEOF_FLOAT_REG, 20 }, + { "f21", GDB_SIZEOF_FLOAT_REG, 21 }, + { "f22", GDB_SIZEOF_FLOAT_REG, 22 }, + { "f23", GDB_SIZEOF_FLOAT_REG, 23 }, + { "f24", GDB_SIZEOF_FLOAT_REG, 24 }, + { "f25", GDB_SIZEOF_FLOAT_REG, 25 }, + { "f26", GDB_SIZEOF_FLOAT_REG, 26 }, + { "f27", GDB_SIZEOF_FLOAT_REG, 27 }, + { "f28", GDB_SIZEOF_FLOAT_REG, 28 }, + { "f29", GDB_SIZEOF_FLOAT_REG, 29 }, + { "f30", GDB_SIZEOF_FLOAT_REG, 30 }, + { "f31", GDB_SIZEOF_FLOAT_REG, 31 }, + + { "pc", GDB_SIZEOF_REG, offsetof(struct pt_regs, nip) }, + { "msr", GDB_SIZEOF_REG, offsetof(struct pt_regs, msr) }, + { "cr", GDB_SIZEOF_REG_U32, offsetof(struct pt_regs, ccr) }, + { "lr", GDB_SIZEOF_REG, offsetof(struct pt_regs, link) }, + { "ctr", GDB_SIZEOF_REG_U32, offsetof(struct pt_regs, ctr) }, + { "xer", GDB_SIZEOF_REG, offsetof(struct pt_regs, xer) }, +}; -#ifdef CONFIG_FSL_BOOKE -#ifdef CONFIG_SPE - for (reg = 0; reg < 32; reg++) - UNPACK64(current->thread.evr[reg], ptr); +char *dbg_get_reg(int regno, void *mem, struct pt_regs *regs) +{ + if (regno >= DBG_MAX_REG_NUM || regno < 0) + return NULL; + + if (regno < 32 || regno >= 64) + /* First 0 -> 31 gpr registers*/ + /* pc, msr, ls... registers 64 -> 69 */ + memcpy(mem, (void *)regs + dbg_reg_def[regno].offset, + dbg_reg_def[regno].size); + + if (regno >= 32 && regno < 64) { + /* FP registers 32 -> 63 */ +#if defined(CONFIG_FSL_BOOKE) && defined(CONFIG_SPE) + if (current) + memcpy(mem, current->thread.evr[regno-32], + dbg_reg_def[regno].size); #else - ptr += 32; + /* fp registers not used by kernel, leave zero */ + memset(mem, 0, dbg_reg_def[regno].size); #endif + } + + return dbg_reg_def[regno].name; +} + +int dbg_set_reg(int regno, void *mem, struct pt_regs *regs) +{ + if (regno >= DBG_MAX_REG_NUM || regno < 0) + return -EINVAL; + + if (regno < 32 || regno >= 64) + /* First 0 -> 31 gpr registers*/ + /* pc, msr, ls... registers 64 -> 69 */ + memcpy((void *)regs + dbg_reg_def[regno].offset, mem, + dbg_reg_def[regno].size); + + if (regno >= 32 && regno < 64) { + /* FP registers 32 -> 63 */ +#if defined(CONFIG_FSL_BOOKE) && defined(CONFIG_SPE) + memcpy(current->thread.evr[regno-32], mem, + dbg_reg_def[regno].size); #else - /* fp registers not used by kernel, leave zero */ - ptr += 32 * 8 / sizeof(int); + /* fp registers not used by kernel, leave zero */ + return 0; #endif + } - UNPACK64(regs->nip, ptr); - UNPACK64(regs->msr, ptr); - UNPACK32(regs->ccr, ptr); - UNPACK64(regs->link, ptr); - UNPACK64(regs->ctr, ptr); - UNPACK32(regs->xer, ptr); - - BUG_ON((unsigned long)ptr > - (unsigned long)(((void *)gdb_regs) + NUMREGBYTES)); + return 0; } void kgdb_arch_set_pc(struct pt_regs *regs, unsigned long pc) -- 1.6.3.3 ^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2010-10-29 18:45 UTC | newest] Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2010-10-29 18:43 [GIT PULL] kgdb/kdb tree for 2.6.37 Jason Wessel 2010-10-29 18:43 ` [PATCH 1/7] kdb: Add kdb kernel module sample Jason Wessel 2010-10-29 18:43 ` [PATCH 2/7] kdb: fix per_cpu command to remove supress mask Jason Wessel 2010-10-29 18:43 ` [PATCH 3/7] kgdb,arm: fix register dump Jason Wessel 2010-10-29 18:43 ` [PATCH 4/7] kdb: Fix early debugging crash regression Jason Wessel 2010-10-29 18:43 ` [PATCH 5/7] debug_core,x86,blackfin: Clean up hw debug disable API Jason Wessel 2010-10-29 18:43 ` [PATCH 6/7] kgdbts: prevent re-entry to kgdbts before it unregisters Jason Wessel 2010-10-29 18:43 ` [PATCH 7/7] kgdb,ppc: Individual register get/set for ppc Jason Wessel
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®