aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBjorn Helgaas <bhelgaas@google.com>2021-11-10 12:01:14 -0600
committerBjorn Helgaas <bhelgaas@google.com>2021-11-11 13:36:14 -0600
commit68da4e0eaaab421f228eac57cbe7505b136464af (patch)
tree72889ae31cb78d297553aa05af627e1430305d2a
parentdda4b381f05d447a0ae31e2e44aeb35d313a311f (diff)
downloadlinux-68da4e0eaaab421f228eac57cbe7505b136464af.tar.gz
Revert "PCI: Remove struct pci_dev->driver"
This reverts commit b5f9c644eb1baafcd349ad134e2110773f8d0a38. Revert b5f9c644eb1b ("PCI: Remove struct pci_dev->driver"), which is needed to revert 2a4d9408c9e8 ("PCI: Use to_pci_driver() instead of pci_dev->driver"). 2a4d9408c9e8 caused a NULL pointer dereference reported by Robert Święcki. Details in the revert of that commit. Fixes: 2a4d9408c9e8 ("PCI: Use to_pci_driver() instead of pci_dev->driver") Link: https://lore.kernel.org/linux-i2c/CAP145pgdrdiMAT7=-iB1DMgA7t_bMqTcJL4N0=6u8kNY3EU0dw@mail.gmail.com/ Reported-by: Robert Święcki <robert@swiecki.net> Tested-by: Robert Święcki <robert@swiecki.net> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
-rw-r--r--drivers/pci/pci-driver.c4
-rw-r--r--include/linux/pci.h1
2 files changed, 5 insertions, 0 deletions
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
index 1d98c974381cfe..4c1f46dbfa8768 100644
--- a/drivers/pci/pci-driver.c
+++ b/drivers/pci/pci-driver.c
@@ -319,10 +319,12 @@ static long local_pci_probe(void *_ddi)
* its remove routine.
*/
pm_runtime_get_sync(dev);
+ pci_dev->driver = pci_drv;
rc = pci_drv->probe(pci_dev, ddi->id);
if (!rc)
return rc;
if (rc < 0) {
+ pci_dev->driver = NULL;
pm_runtime_put_sync(dev);
return rc;
}
@@ -388,6 +390,7 @@ static int pci_call_probe(struct pci_driver *drv, struct pci_dev *dev,
* @pci_dev: PCI device being probed
*
* returns 0 on success, else error.
+ * side-effect: pci_dev->driver is set to drv when drv claims pci_dev.
*/
static int __pci_device_probe(struct pci_driver *drv, struct pci_dev *pci_dev)
{
@@ -462,6 +465,7 @@ static void pci_device_remove(struct device *dev)
pm_runtime_put_noidle(dev);
}
pcibios_free_irq(pci_dev);
+ pci_dev->driver = NULL;
pci_iov_remove(pci_dev);
/* Undo the runtime PM settings in local_pci_probe() */
diff --git a/include/linux/pci.h b/include/linux/pci.h
index b4dbcc86b3f133..e58888e21ab736 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -342,6 +342,7 @@ struct pci_dev {
u16 pcie_flags_reg; /* Cached PCIe Capabilities Register */
unsigned long *dma_alias_mask;/* Mask of enabled devfn aliases */
+ struct pci_driver *driver; /* Driver bound to this device */
u64 dma_mask; /* Mask of the bits of bus address this
device implements. Normally this is
0xffffffff. You only need to change