kgdb: Add the ability to schedule a breakpoint via a tasklet
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 <jason.wessel@windriver.com>
This commit is contained in:
parent
5dd11d5d47
commit
1cee5e35f1
2 changed files with 27 additions and 0 deletions
|
@ -271,6 +271,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,
|
||||
|
|
|
@ -114,6 +114,7 @@ EXPORT_SYMBOL_GPL(kgdb_active);
|
|||
*/
|
||||
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;
|
||||
|
@ -789,6 +790,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;
|
||||
|
|
Loading…
Reference in a new issue