Re: [PATCH 4.19 023/191] gpio: gpio-grgpio: fix possible sleep-in-atomic-context bugs in grgpio_irq_map/unmap()

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi!

> From: Jia-Ju Bai <baijiaju1990@xxxxxxxxx>
> 
> [ Upstream commit e36eaf94be8f7bc4e686246eed3cf92d845e2ef8 ]
> 
> The driver may sleep while holding a spinlock.

True.

But you can't fix the bug by simply removing the locking, as now
nothing prevents grgpio_irq_unmap() from running while
grgpio_irq_map() is proceeding.

grgpio_irq_map()
	lirq->irq = irq;
	(drops the lock)

grgpio_irq_unmap()
	(gets the lock)
 	if (lirq->irq == irq) {
	 	...
		(proceeds to work with half-initialized structure)

Best regards,
							Pavel


> index 60a1556c570a4..c1be299e5567b 100644
> --- a/drivers/gpio/gpio-grgpio.c
> +++ b/drivers/gpio/gpio-grgpio.c
> @@ -258,17 +258,16 @@ static int grgpio_irq_map(struct irq_domain *d, unsigned int irq,
>  	lirq->irq = irq;
>  	uirq = &priv->uirqs[lirq->index];
>  	if (uirq->refcnt == 0) {
> +		spin_unlock_irqrestore(&priv->gc.bgpio_lock, flags);
>  		ret = request_irq(uirq->uirq, grgpio_irq_handler, 0,
>  				  dev_name(priv->dev), priv);
>  		if (ret) {
>  			dev_err(priv->dev,
>  				"Could not request underlying irq %d\n",
>  				uirq->uirq);
> -
> -			spin_unlock_irqrestore(&priv->gc.bgpio_lock, flags);
> -
>  			return ret;
>  		}
> +		spin_lock_irqsave(&priv->gc.bgpio_lock, flags);
>  	}
>  	uirq->refcnt++;
>  
> @@ -314,8 +313,11 @@ static void grgpio_irq_unmap(struct irq_domain *d, unsigned int irq)
>  	if (index >= 0) {
>  		uirq = &priv->uirqs[lirq->index];
>  		uirq->refcnt--;
> -		if (uirq->refcnt == 0)
> +		if (uirq->refcnt == 0) {
> +			spin_unlock_irqrestore(&priv->gc.bgpio_lock, flags);
>  			free_irq(uirq->uirq, priv);
> +			return;
> +		}
>  	}
>  
>  	spin_unlock_irqrestore(&priv->gc.bgpio_lock, flags);

-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html

Attachment: signature.asc
Description: Digital signature


[Index of Archives]     [Linux Kernel]     [Kernel Development Newbies]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite Hiking]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux