[PATHC] kdb early fix for i386 kernel

Konstantin Baydarov <[email protected]>
Newsgroups gmane.linux.kernel.debugging
Message-ID <[email protected]>
Hi!
I didn't get any reply on my previous message, I update patch and I hope I'll get
reply on that one.

Issue:
  KDB early doesn't work. Can't get kdb console during boot.
Investigations:
  KDB tries to stop kernel very early (in star_kernel() function) executing KDB_ENTER().
  To stop kernel kdb have to register trap kdb_call() in IDT before KDB_ENTER() call.
  But KDB set gate traps later using initcall.
How Solved:
  Patch set KDBENTER_VECTOR trap gate before KDB_ENTER call - in the end of init_IRQ().
  I set KDBENTER_VECTOR trap gate in init_IRQ, not in init_traps(), because in SMP
  case init_IRQ() can reset KDBENTER_VECTOR trap gate to default handler.
  I set KDB_VECTOR SMP trap gate in smp_intr_init() - also before KDB_ENTER() call.
  Another issue: kernel can reset KDB trap gates in setup_IO_APIC_irqs(),
  so I've added extra check in setup_IO_APIC_irqs() to prevent KDB trap gates reset.

Patch against krenel 2.6.18. Thanks.

Signed-off-by: Konstantin Baydarov <[email protected]>

 arch/i386/kdb/kdbasupport.c |   38 --------------------------------------
 arch/i386/kernel/i8259.c    |    8 ++++++++
 arch/i386/kernel/io_apic.c  |    5 ++++-
 arch/i386/kernel/smpboot.c  |    8 ++++++++
 arch/i386/kernel/traps.c    |    8 ++++++++
 5 files changed, 28 insertions(+), 39 deletions(-)

Index: linux-2.6.18/arch/i386/kdb/kdbasupport.c
===================================================================
--- linux-2.6.18.orig/arch/i386/kdb/kdbasupport.c
+++ linux-2.6.18/arch/i386/kdb/kdbasupport.c
@@ -875,32 +875,6 @@ kdba_stackdepth(int argc, const char **a
 	return 0;
 }
 
-/* Copied from arch/i386/kernel/traps.c */
-
-extern struct desc_struct idt_table[256];
-
-#define _set_gate(gate_addr,type,dpl,addr,seg) \
-do { \
-  int __d0, __d1; \
-  __asm__ __volatile__ ("movw %%dx,%%ax\n\t" \
-	"movw %4,%%dx\n\t" \
-	"movl %%eax,%0\n\t" \
-	"movl %%edx,%1" \
-	:"=m" (*((long *) (gate_addr))), \
-	 "=m" (*(1+(long *) (gate_addr))), "=&a" (__d0), "=&d" (__d1) \
-	:"i" ((short) (0x8000+(dpl<<13)+(type<<8))), \
-	 "3" ((char *) (addr)),"2" ((seg) << 16)); \
-} while (0)
-
-static void __init set_trap_gate(unsigned int n, void *addr)
-{
-	_set_gate(idt_table+n,15,0,addr,__KERNEL_CS);
-}
-
-/* End of copy from arch/i386/kernel/traps.c */
-
-asmlinkage int kdb_call(void);
-
 /* Executed once on each cpu at startup. */
 void
 kdba_cpu_up(void)
@@ -1037,18 +1011,6 @@ kdba_verify_rw(unsigned long addr, size_
 	return(kdba_getarea_size(data, addr, size) || kdba_putarea_size(addr, data, size));
 }
 
-static int __init
-kdba_late_init(void)
-{
-#ifdef	CONFIG_SMP
-	set_intr_gate(KDB_VECTOR, kdb_interrupt);
-#endif
-	set_trap_gate(KDBENTER_VECTOR, kdb_call);
-	return 0;
-}
-
-__initcall(kdba_late_init);
-
 #ifdef	CONFIG_SMP
 
 #include <mach_ipi.h>
