RE: [PATCH v2 2/2] pci: AMD: Add CPM6 host controller support to AMD MDB PCIe driver
"Musham, Sai Krishna" <[email protected]> Mon, 3 Aug 2026 10:43:35 +0000
| Newsgroups | org.kernel.vger.linux-devicetree,dev.linux.lists.sashiko-reviews,org.kernel.vger.linux-pci |
|---|---|
| Message-ID | <IA4PR12MB9810B005A5C39C0ADD785861CDD52@IA4PR12MB9810.namprd12.prod.outlook.com> |
AMD General > -----Original Message----- > From: [email protected] <[email protected]> > Sent: Wednesday, July 29, 2026 2:04 AM > To: Musham, Sai Krishna <[email protected]> > Cc: [email protected]; [email protected]; [email protected]; > [email protected] > Subject: Re: [PATCH v2 2/2] pci: AMD: Add CPM6 host controller support to > AMD MDB PCIe driver > > Thank you for your contribution! Sashiko AI review found 8 potential issue(s) > to consider: > > New issues: > - [High] Double-free and Use-After-Free of devm-managed interrupts on > probe failure. > - [High] Masking a single virtual INTx line on CPM6 unconditionally disables > the aggregate hardware INTx interrupt, breaking other devices. > - [High] Unhandled bits in `AMD_CPM6_PCIE_ERR_STATUS` are never cleared, > leading to an unrecoverable infinite IRQ storm. > - [High] Exclusive ioremap of the shared `slcr` region will cause the second > CPM6 host controller to fail probing. > - [High] Uncoordinated W1C clearing of the shared sticky aggregator bit > causes lost interrupts for the other host. > > Pre-existing issues: > - [High] INTxB, INTxC, and INTxD interrupts on MDB5 are silently dropped > because their hardware IRQs are never mapped. > - [High] Use-After-Free of irq_domain triggered by concurrent hardware > interrupt during probe error path. > - [High] Clearing sticky W1C status registers at the end of the interrupt handler > creates a race condition that loses concurrent edges. > -- > > --- Patch [2]: [PATCH v2 2/2] pci: AMD: Add CPM6 host controller support to > AMD MDB PCIe driver --- > commit 72da33718ab9f6a5d8466cccef118aefc6c26f76 > Author: Sai Krishna Musham <[email protected]> > Subject: pci: AMD: Add CPM6 host controller support to AMD MDB PCIe > driver > > This patch extends the AMD MDB PCIe driver to support AMD Versal2 CPM6 > variants. It adds variant-specific register layouts and implements a shared > aggregator clearing mechanism for the new interrupt architecture. > > Link: https://lore.kernel.org/all/20260402180006.486229-3- > [email protected]/ > > > diff --git a/drivers/pci/controller/dwc/pcie-amd-mdb.c > b/drivers/pci/controller/dwc/pcie-amd-mdb.c > > index dee295f281a30..dbf36ce9902c8 100644 > > --- a/drivers/pci/controller/dwc/pcie-amd-mdb.c > > +++ b/drivers/pci/controller/dwc/pcie-amd-mdb.c > [ ... ] > > @@ -148,42 +287,34 @@ static void > amd_mdb_pcie_clear_aggregators(struct amd_mdb_pcie *pcie) > > writel_relaxed(merged_mask, pcie->slcr + > AMD_CPM6_MERGED_STATUS); > > > > /* > > * Clear MERGED in the PS_MISC severity register so the misc GIC line > > * de-asserts. > > */ > > writel_relaxed(AMD_CPM6_PS_IR_MERGED, > > pcie->slcr + AMD_CPM6_PS_MISC_IR_STATUS); > > } > > [Severity: High] > Does blindly clearing the shared sticky aggregator bit drop concurrent > interrupts from the other host controller? > > The commit mentions this aggregator is shared between controllers. If Host 0 > clears this W1C bit while Host 1 has a pending unserviced interrupt in the > MERGED register, Host 1's edge might be swallowed and never serviced. > > Does this need coordinated locking to ensure it is only cleared when no > other hosts have pending interrupts? > No coordinated locking is needed. The W1C clears only this host's MERGED Bits (HOST0: 13/14, HOST1: 16/17), the peer's bits are untouched. PS_MISC bit 21 (merged_interrupts_0) is a sticky W1C aggregate of MERGED_INTERRUPTS. where both hosts live; since the peer's MERGED bits stay set, bit 21 re-asserts and the peer's interrupt still fires. > [ ... ] > > @@ -213,11 +237,15 @@ static void amd_mdb_intx_irq_mask(struct > irq_data *data) > > if (pcie->variant->version == MDB5) > > val = FIELD_PREP(AMD_MDB_TLP_PCIE_INTX_MASK, > > AMD_MDB_PCIE_INTR_INTX_ASSERT(data- > >hwirq)); > > else > > val = pcie->variant->intx_mask; > > > > /* > > * Writing '1' to a bit in AMD_MDB_TLP_IR_DISABLE_MISC disables > that > > * interrupt, writing '0' has no effect. > > */ > > - writel_relaxed(val, pcie->slcr + AMD_MDB_TLP_IR_DISABLE_MISC); > > + writel_relaxed(val, pcie->intr_base + pcie->variant- > >misc_disable_reg); > > [Severity: High] > Will masking a single virtual INTx line on CPM6 unconditionally disable the > aggregate hardware INTx interrupt? > > On CPM6, there appears to be only a single aggregate INTx hardware interrupt > bit. If an endpoint driver unbinds or calls disable_irq() on INTA, this > unconditionally writes the intx_mask bit to the disable register. > > Does this disable the hardware aggregate interrupt completely, potentially > starving other endpoint devices relying on INTB, INTC, or INTD? > > [ ... ] > > @@ -354,16 +375,19 @@ static irqreturn_t amd_mdb_pcie_event(int irq, > void *args) > > 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); > > > > if (pcie->variant->version == MDB5) { > > for_each_set_bit(i, &val, 32) > > generic_handle_domain_irq(pcie->mdb_domain, i); > > [Severity: High] > This is a pre-existing issue, but are INTxB, INTxC, and INTxD interrupts > silently dropped on MDB5? > > When an INTx occurs, amd_mdb_pcie_event() extracts the asserted bit and > calls generic_handle_domain_irq(). However, amd_mdb_setup_irq() only > creates a mapping for the single intx_hwirq (INTxA). > > Bits corresponding to INTxB, INTxC, and INTxD are never mapped, so > generic_handle_domain_irq() will return -EINVAL and the interrupts will be > lost. > > > writel_relaxed(val, pcie->intr_base + pcie->variant- > >misc_status_reg); > > return IRQ_HANDLED; > > } > > > > val &= pcie->variant->misc_mask_all; > > > > for_each_set_bit(i, &val, 32) > > generic_handle_domain_irq(pcie->mdb_domain, i); > > > > /* Clear handled + any unhandled sticky bits to avoid IRQ storms. */ > > - writel_relaxed(val, pcie->slcr + AMD_MDB_TLP_IR_STATUS_MISC); > > + writel_relaxed(ev_raw, pcie->intr_base + pcie->variant- > >misc_status_reg); > > [Severity: High] > This isn't a bug introduced by this patch, but does clearing the sticky W1C > status register at the end of the interrupt handler create a race condition? > > If a second edge of the same interrupt type occurs during the handling > phase, writing ev_raw back to the W1C register at the very end will clear > the new edge without it ever being processed. > > Should the status register be ACKed before handling the events so that new > edges can latch correctly? > Agreed. This is pre-existing MDB5 behavior and ACK-before-handle is the right hardening. I will send it as a separate patch (per Bjorn), rather than mixing it with CPM6 support. > > + /* On CPM6 the completion timeout is reported via the PCIE_ERR > register. */ > > + err = readl_relaxed(pcie->intr_base + > AMD_CPM6_PCIE_ERR_STATUS); > > + err &= ~readl_relaxed(pcie->intr_base + > AMD_CPM6_PCIE_ERR_MASK); > > + err &= AMD_CPM6_PCIE_ERR_MASK_ALL; > > + if (err) { > > + dev_warn(pcie->pci.dev, "Completion timeout\n"); > > + writel_relaxed(err, pcie->intr_base + > AMD_CPM6_PCIE_ERR_STATUS); > > + } > > [Severity: High] > Are unhandled bits in the PCIE_ERR_STATUS register masked out and never > cleared? > > The driver masks the read value with AMD_CPM6_PCIE_ERR_MASK_ALL and > only > writes back the known bits to the W1C register. If any unhandled bit is > set, it remains uncleared. > > Since this register feeds into the sticky MERGED aggregator, will this cause > the hardware to immediately re-assert the main parent interrupt and create > an unrecoverable IRQ storm? > > [ ... ] > > @@ -400,10 +421,30 @@ static void > amd_mdb_pcie_free_irq_domains(struct amd_mdb_pcie *pcie) > > + const struct amd_mdb_intr_cause *intr_cause = > > + pcie->variant->version == MDB5 ? > > + mdb5_intr_cause : cpm6_intr_cause; > > + int i, irq; > > + > > + for (i = 0; i < ARRAY_SIZE(mdb5_intr_cause); i++) { > > + if (!intr_cause[i].str) > > + continue; > > + irq = irq_find_mapping(pcie->mdb_domain, i); > > + if (irq) { > > + disable_irq(irq); > > + free_irq(irq, pcie); > > + irq_dispose_mapping(irq); > > + } > > + } > > [Severity: High] > Is it safe to manually call free_irq() on an interrupt allocated with > devm_request_irq()? > > In amd_mdb_setup_irq(), these interrupts are allocated under devres > management. On probe failure, this error path manually frees them. When > the > driver unbinds, devres will attempt to free the same IRQs again. > > Can this cause a double-free on a disposed virtual IRQ mapping? > > [ ... ] > > irq_domain_remove(pcie->mdb_domain); > > pcie->mdb_domain = NULL; > > [Severity: High] > This is a pre-existing issue, but can this lead to a use-after-free of the > irq_domain if a hardware interrupt arrives concurrently? > > The error path destroys and frees pcie->mdb_domain, but fails to disable > the main event interrupt first. If an interrupt fires concurrently, > amd_mdb_pcie_event() might dereference the freed domain pointer to > dispatch > child interrupts. > Agreed, this is a pre-existing problem. Removing the manual free loop above makes the window smaller, but the real fix - stopping the parent event IRQ before removing the domains - is generic MDB5 code. I'll do that in a separate patch so it can be backported on its own, as Bjorn suggested. > [ ... ] > > @@ -639,12 +660,26 @@ static int amd_mdb_add_pcie_port(struct > amd_mdb_pcie *pcie, > > pcie->slcr = devm_platform_ioremap_resource_byname(pdev, "slcr"); > > if (IS_ERR(pcie->slcr)) > > return PTR_ERR(pcie->slcr); > > [Severity: High] > Will an exclusive ioremap of the shared slcr region cause the second CPM6 > host controller to fail probing? > > The commit message notes the aggregation layer is shared between the two > controllers. Requesting exclusive access to the memory region here means the > first device claims it, and the second device might fail to probe with a > resource conflict. > > -- > Sashiko AI review ยท https://sashiko.dev/#/patchset/20260728202044.1785986- > [email protected]?part=2 Thanks, Sai Krishna