From: Jan Kiszka <jan.kiszka@web.de>
To: Jason Wessel <jason.wessel@windriver.com>
Cc: Ingo Molnar <mingo@elte.hu>,
Linux Kernel Mailing List <linux-kernel@vger.kernel.org>,
kgdb-bugreport@lists.sourceforge.net
Subject: [PATCH 1/5] KGDB: improve early init
Date: Wed, 30 Jan 2008 00:43:55 +0100 [thread overview]
Message-ID: <479FBA3B.5050209@web.de> (raw)
[Warning in advance]
This patch reintroduces the early KGDB_CONSOLE registration issue: If
you switch this on, trigger the debugger before any tty-providing
console was registered and you do not provide an explicit console=
parameter, you end up with a panic due to lacking /dev/console. But this
time I have a better fix (for register_console), will be posted
separately later on.
<--snip-->
In case "kgdbwait" is passed as kernel parameter, KGDB tries to set up
and connect to the front-end already during early_param evaluation. This
fails on x86 as the exception stack is not yet initialized, effectively
delaying kgdbwait until late-init.
Therefore, this patch hooks into the x86 trap initialization and
re-triggers the KGDB setup, including a potential early rendezvous with
gdb. As a precondition, KGDB's setup states are refactored once again to
allow multiple invocations of kgdb_early_entry and correct tracking of
pending kgdbwait requests.
Signed-off-by: Jan Kiszka <jan.kiszka@web.de>
---
arch/x86/kernel/traps_32.c | 4 +++
arch/x86/kernel/traps_64.c | 4 +++
include/linux/kgdb.h | 7 ++++-
kernel/kgdb.c | 55 ++++++++++++++++++++++++---------------------
4 files changed, 44 insertions(+), 26 deletions(-)
Index: b/arch/x86/kernel/traps_32.c
===================================================================
--- a/arch/x86/kernel/traps_32.c
+++ b/arch/x86/kernel/traps_32.c
@@ -25,6 +25,7 @@
#include <linux/utsname.h>
#include <linux/kprobes.h>
#include <linux/kexec.h>
+#include <linux/kgdb.h>
#include <linux/unwind.h>
#include <linux/uaccess.h>
#include <linux/nmi.h>
@@ -1215,6 +1216,9 @@ void __init trap_init(void)
*/
cpu_init();
+ /* With the TSS set up, it's now save to arm early KGDB. */
+ kgdb_early_entry();
+
trap_init_hook();
}
Index: b/arch/x86/kernel/traps_64.c
===================================================================
--- a/arch/x86/kernel/traps_64.c
+++ b/arch/x86/kernel/traps_64.c
@@ -27,6 +27,7 @@
#include <linux/nmi.h>
#include <linux/kprobes.h>
#include <linux/kexec.h>
+#include <linux/kgdb.h>
#include <linux/unwind.h>
#include <linux/uaccess.h>
#include <linux/bug.h>
@@ -1162,6 +1163,9 @@ void __init trap_init(void)
* Should be a barrier for any external CPU state.
*/
cpu_init();
+
+ /* With the TSS set up, it's now save to arm early KGDB. */
+ kgdb_early_entry();
}
Index: b/include/linux/kgdb.h
===================================================================
--- a/include/linux/kgdb.h
+++ b/include/linux/kgdb.h
@@ -46,7 +46,8 @@ extern struct task_struct *kgdb_usethrea
enum kgdb_initstate {
KGDB_UNINITIALIZED = 0,
- KGDB_SEMI_INITIALIZED,
+ KGDB_ARCH_INITIALIZED,
+ KGDB_DELAYED_CONNECTION,
KGDB_FULLY_INITIALIZED
};
@@ -286,11 +287,15 @@ int kgdb_handle_exception(int ex_vector,
struct pt_regs *regs);
int kgdb_nmihook(int cpu, void *regs);
+void __init kgdb_early_entry(void);
+
extern int debugger_step;
extern atomic_t debugger_active;
#else /* !CONFIG_KGDB */
static const atomic_t debugger_active = ATOMIC_INIT(0);
+
+static inline void kgdb_early_entry(void) { }
#endif /* !CONFIG_KGDB */
#endif /* _KGDB_H_ */
Index: b/kernel/kgdb.c
===================================================================
--- a/kernel/kgdb.c
+++ b/kernel/kgdb.c
@@ -1925,32 +1925,39 @@ void kgdb_unregister_io_module(struct kg
}
EXPORT_SYMBOL_GPL(kgdb_unregister_io_module);
+static void __init kgdb_initial_breakpoint(void)
+{
+ printk(KERN_CRIT "kgdb: Waiting for connection from remote gdb...\n");
+ breakpoint();
+}
+
/*
* This function can be called very early, either via early_param() or
* an explicit breakpoint() early on.
*/
-static void __init kgdb_early_entry(void)
+void __init kgdb_early_entry(void)
{
+ int need_break = (kgdb_state == KGDB_DELAYED_CONNECTION);
+
/* Let the architecture do any setup that it needs to. */
- kgdb_arch_init();
+ if (kgdb_state == KGDB_UNINITIALIZED) {
+ kgdb_arch_init();
+ kgdb_state = KGDB_ARCH_INITIALIZED;
+ }
/*
* Don't try and do anything until the architecture is able to
* setup the exception stack. In this case, it is up to the
* architecture to hook in and look at us when they are ready.
*/
-
- if (!EXCEPTION_STACK_READY()) {
- kgdb_state = KGDB_SEMI_INITIALIZED;
- /* any kind of break point is deferred to late_init */
+ if (!EXCEPTION_STACK_READY())
return;
- }
/* Now try the I/O. */
/* For early entry kgdb_io_ops.init must be defined */
if (!kgdb_io_ops.init || kgdb_io_ops.init()) {
- /* Try again later. */
- kgdb_state = KGDB_SEMI_INITIALIZED;
+ printk(KERN_ERR "kgdb: Could not setup core I/O for KGDB.\n");
+ printk(KERN_INFO "kgdb: Defering I/O setup to late init.\n");
return;
}
@@ -1964,6 +1971,9 @@ static void __init kgdb_early_entry(void
*/
if (kgdb_io_ops.init)
kgdb_register_for_panic();
+
+ if (need_break)
+ kgdb_initial_breakpoint();
}
/*
@@ -1974,14 +1984,16 @@ static void __init kgdb_early_entry(void
*/
static int __init kgdb_late_entry(void)
{
- int need_break = (kgdb_state == KGDB_SEMI_INITIALIZED);
+ int need_break = (kgdb_state == KGDB_DELAYED_CONNECTION);
/*
* If we haven't tried to initialize KGDB yet, we need to call
* kgdb_arch_init before moving onto the I/O.
*/
- if (kgdb_state == KGDB_UNINITIALIZED)
+ if (kgdb_state == KGDB_UNINITIALIZED) {
kgdb_arch_init();
+ kgdb_state = KGDB_ARCH_INITIALIZED;
+ }
if (kgdb_state != KGDB_FULLY_INITIALIZED) {
if (kgdb_io_ops.init && kgdb_io_ops.init()) {
@@ -2015,11 +2027,8 @@ static int __init kgdb_late_entry(void)
if (kgdb_io_ops.late_init)
kgdb_io_ops.late_init();
- if (need_break) {
- printk(KERN_CRIT "kgdb: Waiting for connection from remote"
- " gdb...\n");
- breakpoint();
- }
+ if (need_break)
+ kgdb_initial_breakpoint();
return 0;
}
@@ -2072,7 +2081,6 @@ module_init(gdb_register_sysrq);
static int kgdb_notify_reboot(struct notifier_block *this,
unsigned long code, void *x)
{
-
unsigned long flags;
/* If we're debugging, or KGDB has not connected, don't try
@@ -2093,6 +2101,7 @@ static int __init opt_kgdb_attachwait(ch
attachwait = 1;
return 0;
}
+
static int __init opt_kgdb_enter(char *str)
{
/* We've already done this by an explicit breakpoint() call. */
@@ -2101,15 +2110,11 @@ static int __init opt_kgdb_enter(char *s
kgdb_early_entry();
attachwait = 1;
- if (kgdb_state == KGDB_FULLY_INITIALIZED)
- printk(KERN_CRIT "Waiting for connection from remote "
- "gdb...\n");
- else {
- printk(KERN_CRIT "KGDB cannot initialize I/O yet.\n");
- return 0;
- }
- breakpoint();
+ if (kgdb_state == KGDB_FULLY_INITIALIZED)
+ kgdb_initial_breakpoint();
+ else
+ kgdb_state = KGDB_DELAYED_CONNECTION;
return 0;
}
next reply other threads:[~2008-01-29 23:44 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-01-29 23:43 Jan Kiszka [this message]
2008-01-30 23:08 ` [PATCH 1/5] KGDB: improve early init Jan Kiszka
2008-01-31 14:22 ` [Kgdb-bugreport] " George Anzinger
2008-01-31 14:41 ` Jan Kiszka
2008-01-31 23:06 ` Jan Kiszka
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=479FBA3B.5050209@web.de \
--to=jan.kiszka@web.de \
--cc=jason.wessel@windriver.com \
--cc=kgdb-bugreport@lists.sourceforge.net \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@elte.hu \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.