kdb
[Top] [All Lists]

PATCH: 2.6.11 i386 changes to use notify callback interface

To: kdb@xxxxxxxxxxx
Subject: PATCH: 2.6.11 i386 changes to use notify callback interface
From: Jack F Vogel <jfv@xxxxxxxxxxxx>
Date: Tue, 15 Mar 2005 17:06:30 -0800
Cc: jfv@xxxxxxxxxx, lcm@xxxxxxxxxx
Reply-to: jfv@xxxxxxxxxxxx
Sender: kdb-bounce@xxxxxxxxxxx
User-agent: Mutt/1.5.6i
This is an experimental patch that I did to switch the i386
kernel to use notify_die(), it is based on the x86_64 version
that I wrote.
This patch is designed to apply over the top of the common and
i386 2.6.11 patches.

From my point of view the goal is to reduce KDB source intrusion
to minimal in the main kernel source, and this patch takes a
step in that direction, it is by no means complete.

I have built, booted, and minimally tested this, it needs more
testing, but I thought I'd give it to you Keith to polish and
tweak to your own tastes.

Cheers,

Jack




-- Attached file included as plaintext by Ecartis --

diff -Naur linux-2.6.11/arch/i386/kdb/kdbasupport.c 
linux-2.6.11-jfv/arch/i386/kdb/kdbasupport.c
--- linux-2.6.11/arch/i386/kdb/kdbasupport.c    2005-03-15 03:53:52.000000000 
-0800
+++ linux-2.6.11-jfv/arch/i386/kdb/kdbasupport.c        2005-03-15 
03:28:34.000000000 -0800
@@ -20,7 +20,7 @@
 #include <linux/sched.h>
 #include <linux/kdb.h>
 #include <linux/kdbprivate.h>
-
+#include <asm/kdebug.h>
 #include <asm/processor.h>
 #include <asm/msr.h>
 #include <asm/uaccess.h>
