* [PATCH v3 1/2] genirq: Provide irq_gc_{lock_irqsave,unlock_irqrestore}() helpers
@ 2016-09-13 13:58 Boris Brezillon
2016-09-13 13:58 ` [PATCH v3 2/2] irqchip/atmel-aic: Fix potential deadlock in ->xlate() Boris Brezillon
2016-09-13 15:04 ` [tip:irq/urgent] genirq: Provide irq_gc_{lock_irqsave,unlock_irqrestore}() helpers tip-bot for Boris Brezillon
0 siblings, 2 replies; 5+ messages in thread
From: Boris Brezillon @ 2016-09-13 13:58 UTC (permalink / raw)
To: Thomas Gleixner, Jason Cooper, Marc Zyngier
Cc: Nicolas Ferre, Alexandre Belloni, linux-kernel, Boris Brezillon,
stable
Some irqchip drivers need to take the generic chip lock outside of the
irq context.
Provide the irq_gc_{lock_irqsave,unlock_irqrestore}() helpers to allow
one to disable irqs while entering a critical section protected by
gc->lock.
Note that we do not provide optimized version of these helpers for !SMP,
because they are not called from the hot-path.
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
Cc: <stable@vger.kernel.org>
---
include/linux/irq.h | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/include/linux/irq.h b/include/linux/irq.h
index b52424eaa0ed..b13668f97648 100644
--- a/include/linux/irq.h
+++ b/include/linux/irq.h
@@ -945,6 +945,12 @@ static inline void irq_gc_lock(struct irq_chip_generic *gc) { }
static inline void irq_gc_unlock(struct irq_chip_generic *gc) { }
#endif
+#define irq_gc_lock_irqsave(gc, flags) \
+ raw_spin_lock_irqsave(&(gc)->lock, flags)
+
+#define irq_gc_unlock_irqrestore(gc, flags) \
+ raw_spin_unlock_irqrestore(&(gc)->lock, flags)
+
static inline void irq_reg_writel(struct irq_chip_generic *gc,
u32 val, int reg_offset)
{
--
2.7.4
^ permalink raw reply related [flat|nested] 5+ messages in thread* [PATCH v3 2/2] irqchip/atmel-aic: Fix potential deadlock in ->xlate() 2016-09-13 13:58 [PATCH v3 1/2] genirq: Provide irq_gc_{lock_irqsave,unlock_irqrestore}() helpers Boris Brezillon @ 2016-09-13 13:58 ` Boris Brezillon 2016-09-13 14:15 ` Boris Brezillon 2016-09-13 15:04 ` [tip:irq/urgent] " tip-bot for Boris Brezillon 2016-09-13 15:04 ` [tip:irq/urgent] genirq: Provide irq_gc_{lock_irqsave,unlock_irqrestore}() helpers tip-bot for Boris Brezillon 1 sibling, 2 replies; 5+ messages in thread From: Boris Brezillon @ 2016-09-13 13:58 UTC (permalink / raw) To: Thomas Gleixner, Jason Cooper, Marc Zyngier Cc: Nicolas Ferre, Alexandre Belloni, linux-kernel, Boris Brezillon, stable 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 raw_spin_{lock_irqsave,unlock_irqrestore}() ones to prevent this bug from happening. Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com> Fixes: b1479ebb7720 ("irqchip: atmel-aic: Add atmel AIC/AIC5 drivers") Cc: <stable@vger.kernel.org> Acked-by: Marc Zyngier <marc.zyngier@arm.com> --- Changes in v3: - introduce and use the irq_gc_{lock_irqsave,unlock_irqrestore}() helpers Changes in v2: - add Marc's ack - fix stable ML address fixup! irqchip/atmel-aic: Fix potential deadlock in ->xlate() --- drivers/irqchip/irq-atmel-aic.c | 5 +++-- drivers/irqchip/irq-atmel-aic5.c | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/irqchip/irq-atmel-aic.c b/drivers/irqchip/irq-atmel-aic.c index 112e17c2768b..37f952dd9fc9 100644 --- a/drivers/irqchip/irq-atmel-aic.c +++ b/drivers/irqchip/irq-atmel-aic.c @@ -176,6 +176,7 @@ static int aic_irq_domain_xlate(struct irq_domain *d, { struct irq_domain_chip_generic *dgc = d->gc; struct irq_chip_generic *gc; + unsigned long flags; unsigned smr; int idx; int ret; @@ -194,11 +195,11 @@ static int aic_irq_domain_xlate(struct irq_domain *d, gc = dgc->gc[idx]; - irq_gc_lock(gc); + irq_gc_lock_irqsave(gc, flags); smr = irq_reg_readl(gc, AT91_AIC_SMR(*out_hwirq)); aic_common_set_priority(intspec[2], &smr); irq_reg_writel(gc, smr, AT91_AIC_SMR(*out_hwirq)); - irq_gc_unlock(gc); + irq_gc_unlock_irqrestore(gc, flags); return ret; } diff --git a/drivers/irqchip/irq-atmel-aic5.c b/drivers/irqchip/irq-atmel-aic5.c index 4f0d068e1abe..2a624d87a035 100644 --- a/drivers/irqchip/irq-atmel-aic5.c +++ b/drivers/irqchip/irq-atmel-aic5.c @@ -258,6 +258,7 @@ static int aic5_irq_domain_xlate(struct irq_domain *d, unsigned int *out_type) { struct irq_chip_generic *bgc = irq_get_domain_generic_chip(d, 0); + unsigned long flags; unsigned smr; int ret; @@ -269,12 +270,12 @@ static int aic5_irq_domain_xlate(struct irq_domain *d, if (ret) return ret; - irq_gc_lock(bgc); + irq_gc_lock_irqsave(bgc, flags); irq_reg_writel(bgc, *out_hwirq, AT91_AIC5_SSR); smr = irq_reg_readl(bgc, AT91_AIC5_SMR); aic_common_set_priority(intspec[2], &smr); irq_reg_writel(bgc, smr, AT91_AIC5_SMR); - irq_gc_unlock(bgc); + irq_gc_unlock_irqrestore(bgc, flags); return ret; } -- 2.7.4 ^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH v3 2/2] irqchip/atmel-aic: Fix potential deadlock in ->xlate() 2016-09-13 13:58 ` [PATCH v3 2/2] irqchip/atmel-aic: Fix potential deadlock in ->xlate() Boris Brezillon @ 2016-09-13 14:15 ` Boris Brezillon 2016-09-13 15:04 ` [tip:irq/urgent] " tip-bot for Boris Brezillon 1 sibling, 0 replies; 5+ messages in thread From: Boris Brezillon @ 2016-09-13 14:15 UTC (permalink / raw) To: Thomas Gleixner, Jason Cooper, Marc Zyngier Cc: Nicolas Ferre, Alexandre Belloni, linux-kernel, stable On Tue, 13 Sep 2016 15:58:29 +0200 Boris Brezillon <boris.brezillon@free-electrons.com> wrote: > 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 > raw_spin_{lock_irqsave,unlock_irqrestore}() ones to prevent this bug from Sorry, I forgot to update my commit message: s/raw_spin_/irq_gc_/. Thomas, can you fix that when applying, or should I send a new version? > happening. > > Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com> > Fixes: b1479ebb7720 ("irqchip: atmel-aic: Add atmel AIC/AIC5 drivers") > Cc: <stable@vger.kernel.org> > Acked-by: Marc Zyngier <marc.zyngier@arm.com> > --- > Changes in v3: > - introduce and use the irq_gc_{lock_irqsave,unlock_irqrestore}() helpers > > Changes in v2: > - add Marc's ack > - fix stable ML address > > fixup! irqchip/atmel-aic: Fix potential deadlock in ->xlate() > --- > drivers/irqchip/irq-atmel-aic.c | 5 +++-- > drivers/irqchip/irq-atmel-aic5.c | 5 +++-- > 2 files changed, 6 insertions(+), 4 deletions(-) > > diff --git a/drivers/irqchip/irq-atmel-aic.c b/drivers/irqchip/irq-atmel-aic.c > index 112e17c2768b..37f952dd9fc9 100644 > --- a/drivers/irqchip/irq-atmel-aic.c > +++ b/drivers/irqchip/irq-atmel-aic.c > @@ -176,6 +176,7 @@ static int aic_irq_domain_xlate(struct irq_domain *d, > { > struct irq_domain_chip_generic *dgc = d->gc; > struct irq_chip_generic *gc; > + unsigned long flags; > unsigned smr; > int idx; > int ret; > @@ -194,11 +195,11 @@ static int aic_irq_domain_xlate(struct irq_domain *d, > > gc = dgc->gc[idx]; > > - irq_gc_lock(gc); > + irq_gc_lock_irqsave(gc, flags); > smr = irq_reg_readl(gc, AT91_AIC_SMR(*out_hwirq)); > aic_common_set_priority(intspec[2], &smr); > irq_reg_writel(gc, smr, AT91_AIC_SMR(*out_hwirq)); > - irq_gc_unlock(gc); > + irq_gc_unlock_irqrestore(gc, flags); > > return ret; > } > diff --git a/drivers/irqchip/irq-atmel-aic5.c b/drivers/irqchip/irq-atmel-aic5.c > index 4f0d068e1abe..2a624d87a035 100644 > --- a/drivers/irqchip/irq-atmel-aic5.c > +++ b/drivers/irqchip/irq-atmel-aic5.c > @@ -258,6 +258,7 @@ static int aic5_irq_domain_xlate(struct irq_domain *d, > unsigned int *out_type) > { > struct irq_chip_generic *bgc = irq_get_domain_generic_chip(d, 0); > + unsigned long flags; > unsigned smr; > int ret; > > @@ -269,12 +270,12 @@ static int aic5_irq_domain_xlate(struct irq_domain *d, > if (ret) > return ret; > > - irq_gc_lock(bgc); > + irq_gc_lock_irqsave(bgc, flags); > irq_reg_writel(bgc, *out_hwirq, AT91_AIC5_SSR); > smr = irq_reg_readl(bgc, AT91_AIC5_SMR); > aic_common_set_priority(intspec[2], &smr); > irq_reg_writel(bgc, smr, AT91_AIC5_SMR); > - irq_gc_unlock(bgc); > + irq_gc_unlock_irqrestore(bgc, flags); > > return ret; > } ^ permalink raw reply [flat|nested] 5+ messages in thread
* [tip:irq/urgent] irqchip/atmel-aic: Fix potential deadlock in ->xlate() 2016-09-13 13:58 ` [PATCH v3 2/2] irqchip/atmel-aic: Fix potential deadlock in ->xlate() Boris Brezillon 2016-09-13 14:15 ` Boris Brezillon @ 2016-09-13 15:04 ` tip-bot for Boris Brezillon 1 sibling, 0 replies; 5+ messages in thread From: tip-bot for Boris Brezillon @ 2016-09-13 15:04 UTC (permalink / raw) To: linux-tip-commits Cc: hpa, linux-kernel, nicolas.ferre, jason, tglx, marc.zyngier, mingo, boris.brezillon, alexandre.belloni Commit-ID: 5eb0d6eb3fac3daa60d9190eed9fa41cf809c756 Gitweb: http://git.kernel.org/tip/5eb0d6eb3fac3daa60d9190eed9fa41cf809c756 Author: Boris Brezillon <boris.brezillon@free-electrons.com> AuthorDate: Tue, 13 Sep 2016 15:58:29 +0200 Committer: Thomas Gleixner <tglx@linutronix.de> CommitDate: Tue, 13 Sep 2016 16:57:40 +0200 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: b1479ebb7720 ("irqchip: atmel-aic: Add atmel AIC/AIC5 drivers") Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com> Acked-by: Marc Zyngier <marc.zyngier@arm.com> Cc: Jason Cooper <jason@lakedaemon.net> Cc: Nicolas Ferre <nicolas.ferre@atmel.com> Cc: stable@vger.kernel.org Cc: Alexandre Belloni <alexandre.belloni@free-electrons.com> Link: http://lkml.kernel.org/r/1473775109-4192-2-git-send-email-boris.brezillon@free-electrons.com Signed-off-by: Thomas Gleixner <tglx@linutronix.de> --- drivers/irqchip/irq-atmel-aic.c | 5 +++-- drivers/irqchip/irq-atmel-aic5.c | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/irqchip/irq-atmel-aic.c b/drivers/irqchip/irq-atmel-aic.c index 112e17c..37f952d 100644 --- a/drivers/irqchip/irq-atmel-aic.c +++ b/drivers/irqchip/irq-atmel-aic.c @@ -176,6 +176,7 @@ static int aic_irq_domain_xlate(struct irq_domain *d, { struct irq_domain_chip_generic *dgc = d->gc; struct irq_chip_generic *gc; + unsigned long flags; unsigned smr; int idx; int ret; @@ -194,11 +195,11 @@ static int aic_irq_domain_xlate(struct irq_domain *d, gc = dgc->gc[idx]; - irq_gc_lock(gc); + irq_gc_lock_irqsave(gc, flags); smr = irq_reg_readl(gc, AT91_AIC_SMR(*out_hwirq)); aic_common_set_priority(intspec[2], &smr); irq_reg_writel(gc, smr, AT91_AIC_SMR(*out_hwirq)); - irq_gc_unlock(gc); + irq_gc_unlock_irqrestore(gc, flags); return ret; } diff --git a/drivers/irqchip/irq-atmel-aic5.c b/drivers/irqchip/irq-atmel-aic5.c index 4f0d068..2a624d8 100644 --- a/drivers/irqchip/irq-atmel-aic5.c +++ b/drivers/irqchip/irq-atmel-aic5.c @@ -258,6 +258,7 @@ static int aic5_irq_domain_xlate(struct irq_domain *d, unsigned int *out_type) { struct irq_chip_generic *bgc = irq_get_domain_generic_chip(d, 0); + unsigned long flags; unsigned smr; int ret; @@ -269,12 +270,12 @@ static int aic5_irq_domain_xlate(struct irq_domain *d, if (ret) return ret; - irq_gc_lock(bgc); + irq_gc_lock_irqsave(bgc, flags); irq_reg_writel(bgc, *out_hwirq, AT91_AIC5_SSR); smr = irq_reg_readl(bgc, AT91_AIC5_SMR); aic_common_set_priority(intspec[2], &smr); irq_reg_writel(bgc, smr, AT91_AIC5_SMR); - irq_gc_unlock(bgc); + irq_gc_unlock_irqrestore(bgc, flags); return ret; } ^ permalink raw reply related [flat|nested] 5+ messages in thread
* [tip:irq/urgent] genirq: Provide irq_gc_{lock_irqsave,unlock_irqrestore}() helpers 2016-09-13 13:58 [PATCH v3 1/2] genirq: Provide irq_gc_{lock_irqsave,unlock_irqrestore}() helpers Boris Brezillon 2016-09-13 13:58 ` [PATCH v3 2/2] irqchip/atmel-aic: Fix potential deadlock in ->xlate() Boris Brezillon @ 2016-09-13 15:04 ` tip-bot for Boris Brezillon 1 sibling, 0 replies; 5+ messages in thread From: tip-bot for Boris Brezillon @ 2016-09-13 15:04 UTC (permalink / raw) To: linux-tip-commits Cc: mingo, boris.brezillon, jason, hpa, linux-kernel, nicolas.ferre, alexandre.belloni, marc.zyngier, tglx Commit-ID: ebf9ff753c041b296241990aef76163bbb2cc9c8 Gitweb: http://git.kernel.org/tip/ebf9ff753c041b296241990aef76163bbb2cc9c8 Author: Boris Brezillon <boris.brezillon@free-electrons.com> AuthorDate: Tue, 13 Sep 2016 15:58:28 +0200 Committer: Thomas Gleixner <tglx@linutronix.de> CommitDate: Tue, 13 Sep 2016 16:57:40 +0200 genirq: Provide irq_gc_{lock_irqsave,unlock_irqrestore}() helpers Some irqchip drivers need to take the generic chip lock outside of the irq context. Provide the irq_gc_{lock_irqsave,unlock_irqrestore}() helpers to allow one to disable irqs while entering a critical section protected by gc->lock. Note that we do not provide optimized version of these helpers for !SMP, because they are not called from the hot-path. [ tglx: Added a comment when these helpers should be [not] used ] Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com> Cc: Jason Cooper <jason@lakedaemon.net> Cc: Marc Zyngier <marc.zyngier@arm.com> Cc: Nicolas Ferre <nicolas.ferre@atmel.com> Cc: stable@vger.kernel.org Cc: Alexandre Belloni <alexandre.belloni@free-electrons.com> Link: http://lkml.kernel.org/r/1473775109-4192-1-git-send-email-boris.brezillon@free-electrons.com Signed-off-by: Thomas Gleixner <tglx@linutronix.de> --- include/linux/irq.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/include/linux/irq.h b/include/linux/irq.h index b52424e..0ac26c8 100644 --- a/include/linux/irq.h +++ b/include/linux/irq.h @@ -945,6 +945,16 @@ static inline void irq_gc_lock(struct irq_chip_generic *gc) { } static inline void irq_gc_unlock(struct irq_chip_generic *gc) { } #endif +/* + * The irqsave variants are for usage in non interrupt code. Do not use + * them in irq_chip callbacks. Use irq_gc_lock() instead. + */ +#define irq_gc_lock_irqsave(gc, flags) \ + raw_spin_lock_irqsave(&(gc)->lock, flags) + +#define irq_gc_unlock_irqrestore(gc, flags) \ + raw_spin_unlock_irqrestore(&(gc)->lock, flags) + static inline void irq_reg_writel(struct irq_chip_generic *gc, u32 val, int reg_offset) { ^ permalink raw reply related [flat|nested] 5+ messages in thread
end of thread, other threads:[~2016-09-13 15:04 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-09-13 13:58 [PATCH v3 1/2] genirq: Provide irq_gc_{lock_irqsave,unlock_irqrestore}() helpers Boris Brezillon
2016-09-13 13:58 ` [PATCH v3 2/2] irqchip/atmel-aic: Fix potential deadlock in ->xlate() Boris Brezillon
2016-09-13 14:15 ` Boris Brezillon
2016-09-13 15:04 ` [tip:irq/urgent] " tip-bot for Boris Brezillon
2016-09-13 15:04 ` [tip:irq/urgent] genirq: Provide irq_gc_{lock_irqsave,unlock_irqrestore}() helpers tip-bot for Boris Brezillon
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.