Revert "PCI: Remove struct pci_dev->driver"
authorBjorn Helgaas <bhelgaas@google.com>
Wed, 10 Nov 2021 18:01:14 +0000 (12:01 -0600)
committerBjorn Helgaas <bhelgaas@google.com>
Thu, 11 Nov 2021 19:36:14 +0000 (13:36 -0600)
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>
drivers/pci/pci-driver.c
include/linux/pci.h

index 1d98c974381cfec850461eadc3e91c7086198381..4c1f46dbfa87688eaa2eed548d0a5332a1f8ff30 100644 (file)
@@ -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() */
index b4dbcc86b3f1334c8567a485366d5c30d5611f35..e58888e21ab7362427bc8d415e4bd14ec589ae8b 100644 (file)
@@ -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