[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.