Commit bec4d62e authored by Jason Wessel's avatar Jason Wessel

kgdb,debug_core: add the ability to control the reboot notifier

Sometimes it is desirable to stop the kernel debugger before allowing
a system to reboot either with kdb or kgdb.  This patch adds the
ability to turn the reboot notifier on and off or enter the debugger
and stop kernel execution before rebooting.

It is possible to change the setting after booting the kernel with the
following:

echo 1 > /sys/module/debug_core/parameters/kgdbreboot

It is also possible to change this setting using kdb / kgdb to
manipulate the variable directly.

Using KDB:
   mm kgdbreboot 1

Using gdb:
   set kgdbreboot=1
Reported-by: default avatarJan Kiszka <jan.kiszka@siemens.com>
Signed-off-by: default avatarJason Wessel <jason.wessel@windriver.com>
parent 8f30d411
...@@ -361,6 +361,23 @@ ...@@ -361,6 +361,23 @@
<para>It is possible to use this option with kgdboc on a tty that is not a system console. <para>It is possible to use this option with kgdboc on a tty that is not a system console.
</para> </para>
</para> </para>
</sect1>
<sect1 id="kgdbreboot">
<title>Run time parameter: kgdbreboot</title>
<para> The kgdbreboot feature allows you to change how the debugger
deals with the reboot notification. You have 3 choices for the
behavior. The default behavior is always set to 0.</para>
<orderedlist>
<listitem><para>echo -1 > /sys/module/debug_core/parameters/kgdbreboot</para>
<para>Ignore the reboot notification entirely.</para>
</listitem>
<listitem><para>echo 0 > /sys/module/debug_core/parameters/kgdbreboot</para>
<para>Send the detach message to any attached debugger client.</para>
</listitem>
<listitem><para>echo 1 > /sys/module/debug_core/parameters/kgdbreboot</para>
<para>Enter the debugger on reboot notify.</para>
</listitem>
</orderedlist>
</sect1> </sect1>
</chapter> </chapter>
<chapter id="usingKDB"> <chapter id="usingKDB">
......
...@@ -76,6 +76,8 @@ static int exception_level; ...@@ -76,6 +76,8 @@ static int exception_level;
struct kgdb_io *dbg_io_ops; struct kgdb_io *dbg_io_ops;
static DEFINE_SPINLOCK(kgdb_registration_lock); static DEFINE_SPINLOCK(kgdb_registration_lock);
/* Action for the reboot notifiter, a global allow kdb to change it */
static int kgdbreboot;
/* kgdb console driver is loaded */ /* kgdb console driver is loaded */
static int kgdb_con_registered; static int kgdb_con_registered;
/* determine if kgdb console output should be used */ /* determine if kgdb console output should be used */
...@@ -97,6 +99,7 @@ static int __init opt_kgdb_con(char *str) ...@@ -97,6 +99,7 @@ static int __init opt_kgdb_con(char *str)
early_param("kgdbcon", opt_kgdb_con); early_param("kgdbcon", opt_kgdb_con);
module_param(kgdb_use_con, int, 0644); module_param(kgdb_use_con, int, 0644);
module_param(kgdbreboot, int, 0644);
/* /*
* Holds information about breakpoints in a kernel. These breakpoints are * Holds information about breakpoints in a kernel. These breakpoints are
...@@ -788,8 +791,21 @@ void __init dbg_late_init(void) ...@@ -788,8 +791,21 @@ void __init dbg_late_init(void)
static int static int
dbg_notify_reboot(struct notifier_block *this, unsigned long code, void *x) dbg_notify_reboot(struct notifier_block *this, unsigned long code, void *x)
{ {
/*
* Take the following action on reboot notify depending on value:
* 1 == Enter debugger
* 0 == [the default] detatch debug client
* -1 == Do nothing... and use this until the board resets
*/
switch (kgdbreboot) {
case 1:
kgdb_breakpoint();
case -1:
goto done;
}
if (!dbg_kdb_mode) if (!dbg_kdb_mode)
gdbstub_exit(code); gdbstub_exit(code);
done:
return NOTIFY_DONE; return NOTIFY_DONE;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment