From: "Paul Louvel" <paul.louvel@bootlin.com>
To: <sashiko-reviews@lists.linux.dev>,
"Paul Louvel" <paul.louvel@bootlin.com>
Cc: <conor+dt@kernel.org>, <devicetree@vger.kernel.org>, <robh@kernel.org>
Subject: Re: [PATCH 08/12] soc: fsl: qe: Convert to generic IRQ chip
Date: Fri, 03 Jul 2026 16:28:06 +0200 [thread overview]
Message-ID: <DJP09A8O5CHS.1KVKCP45QSMDH@bootlin.com> (raw)
In-Reply-To: <20260703134516.ECD1A1F000E9@smtp.kernel.org>
On Fri Jul 3, 2026 at 3:45 PM CEST, sashiko-bot wrote:
> Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
>
> New issues:
> - [High] Incorrect hwirq calculation in `qepic_cascade()` maps bit indices [0..31] to hwirqs [32..1] instead of [31..0], causing out-of-bounds mapping and shifting all IRQs by one.
> - [High] Race condition on probe: The chained interrupt handler is registered before `data->gc` is initialized, causing a NULL pointer dereference if an interrupt fires early.
>
> Pre-existing issues:
> - [High] The IRQ mask, unmask, and set_type callbacks use lockless read-modify-write operations on shared registers, leading to data races.
> --
>
> commit 39268a559b43e95ee6bcd43807086719d4997f6e
> Author: Paul Louvel <paul.louvel@bootlin.com>
>
> soc: fsl: qe: Convert to generic IRQ chip
>
> The generic IRQ chip framework is available to handle IRQ chips. Using
> this framework for the QE interrupt controller allows to simplify the
> driver. Indeed, the framework internally handles operations coded
> directly in the driver.
>
>> diff --git a/drivers/soc/fsl/qe/qe_ports_ic.c b/drivers/soc/fsl/qe/qe_ports_ic.c
>> index c8b73b0aa2334..d022aa224f6d6 100644
>> --- a/drivers/soc/fsl/qe/qe_ports_ic.c
>> +++ b/drivers/soc/fsl/qe/qe_ports_ic.c
>> @@ -20,63 +20,65 @@ struct qepic_data {
>> void __iomem *reg;
>> struct irq_domain *host;
>> int irq;
>> + struct irq_chip_generic *gc;
>> };
>>
>> static void qepic_mask(struct irq_data *d)
>> {
>> - struct qepic_data *data = irq_data_get_irq_chip_data(d);
>> + struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
>> + struct irq_chip_type *ct = irq_data_get_chip_type(d);
>>
>> - clrbits32(data->reg + CEPIMR, 1 << (31 - irqd_to_hwirq(d)));
>> + clrbits32(gc->reg_base + ct->regs.mask, d->mask);
>> }
>
> [Severity: High]
> This is a pre-existing issue, but does this lockless read-modify-write
> operation cause data races?
>
> The qepic_mask(), qepic_unmask(), and qepic_set_type() callbacks use
> clrbits32() and setbits32() on shared registers without a shared controller
> lock. If multiple CPUs modify different IRQs concurrently, could updates to
> the shared mask or type registers be lost?
>
> [ ... ]
>
>> static void qepic_cascade(struct irq_desc *desc)
>> {
>> struct qepic_data *data = irq_desc_get_handler_data(desc);
>> + struct irq_chip_type *ct = data->gc->chip_types;
>> struct irq_chip *chip = irq_desc_get_chip(desc);
>> unsigned long event, bit;
>>
>> chained_irq_enter(chip, desc);
>>
>> - event = in_be32(data->reg + CEPIER);
>> + event = in_be32(data->gc->reg_base + ct->regs.eoi);
>> if (!event) {
>> handle_bad_irq(desc);
>> goto out;
>> }
>
> [Severity: High]
> Could the hwirq calculation in qepic_cascade() be incorrect?
>
> When an interrupt fires, the trailing loop (using for_each_set_bit) yields a
> 0-based bit index, but generic_handle_domain_irq() evaluates the hwirq using
> "32 - bit".
>
> For example, if bit 0 is set, it maps to hwirq 32, which exceeds the domain's
> hwirq_max of 32 and leaves all IRQs shifted out of bounds. Does this need to
> be "31 - bit" to correctly map bit indices [0..31] to hwirqs [31..0]?
>
> [ ... ]
>
Valid point.
>> @@ -125,14 +158,16 @@ static int qepic_probe(struct platform_device *pdev)
>> if (data->irq < 0)
>> return data->irq;
>>
>> - data->host = irq_domain_create_linear(dev_fwnode(dev), 32, &qepic_host_ops, data);
>> - if (!data->host)
>> - return -ENODEV;
>> + data->host = devm_irq_domain_instantiate(dev, &d_info);
>> + if (IS_ERR(data->host))
>> + return PTR_ERR(data->host);
>>
>> - irq_set_chained_handler_and_data(data->irq, qepic_cascade, data);
>> -
>> - return devm_add_action_or_reset(dev, qepic_remove, data);
>> + data->gc = irq_get_domain_generic_chip(data->host, 0);
>> + if (!data->gc)
>> + return -ENODEV;
>> + data->gc->reg_base = data->reg;
>>
>> + return 0;
>> }
>
> [Severity: High]
> Can this probe sequence trigger a NULL pointer dereference?
>
> When devm_irq_domain_instantiate() is called, it triggers the init callback
> qepic_domain_init(), which registers the chained handler and unmasks the
> parent interrupt:
>
> qepic_domain_init()
> irq_set_chained_handler_and_data(data->parent_irq, qepic_cascade, data);
>
> If an interrupt is pending and fires immediately, qepic_cascade() will
> execute and attempt to dereference data->gc->reg_base. However, data->gc is
> not initialized until irq_get_domain_generic_chip() is called after the
> domain instantiation returns.
>
> Could this cause a crash if a pending interrupt is triggered during probe?
Valid point.
--
Paul Louvel, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
next prev parent reply other threads:[~2026-07-03 14:28 UTC|newest]
Thread overview: 31+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-03 13:30 [PATCH 00/12] soc: fsl: qe: QE PIC improvement and add support of IRQs to QUICC ENGINE GPIOs Paul Louvel
2026-07-03 13:30 ` [PATCH 01/12] soc: fsl: qe: Add chained_irq_{enter,exit}() calls in cascade handler Paul Louvel
2026-07-03 13:50 ` sashiko-bot
2026-07-03 13:30 ` [PATCH 02/12] dt-bindings: soc: fsl: qe: Set #interrupt-cells to 2 to support interrupt type encoding Paul Louvel
2026-07-03 13:40 ` sashiko-bot
2026-07-06 11:48 ` Paul Louvel
2026-07-03 13:30 ` [PATCH 03/12] dt-bindings: soc: fsl: qe: Convert QE GPIO to DT schema Paul Louvel
2026-07-06 6:48 ` Krzysztof Kozlowski
2026-07-06 9:03 ` Paul Louvel
2026-07-03 13:30 ` [PATCH 04/12] dt-bindings: soc: fsl: qe: Add support of IRQ in QE GPIO Paul Louvel
2026-07-03 13:43 ` sashiko-bot
2026-07-06 6:52 ` Krzysztof Kozlowski
2026-07-06 8:48 ` Paul Louvel
2026-07-03 13:30 ` [PATCH 05/12] soc: fsl: qe: Use generic_handle_domain_irq() Paul Louvel
2026-07-03 13:30 ` [PATCH 06/12] soc: fsl: qe: Iterate over all pending interrupts in cascade handler Paul Louvel
2026-07-03 13:37 ` sashiko-bot
2026-07-03 13:30 ` [PATCH 07/12] soc: fsl: qe: Handle spurious interrupts Paul Louvel
2026-07-03 13:43 ` sashiko-bot
2026-07-03 13:30 ` [PATCH 08/12] soc: fsl: qe: Convert to generic IRQ chip Paul Louvel
2026-07-03 13:45 ` sashiko-bot
2026-07-03 14:28 ` Paul Louvel [this message]
2026-07-06 7:29 ` Christophe Leroy (CS GROUP)
2026-07-06 8:56 ` Paul Louvel
2026-07-03 13:30 ` [PATCH 09/12] soc: fsl: qe: Rename irq variable to parent_irq Paul Louvel
2026-07-03 13:40 ` sashiko-bot
2026-07-03 13:30 ` [PATCH 10/12] soc: fsl: qe: Rename host member to domain in struct qepic_data Paul Louvel
2026-07-03 13:43 ` sashiko-bot
2026-07-03 13:30 ` [PATCH 11/12] soc: fsl: qe: Remove useless struct member Paul Louvel
2026-07-03 13:47 ` sashiko-bot
2026-07-03 13:30 ` [PATCH 12/12] soc: fsl: qe: Add support of IRQs in QE GPIO Paul Louvel
2026-07-03 13:48 ` sashiko-bot
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=DJP09A8O5CHS.1KVKCP45QSMDH@bootlin.com \
--to=paul.louvel@bootlin.com \
--cc=conor+dt@kernel.org \
--cc=devicetree@vger.kernel.org \
--cc=robh@kernel.org \
--cc=sashiko-reviews@lists.linux.dev \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.