git: 2c65f965146a - main - LinuxKPI: pci: fix two errors in lkpi_pci_get_device()
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Fri, 09 May 2025 19:46:00 UTC
The branch main has been updated by bz:
URL: https://cgit.FreeBSD.org/src/commit/?id=2c65f965146a7f822302715a439e17996d17453c
commit 2c65f965146a7f822302715a439e17996d17453c
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-09 19:45:10 +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
MFC after: 3 days
Fixes: 8f61992d7cc11
Reviewed by: dumbbell
Differential Revision: https://reviews.freebsd.org/D50153
---
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 3651946c6ee5..5cf7c601d615 100644
--- a/sys/compat/linuxkpi/common/src/linux_pci.c
+++ b/sys/compat/linuxkpi/common/src/linux_pci.c
@@ -287,18 +287,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