]> git.karo-electronics.de Git - mv-sheeva.git/commitdiff
Merge branch 'dbg-early-merge' of git://git.kernel.org/pub/scm/linux/kernel/git/jwess...
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 21 May 2010 18:10:41 +0000 (11:10 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 21 May 2010 18:10:41 +0000 (11:10 -0700)
* 'dbg-early-merge' of git://git.kernel.org/pub/scm/linux/kernel/git/jwessel/linux-2.6-kgdb:
  echi-dbgp: Add kernel debugger support for the usb debug port
  earlyprintk,vga,kdb: Fix \b and \r for earlyprintk=vga with kdb
  kgdboc: Add ekgdboc for early use of the kernel debugger
  x86,early dr regs,kgdb: Allow kernel debugger early dr register access
  x86,kgdb: Implement early hardware breakpoint debugging
  x86, kgdb, init: Add early and late debug states
  x86, kgdb: early trap init for early debug

12 files changed:
Documentation/kernel-parameters.txt
arch/x86/include/asm/processor.h
arch/x86/kernel/cpu/common.c
arch/x86/kernel/early_printk.c
arch/x86/kernel/kgdb.c
arch/x86/kernel/setup.c
arch/x86/kernel/traps.c
drivers/serial/kgdboc.c
drivers/usb/early/ehci-dbgp.c
include/linux/kgdb.h
init/main.c
kernel/debug/debug_core.c

index bdce359820bb1683160931644836b25efe0b8af3..f5fce483930cf933d0eb7928f1a4fa6cfe8ff921 100644 (file)
@@ -713,6 +713,12 @@ and is between 256 and 4096 characters. It is defined in the file
                        The VGA output is eventually overwritten by the real
                        console.
 
+       ekgdboc=        [X86,KGDB] Allow early kernel console debugging
+                       ekgdboc=kbd
+
+                       This is desgined to be used in conjunction with
+                       the boot argument: earlyprintk=vga
+
        eata=           [HW,SCSI]
 
        edd=            [EDD]
@@ -1121,6 +1127,17 @@ and is between 256 and 4096 characters. It is defined in the file
                        use the HighMem zone if it exists, and the Normal
                        zone if it does not.
 
+       kgdbdbgp=       [KGDB,HW] kgdb over EHCI usb debug port.
+                       Format: <Controller#>[,poll interval]
+                       The controller # is the number of the ehci usb debug
+                       port as it is probed via PCI.  The poll interval is
+                       optional and is the number seconds in between
+                       each poll cycle to the debug port in case you need
+                       the functionality for interrupting the kernel with
+                       gdb or control-c on the dbgp connection.  When
+                       not using this parameter you use sysrq-g to break into
+                       the kernel debugger.
+
        kgdboc=         [KGDB,HW] kgdb over consoles.
                        Requires a tty driver that supports console polling,
                        or a supported polling keyboard driver (non-usb).
index 5a51379dcbe4a7c3dab91a157f752d4c58889117..7e5c6a60b8ee190ab85b8ed88503ec2436197ea9 100644 (file)
@@ -789,6 +789,8 @@ static inline void wbinvd_halt(void)
 extern void enable_sep_cpu(void);
 extern int sysenter_setup(void);
 
+extern void early_trap_init(void);
+
 /* Defined in head.S */
 extern struct desc_ptr         early_gdt_descr;
 
index c1c00d0b1692d47bf45981439122b962a9b1dac0..cc83a002786e0bb16163afd17ffba909f88abe14 100644 (file)
@@ -1084,6 +1084,20 @@ static void clear_all_debug_regs(void)
        }
 }
 
