PCI: plda: Fix IRQ domain leaks in the error paths of plda_init_interrupts()

plda_init_interrupts() initializes IRQ domains and creates IRQ mapping but
does not unwind them when later step fails.

If platform_get_irq() or either irq_create_mapping() fails
in plda_init_interrupts(), the domains are never deinitialized. If
irq_create_mapping() fails, port->intx_irq stays initialized.

Hence, remove the IRQ domains in the error path by calling
plda_pcie_irq_domain_deinit().

Since plda_pcie_irq_domain_deinit() now disposes of the intx_irq and
msi_irq mappings itself before removing their domains, the msi_irq
mapping failure path can go directly to err_irq_domain_deinit instead of
disposing of port->intx_irq separately first.

This issue was found by automated review of sashiko-bot

Fixes: 4602c370bd ("PCI: microchip: Move IRQ functions to pcie-plda-host.c")
Fixes: 76c9113968 ("PCI: plda: Add host init/deinit and map bus functions")
Closes: https://lore.kernel.org/linux-pci/20260718120701.DF4111F000E9@smtp.kernel.org/
Signed-off-by: Ali Tariq <alitariq45892@gmail.com>
[mani: commit log]
Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260723142824.726655-1-alitariq45892@gmail.com
This commit is contained in:
Ali Tariq 2026-07-23 19:28:24 +05:00 committed by Manivannan Sadhasivam
parent 26b73bae01
commit 19a30bbb64

View File

@ -419,6 +419,8 @@ static int plda_pcie_init_irq_domains(struct plda_pcie_rp *port)
return plda_allocate_msi_domains(port);
}
static void plda_pcie_irq_domain_deinit(struct plda_pcie_rp *pcie);
int plda_init_interrupts(struct platform_device *pdev,
struct plda_pcie_rp *port,
const struct plda_event *event)
@ -440,14 +442,17 @@ int plda_init_interrupts(struct platform_device *pdev,
}
port->irq = platform_get_irq(pdev, 0);
if (port->irq < 0)
return -ENODEV;
if (port->irq < 0) {
ret = -ENODEV;
goto err_irq_domain_deinit;
}
for_each_set_bit(i, &port->events_bitmap, port->num_events) {
event_irq = irq_create_mapping(port->event_domain, i);
if (!event_irq) {
dev_err(dev, "failed to map hwirq %d\n", i);
return -ENXIO;
ret = -ENXIO;
goto err_irq_domain_deinit;
}
if (event->request_event_irq)
@ -459,7 +464,7 @@ int plda_init_interrupts(struct platform_device *pdev,
if (ret) {
dev_err(dev, "failed to request IRQ %d\n", event_irq);
return ret;
goto err_irq_domain_deinit;
}
}
@ -467,7 +472,8 @@ int plda_init_interrupts(struct platform_device *pdev,
event->intx_event);
if (!port->intx_irq) {
dev_err(dev, "failed to map INTx interrupt\n");
return -ENXIO;
ret = -ENXIO;
goto err_irq_domain_deinit;
}
/* Plug the INTx chained handler */
@ -475,8 +481,11 @@ int plda_init_interrupts(struct platform_device *pdev,
port->msi_irq = irq_create_mapping(port->event_domain,
event->msi_event);
if (!port->msi_irq)
return -ENXIO;
if (!port->msi_irq) {
dev_err(dev, "failed to map MSI interrupt\n");
ret = -ENXIO;
goto err_irq_domain_deinit;
}
/* Plug the MSI chained handler */
irq_set_chained_handler_and_data(port->msi_irq, plda_handle_msi, port);
@ -485,6 +494,11 @@ int plda_init_interrupts(struct platform_device *pdev,
irq_set_chained_handler_and_data(port->irq, plda_handle_event, port);
return 0;
err_irq_domain_deinit:
plda_pcie_irq_domain_deinit(port);
return ret;
}
EXPORT_SYMBOL_GPL(plda_init_interrupts);