Skip to content

Commit 9141a00

Browse files
wildea01Russell King
authored andcommitted
ARM: 7316/1: kexec: EOI active and mask all interrupts in kexec crash path
The kexec machine crash code can be called in interrupt context via a sysrq trigger made using the magic key combination. If the irq chip dealing with the serial interrupt is using the fasteoi flow handler, then we will never EOI the interrupt because the interrupt handler will be fatal. In the case of a GIC, this results in the crash kernel not receiving interrupts on that CPU interface. This patch adds code (based on the PowerPC implementation) to EOI any pending interrupts on the crash CPU before masking and disabling all interrupts. Secondary cores are not a problem since they are placed into a cpu_relax() loop via an IPI. Reported-by: Lei Wen <[email protected]> Signed-off-by: Will Deacon <[email protected]> Signed-off-by: Russell King <[email protected]>
1 parent ba81f50 commit 9141a00

File tree

1 file changed

+25
-0
lines changed

1 file changed

+25
-0
lines changed

arch/arm/kernel/machine_kexec.c

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include <linux/delay.h>
88
#include <linux/reboot.h>
99
#include <linux/io.h>
10+
#include <linux/irq.h>
1011
#include <asm/pgtable.h>
1112
#include <asm/pgalloc.h>
1213
#include <asm/mmu_context.h>
@@ -53,6 +54,29 @@ void machine_crash_nonpanic_core(void *unused)
5354
cpu_relax();
5455
}
5556

57+
static void machine_kexec_mask_interrupts(void)
58+
{
59+
unsigned int i;
60+
struct irq_desc *desc;
61+
62+
for_each_irq_desc(i, desc) {
63+
struct irq_chip *chip;
64+
65+
chip = irq_desc_get_chip(desc);
66+
if (!chip)
67+
continue;
68+
69+
if (chip->irq_eoi && irqd_irq_inprogress(&desc->irq_data))
70+
chip->irq_eoi(&desc->irq_data);
71+
72+
if (chip->irq_mask)
73+
chip->irq_mask(&desc->irq_data);
74+
75+
if (chip->irq_disable && !irqd_irq_disabled(&desc->irq_data))
76+
chip->irq_disable(&desc->irq_data);
77+
}
78+
}
79+
5680
void machine_crash_shutdown(struct pt_regs *regs)
5781
{
5882
unsigned long msecs;
@@ -70,6 +94,7 @@ void machine_crash_shutdown(struct pt_regs *regs)
7094
printk(KERN_WARNING "Non-crashing CPUs did not react to IPI\n");
7195

7296
crash_save_cpu(regs, smp_processor_id());
97+
machine_kexec_mask_interrupts();
7398

7499
printk(KERN_INFO "Loading crashdump kernel...\n");
75100
}

0 commit comments

Comments
 (0)