Index: linux-2.6.18/arch/i386/kernel/i8259.c
===================================================================
--- linux-2.6.18.orig/arch/i386/kernel/i8259.c
+++ linux-2.6.18/arch/i386/kernel/i8259.c
@@ -395,6 +395,11 @@ void __init init_ISA_irqs (void)
 	}
 }
 
+#ifdef	CONFIG_KDB
+asmlinkage int kdb_call(void);
+void __init kdb_set_trap_gate(unsigned int n, void *addr);
+#endif	/* CONFIG_KDB */
+
 void __init init_IRQ(void)
 {
 	int i;
@@ -434,4 +439,7 @@ void __init init_IRQ(void)
 		setup_irq(FPU_IRQ, &fpu_irq);
 
 	irq_ctx_init(smp_processor_id());
+#ifdef	CONFIG_KDB
+	kdb_set_trap_gate(KDBENTER_VECTOR, kdb_call);
+#endif
 }
Index: linux-2.6.18/arch/i386/kernel/io_apic.c
===================================================================
--- linux-2.6.18.orig/arch/i386/kernel/io_apic.c
+++ linux-2.6.18/arch/i386/kernel/io_apic.c
@@ -1278,7 +1278,10 @@ static void __init setup_IO_APIC_irqs(vo
 		if (IO_APIC_IRQ(irq)) {
 			vector = assign_irq_vector(irq);
 			entry.vector = vector;
-			ioapic_register_intr(irq, vector, IOAPIC_AUTO);
+#ifdef	CONFIG_KDB
+			if((vector != KDB_VECTOR) && (vector != KDBENTER_VECTOR))
+#endif
+				ioapic_register_intr(irq, vector, IOAPIC_AUTO);
 		
 			if (!apic && (irq < 16))
 				disable_8259A_irq(irq);
Index: linux-2.6.18/arch/i386/kernel/smpboot.c
===================================================================
--- linux-2.6.18.orig/arch/i386/kernel/smpboot.c
+++ linux-2.6.18/arch/i386/kernel/smpboot.c
@@ -57,6 +57,11 @@
 #include <mach_wakecpu.h>
 #include <smpboot_hooks.h>
 
+#ifdef	CONFIG_KDB
+#include <linux/kdb.h>
+#include <linux/kdbprivate.h>
+#endif
+
 /* Set if we find a B stepping CPU */
 static int __devinitdata smp_b_stepping;
 
@@ -1485,4 +1490,7 @@ void __init smp_intr_init(void)
 
 	/* IPI for generic function call */
 	set_intr_gate(CALL_FUNCTION_VECTOR, call_function_interrupt);
+#ifdef	CONFIG_KDB
+	set_intr_gate(KDB_VECTOR, kdb_interrupt);
+#endif
 }
Index: linux-2.6.18/arch/i386/kernel/traps.c
===================================================================
--- linux-2.6.18.orig/arch/i386/kernel/traps.c
+++ linux-2.6.18/arch/i386/kernel/traps.c
@@ -40,6 +40,7 @@
 
 #ifdef	CONFIG_KDB
 #include <linux/kdb.h>
+#include <linux/kdbprivate.h>
 #endif	/* CONFIG_KDB */
 
 #include <asm/processor.h>
@@ -1200,6 +1201,13 @@ static void __init set_trap_gate(unsigne
 	_set_gate(idt_table+n,15,0,addr,__KERNEL_CS);
 }
 
+#ifdef	CONFIG_KDB
+void __init kdb_set_trap_gate(unsigned int n, void *addr)
+{
+	set_trap_gate(n, addr);
+}
+#endif
+
 static void __init set_system_gate(unsigned int n, void *addr)
 {
 	_set_gate(idt_table+n,15,3,addr,__KERNEL_CS);
---------------------------
Use http://oss.sgi.com/ecartis to modify your settings or to unsubscribe.
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.