@@ -1434,6 +1434,54 @@
 }
 
 /*
+ * kdba_entry
+ *
+ *     This is the interface routine between
+ *     the notifier die_chain and kdb
+ */
+static int kdba_entry( struct notifier_block *b, unsigned long val, void *v)
+{
+       struct die_args *args = v;
+       int err, trap, ret = 0;
+       struct pt_regs *regs;
+
+       regs = args->regs;
+       err  = args->err;
+       trap  = args->trapnr;
+       switch (val){
+#if defined(CONFIG_SMP)
+               case DIE_NMI_IPI:
+                       ret = kdb_ipi(regs, NULL);
+                       break;
+#endif
+               case DIE_OOPS:
+                       ret = kdb(KDB_REASON_OOPS, err, regs);
+                       break;
+               case DIE_CALL:
+                       ret = kdb(KDB_REASON_ENTER, err, regs);
+                       break;
+               case DIE_DEBUG:
+                       ret = kdb(KDB_REASON_DEBUG, err, regs);
+                       break;
+               case DIE_TRAP:
+                       if (trap == 3)          // breakpoint
+                               ret = kdb(KDB_REASON_BREAK, err, regs);
+                       // falls thru
+               default:
+                        break;
+       }
+       return (ret ? NOTIFY_BAD : NOTIFY_DONE);
+}
+
+/*
+ * notifier block for kdb entry
+ */
+static struct notifier_block kdba_notifier = {
+       .notifier_call = kdba_entry
+};
+
+
+/*
  * kdba_init
  *
  *     Architecture specific initialization.
@@ -1454,7 +1502,7 @@
        kdba_enable_lbr();
        kdb_register("pt_regs", kdba_pt_regs, "address", "Format struct 
pt_regs", 0);
        kdb_register("stackdepth", kdba_stackdepth, "[percentage]", "Print 
processes using >= stack percentage", 0);
-
+       notifier_chain_register(&i386die_chain, &kdba_notifier);
        return;
 }
 
diff -Naur linux-2.6.11/arch/i386/kernel/entry.S 
linux-2.6.11-jfv/arch/i386/kernel/entry.S
--- linux-2.6.11/arch/i386/kernel/entry.S       2005-03-15 03:53:52.000000000 
-0800
+++ linux-2.6.11-jfv/arch/i386/kernel/entry.S   2005-03-14 06:42:01.000000000 
-0800
@@ -147,17 +147,15 @@
        popl %eax
        jmp syscall_exit
 
-#if defined(CONFIG_KDB)
-ENTRY(kdb_call)
+ENTRY(call_debug)
        pushl %eax              # save orig EAX
        SAVE_ALL
        pushl %esp              # struct pt_regs
        pushl $0                # error_code
-       pushl $7                # KDB_REASON_ENTRY
-       call  kdb
+       pushl $7                # REASON_ENTRY
+       call  do_call_debug
        addl  $12,%esp          # remove args
        jmp restore_all
-#endif
 
 /*
  * Return to user mode is not as complex as all this looks,
diff -Naur linux-2.6.11/arch/i386/kernel/i8259.c 
linux-2.6.11-jfv/arch/i386/kernel/i8259.c
--- linux-2.6.11/arch/i386/kernel/i8259.c       2005-03-15 03:53:52.000000000 
-0800
+++ linux-2.6.11-jfv/arch/i386/kernel/i8259.c   2005-03-15 02:55:46.000000000 
-0800
@@ -24,6 +24,7 @@
 #include <asm/apic.h>
 #include <asm/arch_hooks.h>
 #include <asm/i8259.h>
+#include <asm/kdebug.h>
 
 #include <linux/irq.h>
 
@@ -404,11 +405,7 @@
                int vector = FIRST_EXTERNAL_VECTOR + i;
                if (i >= NR_IRQS)
                        break;
-#ifdef CONFIG_KDB
-               if (vector == KDBENTER_VECTOR)
-                       continue;
-#endif
-               if (vector != SYSCALL_VECTOR) 
+               if (vector != SYSCALL_VECTOR && vector != KDB_VECTOR) 
                        set_intr_gate(vector, interrupt[i]);
        }
 
diff -Naur linux-2.6.11/arch/i386/kernel/io_apic.c 
linux-2.6.11-jfv/arch/i386/kernel/io_apic.c
--- linux-2.6.11/arch/i386/kernel/io_apic.c     2005-03-15 03:53:52.000000000 
-0800
+++ linux-2.6.11-jfv/arch/i386/kernel/io_apic.c 2005-03-15 02:52:59.000000000 
-0800
@@ -27,9 +27,6 @@
 #include <linux/delay.h>
 #include <linux/sched.h>
 #include <linux/config.h>
-#ifdef CONFIG_KDB
-#include <linux/kdb.h>
-#endif /* CONFIG_KDB */
 #include <linux/smp_lock.h>
 #include <linux/mc146818rtc.h>
 #include <linux/compiler.h>
@@ -1141,10 +1138,6 @@
        current_vector += 8;
        if (current_vector == SYSCALL_VECTOR)
                goto next;