+#ifdef CONFIG_KGDB
+/*
+ * Restore debug regs if using kgdbwait and you have a kernel debugger
+ * connection established.
+ */
+static void dbg_restore_debug_regs(void)
+{
+       if (unlikely(kgdb_connected && arch_kgdb_ops.correct_hw_break))
+               arch_kgdb_ops.correct_hw_break();
+}
+#else /* ! CONFIG_KGDB */
+#define dbg_restore_debug_regs()
+#endif /* ! CONFIG_KGDB */
+
 /*
  * cpu_init() initializes state that is per-CPU. Some data is already
  * initialized (naturally) in the bootstrap process, such as the GDT
@@ -1174,18 +1188,8 @@ void __cpuinit cpu_init(void)
        load_TR_desc();
        load_LDT(&init_mm.context);
 
-#ifdef CONFIG_KGDB
-       /*
-        * If the kgdb is connected no debug regs should be altered.  This
-        * is only applicable when KGDB and a KGDB I/O module are built
-        * into the kernel and you are using early debugging with
-        * kgdbwait. KGDB will control the kernel HW breakpoint registers.
-        */
-       if (kgdb_connected && arch_kgdb_ops.correct_hw_break)
-               arch_kgdb_ops.correct_hw_break();
-       else
-#endif
-               clear_all_debug_regs();
+       clear_all_debug_regs();
+       dbg_restore_debug_regs();
 
        fpu_init();
 
@@ -1239,6 +1243,7 @@ void __cpuinit cpu_init(void)
 #endif
 
        clear_all_debug_regs();
+       dbg_restore_debug_regs();
 
        /*
         * Force FPU initialization:
index b9c830c12b4ac1de45d137a736be6de7fbd19fb4..fa99bae75acee4d1efb12b141a24d97019e03b5f 100644 (file)
@@ -41,6 +41,14 @@ static void early_vga_write(struct console *con, const char *str, unsigned n)
                                writew(0x720, VGABASE + 2*(max_xpos*j + i));
                        current_ypos = max_ypos-1;
                }
+#ifdef CONFIG_KGDB_KDB
+               if (c == '\b') {
+                       if (current_xpos > 0)
+                               current_xpos--;
+               } else if (c == '\r') {
+                       current_xpos = 0;
+               } else
+#endif
                if (c == '\n') {
                        current_xpos = 0;
                        current_ypos++;
index 95b89d4cb8f18f1595a430e0e6eaf8ac5f513487..4f4af75b94828af47b811b6b5c6a45e7c4ae650e 100644 (file)
@@ -199,6 +199,8 @@ static struct hw_breakpoint {
        struct perf_event       **pev;
 } breakinfo[4];
 
+static unsigned long early_dr7;
+
 static void kgdb_correct_hw_break(void)
 {
        int breakno;
@@ -210,6 +212,14 @@ static void kgdb_correct_hw_break(void)
                int cpu = raw_smp_processor_id();
                if (!breakinfo[breakno].enabled)
                        continue;
+               if (dbg_is_early) {
+                       set_debugreg(breakinfo[breakno].addr, breakno);
+                       early_dr7 |= encode_dr7(breakno,
+                                               breakinfo[breakno].len,
+                                               breakinfo[breakno].type);
+                       set_debugreg(early_dr7, 7);
+                       continue;
+               }
                bp = *per_cpu_ptr(breakinfo[breakno].pev, cpu);
                info = counter_arch_bp(bp);
                if (bp->attr.disabled != 1)
@@ -224,7 +234,8 @@ static void kgdb_correct_hw_break(void)
                if (!val)
                        bp->attr.disabled = 0;
        }
-       hw_breakpoint_restore();
+       if (!dbg_is_early)
+               hw_breakpoint_restore();
 }
 
 static int hw_break_reserve_slot(int breakno)
@@ -233,6 +244,9 @@ static int hw_break_reserve_slot(int breakno)
        int cnt = 0;
        struct perf_event **pevent;
 
+       if (dbg_is_early)
+               return 0;
+
        for_each_online_cpu(cpu) {
                cnt++;
                pevent = per_cpu_ptr(breakinfo[breakno].pev, cpu);
@@ -258,6 +272,9 @@ static int hw_break_release_slot(int breakno)
        struct perf_event **pevent;
        int cpu;
 
+       if (dbg_is_early)
+               return 0;
+
        for_each_online_cpu(cpu) {
                pevent = per_cpu_ptr(breakinfo[breakno].pev, cpu);
                if (dbg_release_bp_slot(*pevent))
@@ -302,7 +319,11 @@ static void kgdb_remove_all_hw_break(void)
                bp = *per_cpu_ptr(breakinfo[i].pev, cpu);
                if (bp->attr.disabled == 1)
                        continue;
-               arch_uninstall_hw_breakpoint(bp);
+               if (dbg_is_early)
+                       early_dr7 &= ~encode_dr7(i, breakinfo[i].len,
+                                                breakinfo[i].type);
+               else
+                       arch_uninstall_hw_breakpoint(bp);
                bp->attr.disabled = 1;
        }
 }
@@ -379,6 +400,11 @@ void kgdb_disable_hw_debug(struct pt_regs *regs)
        for (i = 0; i < 4; i++) {
                if (!breakinfo[i].enabled)
                        continue;
+               if (dbg_is_early) {
+                       early_dr7 &= ~encode_dr7(i, breakinfo[i].len,
+                                                breakinfo[i].type);
+                       continue;
+               }
                bp = *per_cpu_ptr(breakinfo[i].pev, cpu);
                if (bp->attr.disabled == 1)
                        continue;
@@ -595,15 +621,16 @@ static struct notifier_block kgdb_notifier = {
  *     specific callbacks.
  */
 int kgdb_arch_init(void)
