From: sashiko-bot@kernel.org
To: "Sai Krishna Musham" <sai.krishna.musham@amd.com>
Cc: conor+dt@kernel.org, devicetree@vger.kernel.org,
linux-pci@vger.kernel.org, robh@kernel.org
Subject: Re: [PATCH v6 2/2] PCI: amd-mdb: Add CPM6 host controller support
Date: Wed, 19 Aug 2026 17:32:45 +0000 [thread overview]
Message-ID: <20260819173245.778871F00A3D@smtp.kernel.org> (raw)
In-Reply-To: <20260819172057.3636214-3-sai.krishna.musham@amd.com>
Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:
- [High] The shared event interrupt handler `amd_mdb_pcie_event` unconditionally returns `IRQ_HANDLED` and clears shared aggregators even when no events are pending, breaking spurious interrupt detection and potentially disrupting the peer host.
- [High] The CPM6 hardware INTx enable bit is unconditionally unmasked during initialization and probe, completely defeating the newly added `intx_refmask` refcount logic and leaving the system vulnerable to unhandled interrupt storms.
- [High] Probe error path and teardown destroy IRQ domains while devm-managed IRQs and mappings are still active, leading to leaked mappings, kernel warnings, and potential use-after-free via the shared IRQ line.
- [Medium] Failing to disable hardware interrupts on an early probe error path leaves the shared line asserted, potentially causing an endless IRQ storm.
--
--- Patch [2]: [PATCH v6 2/2] PCI: amd-mdb: Add CPM6 host controller support ---
commit 35b39748e651a7f764a655c28114103b16705e80
Author: Sai Krishna Musham <sai.krishna.musham@amd.com>
Subject: PCI: amd-mdb: Add CPM6 host controller support
This commit adds support for the AMD Versal2 CPM6 host controller variants.
It introduces a new interrupt register layout and handles a shared GIC event
interrupt line by clearing the controller's aggregator contribution.
> diff --git a/drivers/pci/controller/dwc/pcie-amd-mdb.c b/drivers/pci/controller/dwc/pcie-amd-mdb.c
> index dee295f281a30..4355fa6d48a39 100644
> --- a/drivers/pci/controller/dwc/pcie-amd-mdb.c
> +++ b/drivers/pci/controller/dwc/pcie-amd-mdb.c
[ ... ]
> @@ -193,11 +285,10 @@ static void amd_mdb_event_irq_unmask(struct irq_data *d)
> struct dw_pcie *pci = &pcie->pci;
> struct dw_pcie_rp *port = &pci->pp;
> unsigned long flags;
> - u32 val;
>
> raw_spin_lock_irqsave(&port->lock, flags);
> - val = BIT(d->hwirq);
> - writel_relaxed(val, pcie->slcr + AMD_MDB_TLP_IR_ENABLE_MISC);
> + writel_relaxed(BIT(d->hwirq),
> + pcie->intr_base + pcie->variant->misc_enable_reg);
> raw_spin_unlock_irqrestore(&port->lock, flags);
> }
[Severity: High]
Does this unconditionally unmask the INTx enable bit in the hardware
register?
Since devm_request_irq() will call amd_mdb_event_irq_unmask(), it appears
the parent IRQ subsystem will unconditionally write the hardware bit here.
Would this completely defeat the intx_refmask refcount logic added in
amd_mdb_intx_irq_unmask(), and leave the system vulnerable to an unhandled
interrupt storm if a downstream device asserts INTx early?
[ ... ]
> @@ -226,13 +317,30 @@ static irqreturn_t amd_mdb_pcie_event(int irq, void *args)
> {
> struct amd_mdb_pcie *pcie = args;
> unsigned long val;
> + u32 ev_raw;
> int i;
>
> - val = readl_relaxed(pcie->slcr + AMD_MDB_TLP_IR_STATUS_MISC);
> - val &= ~readl_relaxed(pcie->slcr + AMD_MDB_TLP_IR_MASK_MISC);
> + ev_raw = readl_relaxed(pcie->intr_base + pcie->variant->misc_status_reg);
> + val = ev_raw;
> + val &= ~readl_relaxed(pcie->intr_base + pcie->variant->misc_mask_reg);
[ ... ]
> + /* Clear handled + any unhandled sticky bits to avoid IRQ storms. */
> + writel_relaxed(ev_raw, pcie->intr_base + pcie->variant->misc_status_reg);
> +
> + /* Sticky aggregation bits; clear each pass or the IRQ re-fires */
> + amd_mdb_pcie_clear_aggregators(pcie);
>
> return IRQ_HANDLED;
> }
[Severity: High]
Could this function unconditionally return IRQ_HANDLED and clear the
shared aggregators even when there are no events pending (when
ev_raw == 0)?
The IRQ_NONE return logic seems to have been placed in dw_pcie_rp_intx()
instead of here. Does returning IRQ_HANDLED unconditionally break spurious
interrupt detection for the shared line?
Also, if the peer host triggered the interrupt, will this clear the shared
AMD_CPM6_PS_MISC_IR_STATUS aggregator before the peer can process it?
[ ... ]
> @@ -250,24 +358,59 @@ static void amd_mdb_pcie_free_irq_domains(struct amd_mdb_pcie *pcie)
[ ... ]
> +static void amd_mdb_pcie_init_port(struct amd_mdb_pcie *pcie)
> +{
> + u32 misc_mask_all;
> + u32 val;
> +
> + misc_mask_all = pcie->variant->misc_mask_all;
>
> /* Disable all TLP interrupts. */
> - writel_relaxed(AMD_MDB_PCIE_IMR_ALL_MASK,
> - pcie->slcr + AMD_MDB_TLP_IR_DISABLE_MISC);
> + writel_relaxed(misc_mask_all,
> + pcie->intr_base + pcie->variant->misc_disable_reg);
>
> /* Clear pending TLP interrupts. */
> - val = readl_relaxed(pcie->slcr + AMD_MDB_TLP_IR_STATUS_MISC);
> - val &= AMD_MDB_PCIE_IMR_ALL_MASK;
> - writel_relaxed(val, pcie->slcr + AMD_MDB_TLP_IR_STATUS_MISC);
> + val = readl_relaxed(pcie->intr_base + pcie->variant->misc_status_reg) &
> + misc_mask_all;
> + writel_relaxed(val, pcie->intr_base + pcie->variant->misc_status_reg);
>
> /* Enable all TLP interrupts. */
> - writel_relaxed(AMD_MDB_PCIE_IMR_ALL_MASK,
> - pcie->slcr + AMD_MDB_TLP_IR_ENABLE_MISC);
> + writel_relaxed(misc_mask_all,
> + pcie->intr_base + pcie->variant->misc_enable_reg);
[Severity: High]
Does this unconditionally write misc_mask_all (which contains the INTx
enable bit) to the hardware enable register?
Similar to the issue in amd_mdb_event_irq_unmask(), does this bypass the
dynamic intx_refmask refcounting logic intended for the child domain?
[ ... ]
> @@ -435,9 +601,36 @@ static int amd_mdb_add_pcie_port(struct amd_mdb_pcie *pcie,
> struct device *dev = &pdev->dev;
> int err;
>
> - pcie->slcr = devm_platform_ioremap_resource_byname(pdev, "slcr");
> - if (IS_ERR(pcie->slcr))
> - return PTR_ERR(pcie->slcr);
> + if (pcie->variant->version == MDB5) {
[ ... ]
> + pcie->intr_base = devm_platform_ioremap_resource_byname(pdev, "intr");
> + if (IS_ERR(pcie->intr_base))
> + return PTR_ERR(pcie->intr_base);
> + }
>
> err = amd_mdb_pcie_init_irq_domains(pcie, pdev);
> if (err)
> - return err;
[Severity: Medium]
If amd_mdb_pcie_init_irq_domains() fails, this returns the error directly
and bypasses the out label.
Does this skip the newly added amd_mdb_pcie_disable_interrupts() call,
potentially leaving the shared line asserted and causing an interrupt storm?
[ ... ]
> @@ -466,6 +659,11 @@ static int amd_mdb_add_pcie_port(struct amd_mdb_pcie *pcie,
> return 0;
>
> out:
> + /*
> + * Mask the hardware interrupts before tearing down so a stale source
> + * cannot storm the shared CPM6 GIC line once this host is unwound.
> + */
> + amd_mdb_pcie_disable_interrupts(pcie);
> amd_mdb_pcie_free_irq_domains(pcie);
> return err;
> }
[Severity: High]
Does this error cleanup path destroy the IRQ domains while the devm-managed
IRQs and mappings are still active?
Because devres frees the requested handlers after the probe function returns,
the newly shared IRQ handler remains active while pcie->mdb_domain is NULL.
Can an asynchronous interrupt from the peer controller hitting the handler
during this window cause a NULL pointer dereference?
Should the mappings be disposed of via irq_dispose_mapping() or the handlers
freed explicitly before destroying the domains?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260819172057.3636214-1-sai.krishna.musham@amd.com?part=2
prev parent reply other threads:[~2026-08-19 17:32 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-19 17:20 [PATCH v6 0/2] pci: AMD: Add Versal2 CPM6 PCIe host controller support Sai Krishna Musham
2026-08-19 17:20 ` [PATCH v6 1/2] dt-bindings: PCI: amd-mdb: Add CPM6 support Sai Krishna Musham
2026-08-19 17:25 ` sashiko-bot
2026-08-19 17:20 ` [PATCH v6 2/2] PCI: amd-mdb: Add CPM6 host controller support Sai Krishna Musham
2026-08-19 17:32 ` sashiko-bot [this message]
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=20260819173245.778871F00A3D@smtp.kernel.org \
--to=sashiko-bot@kernel.org \
--cc=conor+dt@kernel.org \
--cc=devicetree@vger.kernel.org \
--cc=linux-pci@vger.kernel.org \
--cc=robh@kernel.org \
--cc=sai.krishna.musham@amd.com \
--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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox