[PATCH] PCI: xilinx-xdma-pl: fix refcount leak in xilinx_pl_dma_pcie_init_irq_domain()
From: Wentao Liang
Date: Tue Jun 16 2026 - 10:28:36 EST
of_get_child_by_name() acquires a reference on the returned device node,
which must be released with of_node_put() after use. In
xilinx_pl_dma_pcie_init_irq_domain(), the reference is properly released
on the success path, but error paths that return directly fail to do so,
leading to a reference count leak.
Additionally, when the INTx domain creation or MSI initialization fails,
the already created PL DMA IRQ domain is not removed, causing another
memory leak.
Fix this by using goto-based error handling:
- Add a common 'out_put_node' label to release the node reference.
- Add 'out_remove_pldma' to delete the PL DMA domain before releasing
the node.
- Ensure all error paths jump to the appropriate cleanup labels.
Cc: stable@xxxxxxxxxxxxxxx
Fixes: 8d786149d78c ("PCI: xilinx-xdma: Add Xilinx XDMA Root Port driver")
Signed-off-by: Wentao Liang <vulab@xxxxxxxxxxx>
---
drivers/pci/controller/pcie-xilinx-dma-pl.c | 18 ++++++++++++++----
1 file changed, 14 insertions(+), 4 deletions(-)
diff --git a/drivers/pci/controller/pcie-xilinx-dma-pl.c b/drivers/pci/controller/pcie-xilinx-dma-pl.c
index b037c8f315e4..e7a83a758874 100644
--- a/drivers/pci/controller/pcie-xilinx-dma-pl.c
+++ b/drivers/pci/controller/pcie-xilinx-dma-pl.c
@@ -580,8 +580,10 @@ static int xilinx_pl_dma_pcie_init_irq_domain(struct pl_dma_pcie *port)
port->pldma_domain = irq_domain_create_linear(of_fwnode_handle(pcie_intc_node), 32,
&event_domain_ops, port);
- if (!port->pldma_domain)
- return -ENOMEM;
+ if (!port->pldma_domain) {
+ ret = -ENOMEM;
+ goto out_put_node;
+ }
irq_domain_update_bus_token(port->pldma_domain, DOMAIN_BUS_NEXUS);
@@ -589,7 +591,8 @@ static int xilinx_pl_dma_pcie_init_irq_domain(struct pl_dma_pcie *port)
&intx_domain_ops, port);
if (!port->intx_domain) {
dev_err(dev, "Failed to get a INTx IRQ domain\n");
- return -ENOMEM;
+ ret = -ENOMEM;
+ goto out_remove_pldma;
}
irq_domain_update_bus_token(port->intx_domain, DOMAIN_BUS_WIRED);
@@ -597,13 +600,20 @@ static int xilinx_pl_dma_pcie_init_irq_domain(struct pl_dma_pcie *port)
ret = xilinx_pl_dma_pcie_init_msi_irq_domain(port);
if (ret != 0) {
irq_domain_remove(port->intx_domain);
- return -ENOMEM;
+ ret = -ENOMEM;
+ goto out_remove_pldma;
}
of_node_put(pcie_intc_node);
raw_spin_lock_init(&port->lock);
return 0;
+
+out_remove_pldma:
+ irq_domain_remove(port->pldma_domain);
+out_put_node:
+ of_node_put(pcie_intc_node);
+ return ret;
}
static int xilinx_pl_dma_pcie_setup_irq(struct pl_dma_pcie *port)
--
2.34.1