+{
+       return register_die_notifier(&kgdb_notifier);
+}
+
+void kgdb_arch_late(void)
 {
        int i, cpu;
-       int ret;
        struct perf_event_attr attr;
        struct perf_event **pevent;
 
-       ret = register_die_notifier(&kgdb_notifier);
-       if (ret != 0)
-               return ret;
        /*
         * Pre-allocate the hw breakpoint structions in the non-atomic
         * portion of kgdb because this operation requires mutexs to
@@ -615,12 +642,15 @@ int kgdb_arch_init(void)
        attr.bp_type = HW_BREAKPOINT_W;
        attr.disabled = 1;
        for (i = 0; i < 4; i++) {
+               if (breakinfo[i].pev)
+                       continue;
                breakinfo[i].pev = register_wide_hw_breakpoint(&attr, NULL);
                if (IS_ERR(breakinfo[i].pev)) {
-                       printk(KERN_ERR "kgdb: Could not allocate hw breakpoints\n");
+                       printk(KERN_ERR "kgdb: Could not allocate hw"
+                              "breakpoints\nDisabling the kernel debugger\n");
                        breakinfo[i].pev = NULL;
                        kgdb_arch_exit();
-                       return -1;
+                       return;
                }
                for_each_online_cpu(cpu) {
                        pevent = per_cpu_ptr(breakinfo[i].pev, cpu);
@@ -631,7 +661,6 @@ int kgdb_arch_init(void)
                        }
                }
        }
-       return ret;
 }
 
 /**
index c4851eff57b32ce96e5bc2e72f536d01a6a78fb8..e8029896309af8cadb39b2445568d8c3ddc410ae 100644 (file)
@@ -725,6 +725,7 @@ void __init setup_arch(char **cmdline_p)
        /* VMI may relocate the fixmap; do this before touching ioremap area */
        vmi_init();
 
+       early_trap_init();
        early_cpu_init();
        early_ioremap_init();
 
index 7eaad4c5110a15934bc24b162acb274a85bf82c7..142d70c74b027c31512c02dafea1e510d686a2fb 100644 (file)
@@ -808,6 +808,16 @@ dotraplinkage void do_iret_error(struct pt_regs *regs, long error_code)
 }
 #endif
 