-#ifdef CONFIG_KDB
-       if (current_vector == KDBENTER_VECTOR)
-               goto next;
-#endif /* CONFIG_KDB */
 
        if (current_vector >= FIRST_SYSTEM_VECTOR) {
                offset++;
diff -Naur linux-2.6.11/arch/i386/kernel/nmi.c 
linux-2.6.11-jfv/arch/i386/kernel/nmi.c
--- linux-2.6.11/arch/i386/kernel/nmi.c 2005-03-01 23:38:10.000000000 -0800
+++ linux-2.6.11-jfv/arch/i386/kernel/nmi.c     2005-03-15 03:08:29.000000000 
-0800
@@ -31,6 +31,7 @@
 #include <asm/mtrr.h>
 #include <asm/mpspec.h>
 #include <asm/nmi.h>
+#include <asm/kdebug.h>
 
 #include "mach_traps.h"
 
@@ -491,8 +492,13 @@
                 * wait a few IRQs (5 seconds) before doing the oops ...
                 */
                alert_counter[cpu]++;
-               if (alert_counter[cpu] == 5*nmi_hz)
+               if (alert_counter[cpu] == 5*nmi_hz) {
+                       if (notify_die(DIE_NMI, "nmi", regs, 0, 2, SIGINT) == 
NOTIFY_BAD) {
+                               alert_counter[cpu] = 0;
+                               return;
+                       }
                        die_nmi(regs, "NMI Watchdog detected LOCKUP");
+               }
        } else {
                last_irq_sums[cpu] = sum;
                alert_counter[cpu] = 0;
diff -Naur linux-2.6.11/arch/i386/kernel/smp.c 
linux-2.6.11-jfv/arch/i386/kernel/smp.c
--- linux-2.6.11/arch/i386/kernel/smp.c 2005-03-15 03:53:52.000000000 -0800
+++ linux-2.6.11-jfv/arch/i386/kernel/smp.c     2005-03-15 02:45:22.000000000 
-0800
@@ -25,6 +25,7 @@
 #include <mach_apic.h>
 
 #include <linux/config.h>
+#include <asm/kdebug.h>
 #ifdef CONFIG_KDB
 #include <linux/kdb.h>
 #endif /* CONFIG_KDB */
diff -Naur linux-2.6.11/arch/i386/kernel/traps.c 
linux-2.6.11-jfv/arch/i386/kernel/traps.c
--- linux-2.6.11/arch/i386/kernel/traps.c       2005-03-15 03:53:52.000000000 
-0800
+++ linux-2.6.11-jfv/arch/i386/kernel/traps.c   2005-03-15 03:36:16.000000000 
-0800
@@ -61,9 +61,6 @@
 #include "mach_traps.h"
 
 asmlinkage int system_call(void);
-#ifdef CONFIG_KDB
-asmlinkage int kdb_call(void);
-#endif /* CONFIG_KDB */
 
 struct desc_struct default_ldt[] = { { 0, 0 }, { 0, 0 }, { 0, 0 },
                { 0, 0 }, { 0, 0 } };
@@ -100,6 +97,7 @@
 asmlinkage void alignment_check(void);
 asmlinkage void spurious_interrupt_bug(void);
 asmlinkage void machine_check(void);
+asmlinkage void call_debug(void);
 
 static int kstack_depth_to_print = 24;
 struct notifier_block *i386die_chain;
@@ -350,10 +348,6 @@
        bust_spinlocks(0);
        die.lock_owner = -1;
        spin_unlock_irq(&die.lock);
-#ifdef CONFIG_KDB
-       kdb_diemsg = str;
-       kdb(KDB_REASON_OOPS, err, regs);
-#endif /* CONFIG_KDB */
        if (in_interrupt())
                panic("Fatal exception in interrupt");
 
@@ -455,7 +449,7 @@
 }
 
 DO_VM86_ERROR_INFO( 0, SIGFPE,  "divide error", divide_error, FPE_INTDIV, 
regs->eip)
-#if    !defined(CONFIG_KPROBES) && !defined(CONFIG_KDB)
+#if    !defined(CONFIG_KPROBES)
 DO_VM86_ERROR( 3, SIGTRAP, "int3", int3)
 #endif
 DO_VM86_ERROR( 4, SIGSEGV, "overflow", overflow)
@@ -551,9 +545,6 @@
 
 static void unknown_nmi_error(unsigned char reason, struct pt_regs * regs)
 {
-#ifdef CONFIG_KDB
-       (void)kdb(KDB_REASON_NMI, reason, regs);
-#endif /* CONFIG_KDB */
 #ifdef CONFIG_MCA
        /* Might actually be able to figure out what the guilty party
        * is. */
@@ -583,9 +574,6 @@
                smp_processor_id(), regs->eip);
        show_registers(regs);
        printk("console shuts up ...\n");
