diff mbox series

gpiolib: irq hooks: fix recursion in gpiochip_irq_unmask

Message ID 20201210070514.13238-1-nikita.shubin@maquefel.me
State New
Headers show
Series gpiolib: irq hooks: fix recursion in gpiochip_irq_unmask | expand

Commit Message

Nikita Shubin Dec. 10, 2020, 7:05 a.m. UTC
irqchip shared with multiple gpiochips, leads to recursive call of
gpiochip_irq_mask/gpiochip_irq_unmask which was assigned to
rqchip->irq_mask/irqchip->irq_unmask, these happens becouse of
only irqchip->irq_enable == gpiochip_irq_enable is checked.

Let's add an additional check to make sure shared irqchip is detected
even if irqchip->irq_enable wasn't defined.

Fixes: a8173820f441 ("gpio: gpiolib: Allow GPIO IRQs to lazy disable")
Signed-off-by: Nikita Shubin <nikita.shubin@maquefel.me>
---
 drivers/gpio/gpiolib.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

Comments

Linus Walleij Dec. 11, 2020, 11:26 p.m. UTC | #1
On Thu, Dec 10, 2020 at 8:06 AM Nikita Shubin <nikita.shubin@maquefel.me> wrote:

> irqchip shared with multiple gpiochips, leads to recursive call of
> gpiochip_irq_mask/gpiochip_irq_unmask which was assigned to
> rqchip->irq_mask/irqchip->irq_unmask, these happens becouse of
> only irqchip->irq_enable == gpiochip_irq_enable is checked.
>
> Let's add an additional check to make sure shared irqchip is detected
> even if irqchip->irq_enable wasn't defined.
>
> Fixes: a8173820f441 ("gpio: gpiolib: Allow GPIO IRQs to lazy disable")
> Signed-off-by: Nikita Shubin <nikita.shubin@maquefel.me>

Good catch!
Patch applied.

Yours,
Linus Walleij
diff mbox series

Patch

diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index 589eceecf374..5ce0c14c637b 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -1419,7 +1419,8 @@  static void gpiochip_set_irq_hooks(struct gpio_chip *gc)
 	if (WARN_ON(gc->irq.irq_enable))
 		return;
 	/* Check if the irqchip already has this hook... */
-	if (irqchip->irq_enable == gpiochip_irq_enable) {
+	if (irqchip->irq_enable == gpiochip_irq_enable ||
+		irqchip->irq_mask == gpiochip_irq_mask) {
 		/*
 		 * ...and if so, give a gentle warning that this is bad
 		 * practice.