Skip to content

Commit 9e8bc2d

Browse files
YchameBartosz Golaszewski
authored andcommitted
gpio: timberdale: Fix potential deadlock on &tgpio->lock
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 <[email protected]> Reviewed-by: Andy Shevchenko <[email protected]> Signed-off-by: Bartosz Golaszewski <[email protected]>
1 parent 6465e26 commit 9e8bc2d

File tree

1 file changed

+3
-2
lines changed

1 file changed

+3
-2
lines changed

drivers/gpio/gpio-timberdale.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,10 @@ static int timbgpio_update_bit(struct gpio_chip *gpio, unsigned index,
4343
unsigned offset, bool enabled)
4444
{
4545
struct timbgpio *tgpio = gpiochip_get_data(gpio);
46+
unsigned long flags;
4647
u32 reg;
4748

48-
spin_lock(&tgpio->lock);
49+
spin_lock_irqsave(&tgpio->lock, flags);
4950
reg = ioread32(tgpio->membase + offset);
5051

5152
if (enabled)
@@ -54,7 +55,7 @@ static int timbgpio_update_bit(struct gpio_chip *gpio, unsigned index,
5455
reg &= ~(1 << index);
5556

5657
iowrite32(reg, tgpio->membase + offset);
57-
spin_unlock(&tgpio->lock);
58+
spin_unlock_irqrestore(&tgpio->lock, flags);
5859

5960
return 0;
6061
}

0 commit comments

Comments
 (0)