aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/kernel/gdb-stub.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/kernel/gdb-stub.c')
-rw-r--r--arch/mips/kernel/gdb-stub.c61
1 files changed, 60 insertions, 1 deletions
diff --git a/arch/mips/kernel/gdb-stub.c b/arch/mips/kernel/gdb-stub.c
index d4f88e0af24c..6ecbdc1fefd1 100644
--- a/arch/mips/kernel/gdb-stub.c
+++ b/arch/mips/kernel/gdb-stub.c
@@ -140,6 +140,7 @@
140#include <asm/system.h> 140#include <asm/system.h>
141#include <asm/gdb-stub.h> 141#include <asm/gdb-stub.h>
142#include <asm/inst.h> 142#include <asm/inst.h>
143#include <asm/smp.h>
143 144
144/* 145/*
145 * external low-level support routines 146 * external low-level support routines
@@ -669,6 +670,64 @@ static void kgdb_wait(void *arg)
669 local_irq_restore(flags); 670 local_irq_restore(flags);
670} 671}
671 672
673/*
674 * GDB stub needs to call kgdb_wait on all processor with interrupts
675 * disabled, so it uses it's own special variant.
676 */
677static int kgdb_smp_call_kgdb_wait(void)
678{
679#ifdef CONFIG_SMP
680 struct call_data_struct data;
681 int i, cpus = num_online_cpus() - 1;
682 int cpu = smp_processor_id();
683
684 /*
685 * Can die spectacularly if this CPU isn't yet marked online
686 */
687 BUG_ON(!cpu_online(cpu));
688
689 if (!cpus)
690 return 0;
691
692 if (spin_is_locked(&smp_call_lock)) {
693 /*
694 * Some other processor is trying to make us do something
695 * but we're not going to respond... give up
696 */
697 return -1;
698 }
699
700 /*
701 * We will continue here, accepting the fact that
702 * the kernel may deadlock if another CPU attempts
703 * to call smp_call_function now...
704 */
705
706 data.func = kgdb_wait;
707 data.info = NULL;
708 atomic_set(&data.started, 0);
709 data.wait = 0;
710
711 spin_lock(&smp_call_lock);
712 call_data = &data;
713 mb();
714
715 /* Send a message to all other CPUs and wait for them to respond */
716 for (i = 0; i < NR_CPUS; i++)
717 if (cpu_online(i) && i != cpu)
718 core_send_ipi(i, SMP_CALL_FUNCTION);
719
720 /* Wait for response */
721 /* FIXME: lock-up detection, backtrace on lock-up */
722 while (atomic_read(&data.started) != cpus)
723 barrier();
724
725 call_data = NULL;
726 spin_unlock(&smp_call_lock);
727#endif
728
729 return 0;
730}
672 731
673/* 732/*
674 * This function does all command processing for interfacing to gdb. It 733 * This function does all command processing for interfacing to gdb. It
@@ -718,7 +777,7 @@ void handle_exception (struct gdb_regs *regs)
718 /* 777 /*
719 * force other cpus to enter kgdb 778 * force other cpus to enter kgdb
720 */ 779 */
721 smp_call_function(kgdb_wait, NULL, 0, 0); 780 kgdb_smp_call_kgdb_wait();
722 781
723 /* 782 /*
724 * If we're in breakpoint() increment the PC 783 * If we're in breakpoint() increment the PC