Patch "gpio: timberdale: Fix potential deadlock on &tgpio->lock" has been added to the 4.19-stable tree

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

 



This is a note to let you know that I've just added the patch titled

    gpio: timberdale: Fix potential deadlock on &tgpio->lock

to the 4.19-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     gpio-timberdale-fix-potential-deadlock-on-tgpio-lock.patch
and it can be found in the queue-4.19 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit 033bb212fc1e9aa52681f271400c1bda39686925
Author: Chengfeng Ye <dg573847474@xxxxxxxxx>
Date:   Tue Sep 26 10:29:14 2023 +0000

    gpio: timberdale: Fix potential deadlock on &tgpio->lock
    
    [ Upstream commit 9e8bc2dda5a7a8e2babc9975f4b11c9a6196e490 ]
    
    As timbgpio_irq_enable()/timbgpio_irq_disable() callback could be
    executed under irq context, it could introduce double locks on
    &tgpio->lock if it preempts other execution units requiring
    the same locks.
    
    timbgpio_gpio_set()
    --> timbgpio_update_bit()
    --> spin_lock(&tgpio->lock)
    <interrupt>
       --> timbgpio_irq_disable()
       --> spin_lock_irqsave(&tgpio->lock)
    
    This flaw was found by an experimental static analysis tool I am
    developing for irq-related deadlock.
    
    To prevent the potential deadlock, the patch uses spin_lock_irqsave()
    on &tgpio->lock inside timbgpio_gpio_set() to prevent the possible
    deadlock scenario.
    
    Signed-off-by: Chengfeng Ye <dg573847474@xxxxxxxxx>
    Reviewed-by: Andy Shevchenko <andy@xxxxxxxxxx>
    Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@xxxxxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/drivers/gpio/gpio-timberdale.c b/drivers/gpio/gpio-timberdale.c
index 314e300d6ba33..1e6925c27ae29 100644
--- a/drivers/gpio/gpio-timberdale.c
+++ b/drivers/gpio/gpio-timberdale.c
@@ -55,9 +55,10 @@ static int timbgpio_update_bit(struct gpio_chip *gpio, unsigned index,
 	unsigned offset, bool enabled)
 {
 	struct timbgpio *tgpio = gpiochip_get_data(gpio);
+	unsigned long flags;
 	u32 reg;
 
-	spin_lock(&tgpio->lock);
+	spin_lock_irqsave(&tgpio->lock, flags);
 	reg = ioread32(tgpio->membase + offset);
 
 	if (enabled)
@@ -66,7 +67,7 @@ static int timbgpio_update_bit(struct gpio_chip *gpio, unsigned index,
 		reg &= ~(1 << index);
 
 	iowrite32(reg, tgpio->membase + offset);
-	spin_unlock(&tgpio->lock);
+	spin_unlock_irqrestore(&tgpio->lock, flags);
 
 	return 0;
 }



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux