git: c121ed33cde5 - stable/15 - linuxkpi: Fix double-cleanup in linux_pci_attach_device() error path

From: Konstantin Belousov <kib_at_FreeBSD.org>
Date: Wed, 30 Sep 2026 00:53:33 UTC
The branch stable/15 has been updated by kib:

URL: https://cgit.FreeBSD.org/src/commit/?id=c121ed33cde56dd2bf019ffe22c47b12f134b8c9

commit c121ed33cde56dd2bf019ffe22c47b12f134b8c9
Author:     Slava Shwartsman <slavash@nvidia.com>
AuthorDate: 2026-09-22 17:21:13 +0000
Commit:     Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2026-09-30 00:52:16 +0000

    linuxkpi: Fix double-cleanup in linux_pci_attach_device() error path
    
    (cherry picked from commit ac9c07a3e90888d69d0a524de520d4de8ae60de5)
---
 sys/compat/linuxkpi/common/src/linux_pci.c | 19 +++++++------------
 1 file changed, 7 insertions(+), 12 deletions(-)

diff --git a/sys/compat/linuxkpi/common/src/linux_pci.c b/sys/compat/linuxkpi/common/src/linux_pci.c
index b5aee166de2d..e75e5ba8086f 100644
--- a/sys/compat/linuxkpi/common/src/linux_pci.c
+++ b/sys/compat/linuxkpi/common/src/linux_pci.c
@@ -182,6 +182,8 @@ linux_pdev_dma_uninit(struct pci_dev *pdev)
 	struct linux_dma_priv *priv;
 
 	priv = pdev->dev.dma_priv;
+	if (priv == NULL)
+		return (0);
 	if (priv->dmat)
 		bus_dma_tag_destroy(priv->dmat);
 	if (priv->dmat_coherent)
@@ -480,6 +482,7 @@ lkpifill_pci_dev(device_t dev, struct pci_dev *pdev)
 	spin_lock_init(&pdev->dev.devres_lock);
 	INIT_LIST_HEAD(&pdev->dev.devres_head);
 	INIT_LIST_HEAD(&pdev->dev.irqents);
+	INIT_LIST_HEAD(&pdev->links);
 
 	return (0);
 }
@@ -698,7 +701,7 @@ linux_pci_attach_device(device_t dev, struct pci_driver *pdrv,
 	pdev->irq = pdev->dev.irq;
 	error = linux_pdev_dma_init(pdev);
 	if (error)
-		goto out_dma_init;
+		goto out_err;
 
 	spin_lock(&pci_lock);
 	list_add(&pdev->links, &pci_devices);
@@ -713,7 +716,7 @@ linux_pci_attach_device(device_t dev, struct pci_driver *pdrv,
 		pbus = lkpinew_pci_dev(parent);
 		if (pbus == NULL) {
 			error = ENXIO;
-			goto out_dma_init;
+			goto out_err;
 		}
 	}
 	pcie_find_root_port(pbus);
@@ -728,19 +731,11 @@ linux_pci_attach_device(device_t dev, struct pci_driver *pdrv,
 	if (pdrv != NULL) {
 		error = pdrv->probe(pdev, id);
 		if (error)
-			goto out_probe;
+			goto out_err;
 	}
 	return (0);
 
-/* XXX the cleanup does not match the allocation up there. */
-out_probe:
-	free(pdev->bus, M_DEVBUF);
-	spin_lock_destroy(&pdev->pcie_cap_lock);
-	linux_pdev_dma_uninit(pdev);
-out_dma_init:
-	spin_lock(&pci_lock);
-	list_del(&pdev->links);
-	spin_unlock(&pci_lock);
+out_err:
 	put_device(&pdev->dev);
 	return (-error);
 }