+/* Set of traps needed for early debugging. */
+void __init early_trap_init(void)
+{
+       set_intr_gate_ist(1, &debug, DEBUG_STACK);
+       /* int3 can be called from all */
+       set_system_intr_gate_ist(3, &int3, DEBUG_STACK);
+       set_intr_gate(14, &page_fault);
+       load_idt(&idt_descr);
+}
+
 void __init trap_init(void)
 {
        int i;
@@ -821,10 +831,7 @@ void __init trap_init(void)
 #endif
 
        set_intr_gate(0, &divide_error);
-       set_intr_gate_ist(1, &debug, DEBUG_STACK);
        set_intr_gate_ist(2, &nmi, NMI_STACK);
-       /* int3 can be called from all */
-       set_system_intr_gate_ist(3, &int3, DEBUG_STACK);
        /* int4 can be called from all */
        set_system_intr_gate(4, &overflow);
        set_intr_gate(5, &bounds);
@@ -840,7 +847,6 @@ void __init trap_init(void)
        set_intr_gate(11, &segment_not_present);
        set_intr_gate_ist(12, &stack_segment, STACKFAULT_STACK);
        set_intr_gate(13, &general_protection);
-       set_intr_gate(14, &page_fault);
        set_intr_gate(15, &spurious_interrupt_bug);
        set_intr_gate(16, &coprocessor_error);
        set_intr_gate(17, &alignment_check);
index b765ab48dfe7aa9d1f9b771335e34e4c5695f14d..a9a94ae7234951f3b30b25829c67d1ee13a3a8f2 100644 (file)
@@ -223,6 +223,25 @@ static struct kgdb_io kgdboc_io_ops = {
        .post_exception         = kgdboc_post_exp_handler,
 };
 
+#ifdef CONFIG_KGDB_SERIAL_CONSOLE
+/* This is only available if kgdboc is a built in for early debugging */
+int __init kgdboc_early_init(char *opt)
+{
+       /* save the first character of the config string because the
+        * init routine can destroy it.
+        */
+       char save_ch;
+
+       kgdboc_option_setup(opt);
+       save_ch = config[0];
+       init_kgdboc();
+       config[0] = save_ch;
+       return 0;
+}
+
+early_param("ekgdboc", kgdboc_early_init);
+#endif /* CONFIG_KGDB_SERIAL_CONSOLE */
+
 module_init(init_kgdboc);
 module_exit(cleanup_kgdboc);
 module_param_call(kgdboc, param_set_kgdboc_var, param_get_string, &kps, 0644);
index 6e98a369784473e08ab9efaa462de09a86ba8b8c..94ecdbc758ce60810cf176c0fdd479106b80bcdc 100644 (file)
@@ -19,6 +19,9 @@
 #include <linux/usb/ch9.h>
 #include <linux/usb/ehci_def.h>
 #include <linux/delay.h>
+#include <linux/serial_core.h>
+#include <linux/kgdb.h>
+#include <linux/kthread.h>
 #include <asm/io.h>
 #include <asm/pci-direct.h>
 #include <asm/fixmap.h>
@@ -55,6 +58,7 @@ static struct ehci_regs __iomem *ehci_regs;
 static struct ehci_dbg_port __iomem *ehci_debug;
 static int dbgp_not_safe; /* Cannot use debug device during ehci reset */
 static unsigned int dbgp_endpoint_out;
+static unsigned int dbgp_endpoint_in;
 
 struct ehci_dev {
        u32 bus;
@@ -91,6 +95,13 @@ static inline u32 dbgp_len_update(u32 x, u32 len)
        return (x & ~0x0f) | (len & 0x0f);
 }
 
+#ifdef CONFIG_KGDB
+static struct kgdb_io kgdbdbgp_io_ops;
+#define dbgp_kgdb_mode (dbg_io_ops == &kgdbdbgp_io_ops)
+#else
+#define dbgp_kgdb_mode (0)
+#endif
+
 /*
  * USB Packet IDs (PIDs)
  */
@@ -182,11 +193,10 @@ static void dbgp_breath(void)
        /* Sleep to give the debug port a chance to breathe */
 }
 
