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.

Reply via email to