diff options
Diffstat (limited to 'arch/arm/kernel')
-rw-r--r-- | arch/arm/kernel/smp.c | 6 | ||||
-rw-r--r-- | arch/arm/kernel/traps.c | 11 |
2 files changed, 16 insertions, 1 deletions
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c index baee70267f29..631c5e53e286 100644 --- a/arch/arm/kernel/smp.c +++ b/arch/arm/kernel/smp.c @@ -644,6 +644,11 @@ void handle_IPI(int ipinr, struct pt_regs *regs) break; case IPI_CPU_BACKTRACE: + if (in_nmi()) { + nmi_cpu_backtrace(regs); + break; + } + irq_enter(); nmi_cpu_backtrace(regs); irq_exit(); @@ -755,6 +760,7 @@ static void raise_nmi(cpumask_t *mask) if (cpumask_test_cpu(smp_processor_id(), mask) && irqs_disabled()) nmi_cpu_backtrace(NULL); + BUILD_BUG_ON(SMP_IPI_FIQ_MASK != BIT(IPI_CPU_BACKTRACE)); smp_cross_call(mask, IPI_CPU_BACKTRACE); } diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c index bc698383e822..8f6173cd0a54 100644 --- a/arch/arm/kernel/traps.c +++ b/arch/arm/kernel/traps.c @@ -479,7 +479,16 @@ asmlinkage void __exception_irq_entry handle_fiq_as_nmi(struct pt_regs *regs) nmi_enter(); - /* nop. FIQ handlers for special arch/arm features can be added here. */ + /* + * Either the interrupt controller supports FIQ, meaning it will + * do the right thing with this call, or we will end up treating a + * spurious FIQ (which is normally fatal) as though it were an IRQ + * which, although it risks deadlock, still gives us a sporting + * chance of surviving long enough to log errors. + */ +#ifdef CONFIG_MULTI_IRQ_HANDLER + handle_arch_irq(regs); +#endif nmi_exit(); |