-static int dbgp_wait_until_done(unsigned ctrl)
+static int dbgp_wait_until_done(unsigned ctrl, int loop)
 {
        u32 pids, lpid;
        int ret;
-       int loop = DBGP_LOOPS;
 
 retry:
        writel(ctrl | DBGP_GO, &ehci_debug->control);
@@ -276,13 +286,13 @@ static int dbgp_bulk_write(unsigned devnum, unsigned endpoint,
        dbgp_set_data(bytes, size);
        writel(addr, &ehci_debug->address);
        writel(pids, &ehci_debug->pids);
-       ret = dbgp_wait_until_done(ctrl);
+       ret = dbgp_wait_until_done(ctrl, DBGP_LOOPS);
 
        return ret;
 }
 
 static int dbgp_bulk_read(unsigned devnum, unsigned endpoint, void *data,
-                                int size)
+                         int size, int loops)
 {
        u32 pids, addr, ctrl;
        int ret;
@@ -302,7 +312,7 @@ static int dbgp_bulk_read(unsigned devnum, unsigned endpoint, void *data,
 
        writel(addr, &ehci_debug->address);
        writel(pids, &ehci_debug->pids);
-       ret = dbgp_wait_until_done(ctrl);
+       ret = dbgp_wait_until_done(ctrl, loops);
        if (ret < 0)
                return ret;
 
@@ -343,12 +353,12 @@ static int dbgp_control_msg(unsigned devnum, int requesttype,
        dbgp_set_data(&req, sizeof(req));
        writel(addr, &ehci_debug->address);
        writel(pids, &ehci_debug->pids);
-       ret = dbgp_wait_until_done(ctrl);
+       ret = dbgp_wait_until_done(ctrl, DBGP_LOOPS);
        if (ret < 0)
                return ret;
 
        /* Read the result */
-       return dbgp_bulk_read(devnum, 0, data, size);
+       return dbgp_bulk_read(devnum, 0, data, size, DBGP_LOOPS);
 }
 
 /* Find a PCI capability */
@@ -559,6 +569,7 @@ try_again:
                goto err;
        }
        dbgp_endpoint_out = dbgp_desc.bDebugOutEndpoint;
+       dbgp_endpoint_in = dbgp_desc.bDebugInEndpoint;
 
        /* Move the device to 127 if it isn't already there */
        if (devnum != USB_DEBUG_DEVNUM) {
@@ -968,8 +979,9 @@ int dbgp_reset_prep(void)
        if (!ehci_debug)
                return 0;
 
-       if (early_dbgp_console.index != -1 &&
-               !(early_dbgp_console.flags & CON_BOOT))
+       if ((early_dbgp_console.index != -1 &&
+            !(early_dbgp_console.flags & CON_BOOT)) ||
+           dbgp_kgdb_mode)
                return 1;
        /* This means the console is not initialized, or should get
         * shutdown so as to allow for reuse of the usb device, which
@@ -982,3 +994,93 @@ int dbgp_reset_prep(void)
        return 0;
 }
 EXPORT_SYMBOL_GPL(dbgp_reset_prep);
+
+#ifdef CONFIG_KGDB
+
+static char kgdbdbgp_buf[DBGP_MAX_PACKET];
+static int kgdbdbgp_buf_sz;
+static int kgdbdbgp_buf_idx;
+static int kgdbdbgp_loop_cnt = DBGP_LOOPS;
+
+static int kgdbdbgp_read_char(void)
+{
+       int ret;
+
+       if (kgdbdbgp_buf_idx < kgdbdbgp_buf_sz) {
+               char ch = kgdbdbgp_buf[kgdbdbgp_buf_idx++];
+               return ch;
+       }
+
+       ret = dbgp_bulk_read(USB_DEBUG_DEVNUM, dbgp_endpoint_in,
+                            &kgdbdbgp_buf, DBGP_MAX_PACKET,
+                            kgdbdbgp_loop_cnt);
+       if (ret <= 0)
+               return NO_POLL_CHAR;
+       kgdbdbgp_buf_sz = ret;
+       kgdbdbgp_buf_idx = 1;
+       return kgdbdbgp_buf[0];
+}
+
+static void kgdbdbgp_write_char(u8 chr)
+{
+       early_dbgp_write(NULL, &chr, 1);
+}
+
+static struct kgdb_io kgdbdbgp_io_ops = {
+       .name = "kgdbdbgp",
+       .read_char = kgdbdbgp_read_char,
+       .write_char = kgdbdbgp_write_char,
+};
+
+static int kgdbdbgp_wait_time;
+
+static int __init kgdbdbgp_parse_config(char *str)
+{
+       char *ptr;
+
+       if (!ehci_debug) {
+               if (early_dbgp_init(str))
+                       return -1;
+       }
+       ptr = strchr(str, ',');
+       if (ptr) {
+               ptr++;
+               kgdbdbgp_wait_time = simple_strtoul(ptr, &ptr, 10);
+       }
+       kgdb_register_io_module(&kgdbdbgp_io_ops);
+       kgdbdbgp_io_ops.is_console = early_dbgp_console.index != -1;
+
+       return 0;
+}
+early_param("kgdbdbgp", kgdbdbgp_parse_config);
+
+static int kgdbdbgp_reader_thread(void *ptr)
+{
+       int ret;
+
+       while (readl(&ehci_debug->control) & DBGP_ENABLED) {
+               kgdbdbgp_loop_cnt = 1;
+               ret = kgdbdbgp_read_char();
+               kgdbdbgp_loop_cnt = DBGP_LOOPS;
+               if (ret != NO_POLL_CHAR) {
+                       if (ret == 0x3 || ret == '$') {
+                               if (ret == '$')
+                                       kgdbdbgp_buf_idx--;
+                               kgdb_breakpoint();
+                       }
+                       continue;
+               }
+               schedule_timeout_interruptible(kgdbdbgp_wait_time * HZ);
+       }
+       return 0;
+}
+
+static int __init kgdbdbgp_start_thread(void)
+{
+       if (dbgp_kgdb_mode && kgdbdbgp_wait_time)
+               kthread_run(kgdbdbgp_reader_thread, NULL, "%s", "dbgp");
+
+       return 0;
+}
+module_init(kgdbdbgp_start_thread);
+#endif /* CONFIG_KGDB */
index 6c784ab6856ac006803c52d7d064595262caf345..9340f34d1bb5e7af04ad247d119d341e9d5cd0a6 100644 (file)
@@ -207,6 +207,17 @@ extern int kgdb_validate_break_address(unsigned long addr);
 extern int kgdb_arch_set_breakpoint(unsigned long addr, char *saved_instr);
 extern int kgdb_arch_remove_breakpoint(unsigned long addr, char *bundle);
 
+/**
+ *     kgdb_arch_late - Perform any architecture specific initalization.
+ *
+ *     This function will handle the late initalization of any
+ *     architecture specific callbacks.  This is an optional function for
+ *     handling things like late initialization of hw breakpoints.  The
+ *     default implementation does nothing.
+ */
+extern void kgdb_arch_late(void);
+
+
 /**
  * struct kgdb_arch - Describe architecture specific values.
  * @gdb_bpt_instr: The instruction to trigger a breakpoint.
@@ -285,7 +296,10 @@ extern int                 kgdb_single_step;
 extern atomic_t                        kgdb_active;
 #define in_dbg_master() \
        (raw_smp_processor_id() == atomic_read(&kgdb_active))
+extern bool dbg_is_early;
+extern void __init dbg_late_init(void);
 #else /* ! CONFIG_KGDB */
 #define in_dbg_master() (0)
+#define dbg_late_init()
 #endif /* ! CONFIG_KGDB */
 #endif /* _KGDB_H_ */
index 372771333d983d1eb692032ac47db70ef080924c..22881b5e95e3b00e010b407310539fbd4e1a8a57 100644 (file)
@@ -62,7 +62,7 @@
 #include <linux/sched.h>
 #include <linux/signal.h>
 #include <linux/idr.h>
-#include <linux/kdb.h>
+#include <linux/kgdb.h>
 #include <linux/ftrace.h>
 #include <linux/async.h>
 #include <linux/kmemcheck.h>
@@ -676,7 +676,7 @@ asmlinkage void __init start_kernel(void)
        buffer_init();
        key_init();
        security_init();
-       kdb_init(KDB_INIT_FULL);
+       dbg_late_init();
        vfs_caches_init(totalram_pages);
        signals_init();
        /* rootfs populating might need page-writeback */
index 64b5588c96389228c01dca2932c0fb9625ca18a8..5cb7cd1de10c7dd5b3380f69d49854cb539a4011 100644 (file)
@@ -78,6 +78,8 @@ static DEFINE_SPINLOCK(kgdb_registration_lock);
 static int kgdb_con_registered;
 /* determine if kgdb console output should be used */
 static int kgdb_use_con;
+/* Flag for alternate operations for early debugging */
+bool dbg_is_early = true;
 /* Next cpu to become the master debug core */
 int dbg_switch_cpu;
 
@@ -777,11 +779,25 @@ static struct notifier_block kgdb_panic_event_nb = {
        .priority       = INT_MAX,
 };
 
+void __weak kgdb_arch_late(void)
+{
+}
+
+void __init dbg_late_init(void)
+{
+       dbg_is_early = false;
+       if (kgdb_io_module_registered)
+               kgdb_arch_late();
+       kdb_init(KDB_INIT_FULL);
+}
+
 static void kgdb_register_callbacks(void)
 {
        if (!kgdb_io_module_registered) {
                kgdb_io_module_registered = 1;
                kgdb_arch_init();
+               if (!dbg_is_early)
+                       kgdb_arch_late();
                atomic_notifier_chain_register(&panic_notifier_list,
                                               &kgdb_panic_event_nb);
 #ifdef CONFIG_MAGIC_SYSRQ