Some kgdb I/O modules require the ability to create a breakpoint tasklet, such as kgdboc and external modules such as kgdboe. The breakpoint tasklet is used as an asynchronous entry point into the debugger which will have a different function scope than the current execution path where it might not be safe to have an inline breakpoint. This is true of some of the kgdb I/O drivers which share code with kgdb and rest of the kernel users.
Signed-off-by: Jason Wessel <[email protected]> --- include/linux/kgdb.h | 1 + kernel/debug/debug_core.c | 26 ++++++++++++++++++++++++++ 2 files changed, 27 insertions(+), 0 deletions(-) diff --git a/include/linux/kgdb.h b/include/linux/kgdb.h index e4e9206..076f3c6 100644 --- a/include/linux/kgdb.h +++ b/include/linux/kgdb.h @@ -270,6 +270,7 @@ extern int kgdb_mem2hex(char *mem, char *buf, int count); extern int kgdb_hex2mem(char *buf, char *mem, int count); extern int kgdb_isremovedbreak(unsigned long addr); +extern void kgdb_schedule_breakpoint(void); extern int kgdb_handle_exception(int ex_vector, int signo, int err_code, diff --git a/kernel/debug/debug_core.c b/kernel/debug/debug_core.c index 5ceaa0f..e02c552 100644 --- a/kernel/debug/debug_core.c +++ b/kernel/debug/debug_core.c @@ -112,6 +112,7 @@ atomic_t kgdb_active = ATOMIC_INIT(-1); */ static atomic_t passive_cpu_wait[NR_CPUS]; static atomic_t cpu_in_kgdb[NR_CPUS]; +static atomic_t kgdb_break_tasklet_var; atomic_t kgdb_setting_breakpoint; struct task_struct *kgdb_usethread; @@ -776,6 +777,31 @@ static void kgdb_unregister_callbacks(void) } } +/* + * There are times a tasklet needs to be used vs a compiled in + * break point so as to cause an exception outside a kgdb I/O module, + * such as is the case with kgdboe, where calling a breakpoint in the + * I/O driver itself would be fatal. + */ +static void kgdb_tasklet_bpt(unsigned long ing) +{ + kgdb_breakpoint(); + atomic_set(&kgdb_break_tasklet_var, 0); +} + +static DECLARE_TASKLET(kgdb_tasklet_breakpoint, kgdb_tasklet_bpt, 0); + +void kgdb_schedule_breakpoint(void) +{ + if (atomic_read(&kgdb_break_tasklet_var) || + atomic_read(&kgdb_active) != -1 || + atomic_read(&kgdb_setting_breakpoint)) + return; + atomic_inc(&kgdb_break_tasklet_var); + tasklet_schedule(&kgdb_tasklet_breakpoint); +} +EXPORT_SYMBOL_GPL(kgdb_schedule_breakpoint); + static void kgdb_initial_breakpoint(void) { kgdb_break_asap = 0; -- 1.6.3.1.9.g95405b ------------------------------------------------------------------------------ Throughout its 18-year history, RSA Conference consistently attracts the world's best and brightest in the field, creating opportunities for Conference attendees to learn about information security's most important issues through interactions with peers, luminaries and emerging and established companies. http://p.sf.net/sfu/rsaconf-dev2dev _______________________________________________ Kgdb-bugreport mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/kgdb-bugreport
