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 f46d466..b5de457 100644
--- a/include/linux/kgdb.h
+++ b/include/linux/kgdb.h
@@ -303,6 +303,7 @@ extern int kgdb_nmicallback(int cpu, void *regs);
 
 extern int                     kgdb_single_step;
 extern atomic_t                        kgdb_active;
+extern void kgdb_schedule_breakpoint(void);
 
 #ifdef CONFIG_KGDB_SERIAL_CONSOLE
 extern void __init early_kgdboc_init(void);
diff --git a/kernel/debug/debug_core.c b/kernel/debug/debug_core.c
index 06e73e0..e44e693 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;
@@ -777,6 +778,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.4.rc1


------------------------------------------------------------------------------
This SF.Net email is sponsored by the Verizon Developer Community
Take advantage of Verizon's best-in-class app development support
A streamlined, 14 day to market process makes app distribution fast and easy
Join now and get one step closer to millions of Verizon customers
http://p.sf.net/sfu/verizon-dev2dev 
_______________________________________________
Kgdb-bugreport mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/kgdb-bugreport

Reply via email to