Re: [PATCH v3 4/7] gpio: gpiolib: fix allocation order in hierarchical IRQ domains

From: Linus Walleij

Date: Tue Mar 10 2026 - 05:13:48 EST


On Mon, Mar 9, 2026 at 2:49 PM Oleksij Rempel <o.rempel@xxxxxxxxxxxxxx> wrote:

> In gpiochip_hierarchy_irq_domain_alloc(), calling irq_domain_set_info()
> before irq_domain_alloc_irqs_parent() causes a NULL pointer dereference
> for slow-bus (SPI/I2C) IRQ chips.
>
> irq_domain_set_info() locks the child descriptor, triggering .irq_bus_lock.
> If the child proxies this lock to the parent, it crashes because
> parent->chip is not yet allocated.
>
> Fix this by allocating the parent IRQs first, ensuring parent->chip is
> populated before the child's .irq_bus_lock is invoked.
>
> Signed-off-by: Oleksij Rempel <o.rempel@xxxxxxxxxxxxxx>
> ---
> changes v3
> - new patch

Bartosz, tglx: is this something we should apply for fixes?

I think it needs to go into gpiolib for next at minimum, unless
there is some semantic problem with the patch.

Verbose quote:

> - /*
> - * We set handle_bad_irq because the .set_type() should
> - * always be invoked and set the right type of handler.
> - */
> - irq_domain_set_info(d,
> - irq,
> - hwirq,
> - gc->irq.chip,
> - gc,
> - girq->handler,
> - NULL, NULL);
> - irq_set_probe(irq);
> -
> /* This parent only handles asserted level IRQs */
> ret = girq->populate_parent_alloc_arg(gc, &gpio_parent_fwspec,
> parent_hwirq, parent_type);
> @@ -1657,12 +1644,27 @@ static int gpiochip_hierarchy_irq_domain_alloc(struct irq_domain *d,
> */
> if (irq_domain_is_msi(d->parent) && (ret == -EEXIST))
> ret = 0;
> - if (ret)
> + if (ret) {
> gpiochip_err(gc,
> "failed to allocate parent hwirq %d for hwirq %lu\n",
> parent_hwirq, hwirq);
> + return ret;
> + }
>
> - return ret;
> + /*
> + * We set handle_bad_irq because the .set_type() should
> + * always be invoked and set the right type of handler.
> + */
> + irq_domain_set_info(d,
> + irq,
> + hwirq,
> + gc->irq.chip,
> + gc,
> + girq->handler,
> + NULL, NULL);
> + irq_set_probe(irq);
> +
> + return 0;

Yours,
Linus Walleij