All of lore.kernel.org
 help / color / mirror / Atom feed
From: Alexandre Courbot <acourbot@nvidia.com>
To: Linus Walleij <linus.walleij@linaro.org>
Cc: linux-gpio@vger.kernel.org, linux-kernel@vger.kernel.org,
	ldv-project@linuxtesting.org, gnurou@gmail.com,
	Alexandre Courbot <acourbot@nvidia.com>,
	Alexey Khoroshilov <khoroshilov@ispras.ru>,
	Andreas Larsson <andreas@gaisler.com>
Subject: [PATCH] gpio/grgpio: fix deadlock in grgpio_irq_unmap()
Date: Mon, 17 Aug 2015 17:23:52 +0900	[thread overview]
Message-ID: <1439799832-13402-1-git-send-email-acourbot@nvidia.com> (raw)

As reported by Alexey Khoroshilov:

    grgpio_irq_unmap() code looks quite suspicious regarding usage of
    priv->bgc.lock spinlock.

    It locks the spinlock in line 310:

	spin_lock_irqsave(&priv->bgc.lock, flags);

    and then it can call grgpio_set_imask() in line 317:

	grgpio_set_imask(priv, i, 0);

    But grgpio_set_imask() unconditionally locks the spinlock by itself.

Fix this by moving the spinlock acquisition outside of
grgpio_set_imask().

Found by Linux Driver Verification project (linuxtesting.org).

Reported-by: Alexey Khoroshilov <khoroshilov@ispras.ru>
Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
CC: Alexey Khoroshilov <khoroshilov@ispras.ru>
CC: Andreas Larsson <andreas@gaisler.com>
---
 drivers/gpio/gpio-grgpio.c | 15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/drivers/gpio/gpio-grgpio.c b/drivers/gpio/gpio-grgpio.c
index 77053d61466e..801423fe8143 100644
--- a/drivers/gpio/gpio-grgpio.c
+++ b/drivers/gpio/gpio-grgpio.c
@@ -104,17 +104,12 @@ static void grgpio_set_imask(struct grgpio_priv *priv, unsigned int offset,
 {
 	struct bgpio_chip *bgc = &priv->bgc;
 	unsigned long mask = bgc->pin2mask(bgc, offset);
-	unsigned long flags;
-
-	spin_lock_irqsave(&bgc->lock, flags);
 
 	if (val)
 		priv->imask |= mask;
 	else
 		priv->imask &= ~mask;
 	bgc->write_reg(priv->regs + GRGPIO_IMASK, priv->imask);
-
-	spin_unlock_irqrestore(&bgc->lock, flags);
 }
 
 static int grgpio_to_irq(struct gpio_chip *gc, unsigned offset)
@@ -180,16 +175,26 @@ static void grgpio_irq_mask(struct irq_data *d)
 {
 	struct grgpio_priv *priv = irq_data_get_irq_chip_data(d);
 	int offset = d->hwirq;
+	unsigned long flags;
+
+	spin_lock_irqsave(&priv->bgc.lock, flags);
 
 	grgpio_set_imask(priv, offset, 0);
+
+	spin_unlock_irqrestore(&priv->bgc.lock, flags);
 }
 
 static void grgpio_irq_unmask(struct irq_data *d)
 {
 	struct grgpio_priv *priv = irq_data_get_irq_chip_data(d);
 	int offset = d->hwirq;
+	unsigned long flags;
+
+	spin_lock_irqsave(&priv->bgc.lock, flags);
 
 	grgpio_set_imask(priv, offset, 1);
+
+	spin_unlock_irqrestore(&priv->bgc.lock, flags);
 }
 
 static struct irq_chip grgpio_irq_chip = {
-- 
2.5.0


             reply	other threads:[~2015-08-17  8:24 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-08-17  8:23 Alexandre Courbot [this message]
2015-08-17  8:56 ` [PATCH] gpio/grgpio: fix deadlock in grgpio_irq_unmap() Linus Walleij

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1439799832-13402-1-git-send-email-acourbot@nvidia.com \
    --to=acourbot@nvidia.com \
    --cc=andreas@gaisler.com \
    --cc=gnurou@gmail.com \
    --cc=khoroshilov@ispras.ru \
    --cc=ldv-project@linuxtesting.org \
    --cc=linus.walleij@linaro.org \
    --cc=linux-gpio@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.