Commit f42b3c05 authored by Haotian Zhang's avatar Haotian Zhang Committed by Manivannan Sadhasivam
Browse files

PCI: xilinx: Fix INTx IRQ domain leak in error paths



In xilinx_pcie_init_irq_domain(), if xilinx_allocate_msi_domains() fails
after pcie->leg_domain has been successfully created via
irq_domain_create_linear(), the function returns directly without cleaning
up the allocated IRQ domain, resulting in a resource leak. In
xilinx_free_msi_domains(), pcie->leg_domain is also neglected.

Add irq_domain_remove() call in the error path to properly release the
IRQ domain before returning the error. Also rename
xilinx_free_msi_domains() to xilinx_free_irq_domains() and add the release
of pcie->leg_domain to it.

Fixes: 313b64c3 ("PCI: xilinx: Convert to MSI domains")
Suggested-by: default avatarManivannan Sadhasivam <mani@kernel.org>
Signed-off-by: default avatarHaotian Zhang <vulab@iscas.ac.cn>
Signed-off-by: default avatarManivannan Sadhasivam <mani@kernel.org>
Link: https://patch.msgid.link/20251219021615.965-1-vulab@iscas.ac.cn
parent 8f0b4cce
Loading
Loading
Loading
Loading
+6 −3
Original line number Diff line number Diff line
@@ -302,9 +302,10 @@ static int xilinx_allocate_msi_domains(struct xilinx_pcie *pcie)
	return 0;
}

static void xilinx_free_msi_domains(struct xilinx_pcie *pcie)
static void xilinx_free_irq_domains(struct xilinx_pcie *pcie)
{
	irq_domain_remove(pcie->msi_domain);
	irq_domain_remove(pcie->leg_domain);
}

/* INTx Functions */
@@ -480,8 +481,10 @@ static int xilinx_pcie_init_irq_domain(struct xilinx_pcie *pcie)
		phys_addr_t pa = ALIGN_DOWN(virt_to_phys(pcie), SZ_4K);

		ret = xilinx_allocate_msi_domains(pcie);
		if (ret)
		if (ret) {
			irq_domain_remove(pcie->leg_domain);
			return ret;
		}

		pcie_write(pcie, upper_32_bits(pa), XILINX_PCIE_REG_MSIBASE1);
		pcie_write(pcie, lower_32_bits(pa), XILINX_PCIE_REG_MSIBASE2);
@@ -600,7 +603,7 @@ static int xilinx_pcie_probe(struct platform_device *pdev)

	err = pci_host_probe(bridge);
	if (err)
		xilinx_free_msi_domains(pcie);
		xilinx_free_irq_domains(pcie);

	return err;
}