-#ifdef CONFIG_KDB
-       kdb(KDB_REASON_NMI, 0, regs);
-#endif /* CONFIG_KDB */
        console_silent();
        spin_unlock(&nmi_print_lock);
        bust_spinlocks(0);
@@ -600,16 +588,6 @@
        if (!smp_processor_id())
                reason = get_nmi_reason();
 
-#if defined(CONFIG_SMP) && defined(CONFIG_KDB)
-       /*
-        * Call the kernel debugger to see if this NMI is due
-        * to an KDB requested IPI.  If so, kdb will handle it.
-        */
-       if (kdb_ipi(regs, NULL)) {
-               return;
-       }
-#endif /* defined(CONFIG_SMP) && defined(CONFIG_KDB) */
-
        if (!(reason & 0xc0)) {
                if (notify_die(DIE_NMI_IPI, "nmi_ipi", regs, reason, 0, SIGINT)
                                                        == NOTIFY_STOP)
@@ -715,11 +693,6 @@
 
        __asm__ __volatile__("movl %%db6,%0" : "=r" (condition));
 
-#ifdef CONFIG_KDB
-       if (kdb(KDB_REASON_DEBUG, error_code, regs))
-               return;
-#endif /* CONFIG_KDB */
-
        if (notify_die(DIE_DEBUG, "debug", regs, condition, error_code,
                                        SIGTRAP) == NOTIFY_STOP)
                return;
@@ -782,16 +755,6 @@
        return;
 }
 
-#ifdef CONFIG_KDB
-fastcall void do_int3(struct pt_regs * regs, long error_code)
-{
-       if (kdb(KDB_REASON_BREAK, error_code, regs))
-               return;
-       do_trap(3, SIGTRAP, "int3", 1, regs, error_code, NULL);
-}
-#endif /* CONFIG_KDB */
-
-
 /*
  * Note that we play around with the 'TS' bit in an attempt to get
  * the correct behaviour even in the presence of the asynchronous
@@ -1085,14 +1048,13 @@
        set_trap_gate(19,&simd_coprocessor_error);
 
        set_system_gate(SYSCALL_VECTOR,&system_call);
-#ifdef CONFIG_KDB
        kdb_enablehwfault();
+
        /*
         * A trap gate, used by the kernel to enter the 
         * debugger, preserving all registers.
         */
-       set_trap_gate(KDBENTER_VECTOR, &kdb_call);
-#endif /* CONFIG_KDB */
+       set_trap_gate(KDB_VECTOR, call_debug);
 
        /*
         * Should be a barrier for any external CPU state.
@@ -1101,3 +1063,9 @@
 
        trap_init_hook();
 }
+
+void do_call_debug(struct pt_regs *regs)
+{
+       notify_die(DIE_CALL, "debug call", regs, 0, 255, SIGINT);
+}
+
diff -Naur linux-2.6.11/include/asm-i386/kdb.h 
linux-2.6.11-jfv/include/asm-i386/kdb.h
--- linux-2.6.11/include/asm-i386/kdb.h 2005-03-15 03:53:52.000000000 -0800
+++ linux-2.6.11-jfv/include/asm-i386/kdb.h     2005-03-15 02:47:40.000000000 
-0800
@@ -17,7 +17,7 @@
  * is intended to be used from interrupt level, it must  use
  * a non-maskable entry method.
  */
-#define KDB_ENTER()    do {if (kdb_on && !KDB_IS_RUNNING()) { asm("\tint 
$129\n"); }} while(0)
+#define KDB_ENTER()    do {if (kdb_on && !KDB_IS_RUNNING()) { asm("\tint 
$249\n"); }} while(0)
 
 /*
  * Needed for exported symbols.


---------------------------
Use http://oss.sgi.com/ecartis to modify your settings or to unsubscribe.
<Prev in Thread] Current Thread [Next in Thread>
  • PATCH: 2.6.11 i386 changes to use notify callback interface, Jack F Vogel <=