From: Jan Kiszka <jan.kiszka@web.de>
To: Jason Wessel <jason.wessel@windriver.com>, Ingo Molnar <mingo@elte.hu>
Cc: Linux Kernel Mailing List <linux-kernel@vger.kernel.org>,
kgdb-bugreport@lists.sourceforge.net
Subject: Re: [PATCH 1/5] KGDB: improve early init
Date: Thu, 31 Jan 2008 00:08:05 +0100 [thread overview]
Message-ID: <47A10355.9090707@web.de> (raw)
In-Reply-To: <479FBA3B.5050209@web.de>
[Here comes a rebased version against latest x86/mm]
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 | 52 +++++++++++++++++++++++++--------------------
4 files changed, 44 insertions(+), 23 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
@@ -43,7 +43,8 @@ extern struct task_struct *kgdb_contthre
enum kgdb_initstate {
KGDB_UNINITIALIZED = 0,
- KGDB_SEMI_INITIALIZED,
+ KGDB_ARCH_INITIALIZED,
+ KGDB_DELAYED_CONNECTION,
KGDB_FULLY_INITIALIZED
};
@@ -287,6 +288,8 @@ 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;
@@ -296,6 +299,8 @@ 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
@@ -2104,33 +2104,41 @@ 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;
}
@@ -2145,6 +2153,9 @@ static void __init kgdb_early_entry(void
*/
if (kgdb_io_ops.init)
kgdb_register_for_panic();
+
+ if (need_break)
+ kgdb_initial_breakpoint();
}
/*
@@ -2155,14 +2166,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()) {
@@ -2177,6 +2190,7 @@ static int __init kgdb_late_entry(void)
printk(KERN_INFO "kgdb: Defering I/O setup to kernel "
"module.\n");
memset(&kgdb_io_ops, 0, sizeof(struct kgdb_io));
+ need_break = 0;
}
kgdb_internal_init();
@@ -2198,11 +2212,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;
}
@@ -2290,14 +2301,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 prev parent reply other threads:[~2008-01-30 23:08 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-01-29 23:43 [PATCH 1/5] KGDB: improve early init Jan Kiszka
2008-01-30 23:08 ` Jan Kiszka [this message]
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=47A10355.9090707@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.