genirq: Prevent resend to interrupts marked IRQ_NESTED_THREAD
The resend mechanism happily calls the interrupt handler of interrupts which are marked IRQ_NESTED_THREAD from softirq context. This can result in crashes because the interrupt handler is not the proper way to invoke the device handlers. They must be invoked via handle_nested_irq. Prevent the resend even if the interrupt has no valid parent irq set. Its better to have a lost interrupt than a crashing machine. Reported-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Cc: stable@vger.kernel.org
This commit is contained in:
parent
ce0d3c0a6f
commit
75a06189fc
1 changed files with 13 additions and 5 deletions
|
@ -75,13 +75,21 @@ void check_irq_resend(struct irq_desc *desc, unsigned int irq)
|
||||||
!desc->irq_data.chip->irq_retrigger(&desc->irq_data)) {
|
!desc->irq_data.chip->irq_retrigger(&desc->irq_data)) {
|
||||||
#ifdef CONFIG_HARDIRQS_SW_RESEND
|
#ifdef CONFIG_HARDIRQS_SW_RESEND
|
||||||
/*
|
/*
|
||||||
* If the interrupt has a parent irq and runs
|
* If the interrupt is running in the thread
|
||||||
* in the thread context of the parent irq,
|
* context of the parent irq we need to be
|
||||||
* retrigger the parent.
|
* careful, because we cannot trigger it
|
||||||
|
* directly.
|
||||||
*/
|
*/
|
||||||
if (desc->parent_irq &&
|
if (irq_settings_is_nested_thread(desc)) {
|
||||||
irq_settings_is_nested_thread(desc))
|
/*
|
||||||
|
* If the parent_irq is valid, we
|
||||||
|
* retrigger the parent, otherwise we
|
||||||
|
* do nothing.
|
||||||
|
*/
|
||||||
|
if (!desc->parent_irq)
|
||||||
|
return;
|
||||||
irq = desc->parent_irq;
|
irq = desc->parent_irq;
|
||||||
|
}
|
||||||
/* Set it pending and activate the softirq: */
|
/* Set it pending and activate the softirq: */
|
||||||
set_bit(irq, irqs_resend);
|
set_bit(irq, irqs_resend);
|
||||||
tasklet_schedule(&resend_tasklet);
|
tasklet_schedule(&resend_tasklet);
|
||||||
|
|
Loading…
Reference in a new issue