return 0;
 }
 
+#ifdef CONFIG_KGDB_KDB
+void kdb_dump_stack_on_cpu(int cpu)
+{
+       if (cpu == raw_smp_processor_id()) {
+               dump_stack();
+               return;
+       }
+
+       if (!(kgdb_info[cpu].exception_state & DCPU_IS_SLAVE)) {
+               kdb_printf("ERROR: Task on cpu %d didn't stop in the debugger\n",
+                          cpu);
+               return;
+       }
+
+       /*
+        * In general, architectures don't support dumping the stack of a
+        * "running" process that's not the current one.  From the point of
+        * view of the Linux, kernel processes that are looping in the kgdb
+        * slave loop are still "running".  There's also no API (that actually
+        * works across all architectures) that can do a stack crawl based
+        * on registers passed as a parameter.
+        *
+        * Solve this conundrum by asking slave CPUs to do the backtrace
+        * themselves.
+        */
+       kgdb_info[cpu].exception_state |= DCPU_WANT_BT;
+       while (kgdb_info[cpu].exception_state & DCPU_WANT_BT)
+               cpu_relax();
+}
+#endif
+
 /*
  * Return true if there is a valid kgdb I/O module.  Also if no
  * debugger is attached a message can be printed to the console about
                                atomic_xchg(&kgdb_active, cpu);
                                break;
                        }
+               } else if (kgdb_info[cpu].exception_state & DCPU_WANT_BT) {
+                       dump_stack();
+                       kgdb_info[cpu].exception_state &= ~DCPU_WANT_BT;
                } else if (kgdb_info[cpu].exception_state & DCPU_IS_SLAVE) {
                        if (!raw_spin_is_locked(&dbg_slave_lock))
                                goto return_normal;
 
 #define DCPU_WANT_MASTER 0x1 /* Waiting to become a master kgdb cpu */
 #define DCPU_NEXT_MASTER 0x2 /* Transition from one master cpu to another */
 #define DCPU_IS_SLAVE    0x4 /* Slave cpu enter exception */
+#define DCPU_WANT_BT     0x8 /* Slave cpu should backtrace then clear flag */
 
 struct debuggerinfo_struct {
        void                    *debuggerinfo;
 extern int kdb_parse(const char *cmdstr);
 extern int kdb_common_init_state(struct kgdb_state *ks);
 extern int kdb_common_deinit_state(void);
+extern void kdb_dump_stack_on_cpu(int cpu);
 #else /* ! CONFIG_KGDB_KDB */
 static inline int kdb_stub(struct kgdb_state *ks)
 {
 
 static void kdb_show_stack(struct task_struct *p, void *addr)
 {
        int old_lvl = console_loglevel;
+
        console_loglevel = CONSOLE_LOGLEVEL_MOTORMOUTH;
        kdb_trap_printk++;
-       kdb_set_current_task(p);
-       if (addr) {
-               show_stack((struct task_struct *)p, addr);
-       } else if (kdb_current_regs) {
-#ifdef CONFIG_X86
-               show_stack(p, &kdb_current_regs->sp);
-#else
-               show_stack(p, NULL);
-#endif
-       } else {
-               show_stack(p, NULL);
-       }
+
+       if (!addr && kdb_task_has_cpu(p))
+               kdb_dump_stack_on_cpu(kdb_process_cpu(p));
+       else
+               show_stack(p, addr);
+
        console_loglevel = old_lvl;
        kdb_trap_printk--;
 }