KGDB allows to direct the console output also to the gdb frontend. But if you switch on CONFIG_KGDB_CONSOLE blindly, you end up without a suitable initial console for init, causing a boot panic (like I faced: http://lkml.org/lkml/2008/1/14/284). One workaround is to explicitly provide the first console in the kernel command line. This patch implements a less error-prone approach by registering the console in kgdb_internal_init(). Before that point, it is unusable anyway due to the debugger not being attached. The external references to the kgdbcons were removed, because it should not be used outside the kgdb core. Signed-off-by: Jan Kiszka Signed-off-by: Jason Wessel --- include/linux/kgdb.h | 4 --- kernel/kgdb.c | 56 ++++++++++++++++++++++++--------------------------- 2 files changed, 27 insertions(+), 33 deletions(-) --- a/kernel/kgdb.c +++ b/kernel/kgdb.c @@ -1628,6 +1628,29 @@ static struct notifier_block kgdb_panic_ .notifier_call = kgdb_panic_notify, }; +#ifdef CONFIG_KGDB_CONSOLE +void kgdb_console_write(struct console *co, const char *s, unsigned count) +{ + unsigned long flags; + + /* If we're debugging, or KGDB has not connected, don't try + * and print. */ + if (!kgdb_connected || atomic_read(&debugger_active) != 0) + return; + + local_irq_save(flags); + kgdb_msg_write(s, count); + local_irq_restore(flags); +} + +static struct console kgdbcons = { + .name = "kgdb", + .write = kgdb_console_write, + .flags = CON_PRINTBUFFER | CON_ENABLED, + .index = -1, +}; +#endif + /* * Initialization that needs to be done in either of our entry points. */ @@ -1648,6 +1671,10 @@ static void __init kgdb_internal_init(vo /* We can't do much if this fails */ register_module_notifier(&kgdb_module_load_nb); +#ifdef CONFIG_KGDB_CONSOLE + register_console(&kgdbcons); +#endif + kgdb_initialized = 1; } @@ -1957,35 +1984,6 @@ static int kgdb_notify_reboot(struct not return NOTIFY_DONE; } -#ifdef CONFIG_KGDB_CONSOLE -void kgdb_console_write(struct console *co, const char *s, unsigned count) -{ - unsigned long flags; - - /* If we're debugging, or KGDB has not connected, don't try - * and print. */ - if (!kgdb_connected || atomic_read(&debugger_active) != 0) - return; - - local_irq_save(flags); - kgdb_msg_write(s, count); - local_irq_restore(flags); -} - -struct console kgdbcons = { - .name = "kgdb", - .write = kgdb_console_write, - .flags = CON_PRINTBUFFER | CON_ENABLED, -}; -static int __init kgdb_console_init(void) -{ - register_console(&kgdbcons); - return 0; -} - -console_initcall(kgdb_console_init); -#endif - static int __init opt_kgdb_attachwait(char *str) { attachwait = 1; --- a/include/linux/kgdb.h +++ b/include/linux/kgdb.h @@ -33,10 +33,6 @@ struct pt_regs; struct task_struct; struct uart_port; -#ifdef CONFIG_KGDB_CONSOLE -extern struct console kgdbcons; -#endif - /* To enter the debugger explicitly. */ extern void breakpoint(void); extern int kgdb_connected;