[PATHC] kdb early fix for i386 kernel

Konstantin Baydarov kbaidarov at ru.mvista.com
Fri May 18 07:40:50 PDT 2007


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 <kbaidarov at ru.mvista.com>

 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.


More information about the kdb mailing list