diff options
Diffstat (limited to 'arch/arm/kernel/kgdb.c')
-rw-r--r-- | arch/arm/kernel/kgdb.c | 24 |
1 files changed, 18 insertions, 6 deletions
diff --git a/arch/arm/kernel/kgdb.c b/arch/arm/kernel/kgdb.c index 07db2f8a1b45..fe9dc24567b2 100644 --- a/arch/arm/kernel/kgdb.c +++ b/arch/arm/kernel/kgdb.c @@ -179,14 +179,26 @@ static struct undef_hook kgdb_compiled_brkpt_hook = { static void kgdb_call_nmi_hook(void *ignored) { - kgdb_nmicallback(raw_smp_processor_id(), get_irq_regs()); + kgdb_nmicallback(raw_smp_processor_id(), get_irq_regs()); } void kgdb_roundup_cpus(unsigned long flags) { - local_irq_enable(); - smp_call_function(kgdb_call_nmi_hook, NULL, 0); - local_irq_disable(); +#if defined CONFIG_KGDB_FIQ && defined CONFIG_SMP + struct cpumask mask; + + if (in_nmi()) { + cpumask_copy(&mask, cpu_online_mask); + cpumask_clear_cpu(raw_smp_processor_id(), &mask); + if (!cpumask_empty(&mask)) + send_nmi_ipi_mask(&mask); + return; + } +#endif + + local_irq_enable(); + smp_call_function(kgdb_call_nmi_hook, NULL, 0); + local_irq_disable(); } static int __kgdb_notify(struct die_args *args, unsigned long cmd) @@ -281,8 +293,8 @@ int kgdb_arch_remove_breakpoint(struct kgdb_bkpt *bpt) */ struct kgdb_arch arch_kgdb_ops = { #ifndef __ARMEB__ - .gdb_bpt_instr = {0xfe, 0xde, 0xff, 0xe7} + .gdb_bpt_instr = {0xfe, 0xde, 0xff, 0xe7}, #else /* ! __ARMEB__ */ - .gdb_bpt_instr = {0xe7, 0xff, 0xde, 0xfe} + .gdb_bpt_instr = {0xe7, 0xff, 0xde, 0xfe}, #endif }; |