Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 15 May 2025 09:53:00 GMT
From:      "Bjoern A. Zeeb" <bz@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org
Subject:   git: c6c953fc43d8 - stable/14 - LinuxKPI: pci: fix two errors in lkpi_pci_get_device()
Message-ID:  <202505150953.54F9r0j6050780@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch stable/14 has been updated by bz:

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

commit c6c953fc43d86417bbf18a41a328c60f02a34c69
Author:     Bjoern A. Zeeb <bz@FreeBSD.org>
AuthorDate: 2025-05-04 20:02:07 +0000
Commit:     Bjoern A. Zeeb <bz@FreeBSD.org>
CommitDate: 2025-05-15 09:50:55 +0000

    LinuxKPI: pci: fix two errors in lkpi_pci_get_device()
    
    On any result we need to acquire a reference. pci_dev_get() deals with
    a NULL argument so we can simply pass what we "found" at the end.
    This will avoid reference count problems.
    
    If the iteration on the linux list in lkpi_pci_get_device() does
    not find a match pdev will still be defined at the end of the
    loop but not pointing to a valid pdev.
    Store the found entry in a 2nd variable which otherwise will be NULL.
    This will avoid random panics, usually in sysfs_remove_dir() when
    the reference gets released.
    
    Found during mt76 bringup.
    
    Sponsored by:   The FreeBSD Foundation
    Fixes:          8f61992d7cc11
    Reviewed by:    dumbbell
    Differential Revision: https://reviews.freebsd.org/D50153
    
    (cherry picked from commit 2c65f965146a7f822302715a439e17996d17453c)
---
 sys/compat/linuxkpi/common/src/linux_pci.c | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/sys/compat/linuxkpi/common/src/linux_pci.c b/sys/compat/linuxkpi/common/src/linux_pci.c
index bee79f0478c8..2c2f92082a4e 100644
--- a/sys/compat/linuxkpi/common/src/linux_pci.c
+++ b/sys/compat/linuxkpi/common/src/linux_pci.c
@@ -288,18 +288,22 @@ linux_pci_find(device_t dev, const struct pci_device_id **idp)
 struct pci_dev *
 lkpi_pci_get_device(uint16_t vendor, uint16_t device, struct pci_dev *odev)
 {
-	struct pci_dev *pdev;
+	struct pci_dev *pdev, *found;
 
 	KASSERT(odev == NULL, ("%s: odev argument not yet supported\n", __func__));
 
+	found = NULL;
 	spin_lock(&pci_lock);
 	list_for_each_entry(pdev, &pci_devices, links) {
-		if (pdev->vendor == vendor && pdev->device == device)
+		if (pdev->vendor == vendor && pdev->device == device) {
+			found = pdev;
 			break;
+		}
 	}
+	pci_dev_get(found);
 	spin_unlock(&pci_lock);
 
-	return (pdev);
+	return (found);
 }
 
 static void



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202505150953.54F9r0j6050780>