Skip to content

Commit 5eb0d6e

Browse files
Boris BrezillonKAGA-KOKO
authored andcommitted
irqchip/atmel-aic: Fix potential deadlock in ->xlate()
aic5_irq_domain_xlate() and aic_irq_domain_xlate() take the generic chip lock without disabling interrupts, which can lead to a deadlock if an interrupt occurs while the lock is held in one of these functions. Replace irq_gc_{lock,unlock}() calls by irq_gc_{lock_irqsave,unlock_irqrestore}() ones to prevent this bug from happening. Fixes: b1479eb ("irqchip: atmel-aic: Add atmel AIC/AIC5 drivers") Signed-off-by: Boris Brezillon <[email protected]> Acked-by: Marc Zyngier <[email protected]> Cc: Jason Cooper <[email protected]> Cc: Nicolas Ferre <[email protected]> Cc: [email protected] Cc: Alexandre Belloni <[email protected]> Link: http://lkml.kernel.org/r/1473775109-4192-2-git-send-email-boris.brezillon@free-electrons.com Signed-off-by: Thomas Gleixner <[email protected]>
1 parent ebf9ff7 commit 5eb0d6e

File tree

2 files changed

+6
-4
lines changed

2 files changed

+6
-4
lines changed

drivers/irqchip/irq-atmel-aic.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,7 @@ static int aic_irq_domain_xlate(struct irq_domain *d,
176176
{
177177
struct irq_domain_chip_generic *dgc = d->gc;
178178
struct irq_chip_generic *gc;
179+
unsigned long flags;
179180
unsigned smr;
180181
int idx;
181182
int ret;
@@ -194,11 +195,11 @@ static int aic_irq_domain_xlate(struct irq_domain *d,
194195

195196
gc = dgc->gc[idx];
196197

197-
irq_gc_lock(gc);
198+
irq_gc_lock_irqsave(gc, flags);
198199
smr = irq_reg_readl(gc, AT91_AIC_SMR(*out_hwirq));
199200
aic_common_set_priority(intspec[2], &smr);
200201
irq_reg_writel(gc, smr, AT91_AIC_SMR(*out_hwirq));
201-
irq_gc_unlock(gc);
202+
irq_gc_unlock_irqrestore(gc, flags);
202203

203204
return ret;
204205
}

drivers/irqchip/irq-atmel-aic5.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,7 @@ static int aic5_irq_domain_xlate(struct irq_domain *d,
258258
unsigned int *out_type)
259259
{
260260
struct irq_chip_generic *bgc = irq_get_domain_generic_chip(d, 0);
261+
unsigned long flags;
261262
unsigned smr;
262263
int ret;
263264

@@ -269,12 +270,12 @@ static int aic5_irq_domain_xlate(struct irq_domain *d,
269270
if (ret)
270271
return ret;
271272

272-
irq_gc_lock(bgc);
273+
irq_gc_lock_irqsave(bgc, flags);
273274
irq_reg_writel(bgc, *out_hwirq, AT91_AIC5_SSR);
274275
smr = irq_reg_readl(bgc, AT91_AIC5_SMR);
275276
aic_common_set_priority(intspec[2], &smr);
276277
irq_reg_writel(bgc, smr, AT91_AIC5_SMR);
277-
irq_gc_unlock(bgc);
278+
irq_gc_unlock_irqrestore(bgc, flags);
278279

279280
return ret;
280281
}

0 commit comments

Comments
 (0)