lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <47A10355.9090707@web.de>
Date:	Thu, 31 Jan 2008 00:08:05 +0100
From:	Jan Kiszka <jan.kiszka@....de>
To:	Jason Wessel <jason.wessel@...driver.com>,
	Ingo Molnar <mingo@...e.hu>
CC:	Linux Kernel Mailing List <linux-kernel@...r.kernel.org>,
	kgdb-bugreport@...ts.sourceforge.net
Subject: Re: [PATCH 1/5] KGDB: improve early init

[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@....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;
 }
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