From e0217c5ba10d7bf640f038b2feae58e630f2f958 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Wed, 10 Nov 2021 12:03:34 -0600 Subject: Revert "PCI: Use to_pci_driver() instead of pci_dev->driver" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 2a4d9408c9e8b6f6fc150c66f3fef755c9e20d4a. Robert reported a NULL pointer dereference caused by the PCI core (local_pci_probe()) calling the i2c_designware_pci driver's .runtime_resume() method before the .probe() method. i2c_dw_pci_resume() depends on initialization done by i2c_dw_pci_probe(). Prior to 2a4d9408c9e8 ("PCI: Use to_pci_driver() instead of pci_dev->driver"), pci_pm_runtime_resume() avoided calling the .runtime_resume() method because pci_dev->driver had not been set yet. 2a4d9408c9e8 and b5f9c644eb1b ("PCI: Remove struct pci_dev->driver"), removed pci_dev->driver, replacing it by device->driver, which *has* been set by this time, so pci_pm_runtime_resume() called the .runtime_resume() method when it previously had not. 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 Tested-by: Robert Święcki Signed-off-by: Bjorn Helgaas --- drivers/pci/iov.c | 24 +++++++++--------------- 1 file changed, 9 insertions(+), 15 deletions(-) (limited to 'drivers/pci/iov.c') diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c index 1d7a7c5b5307..0267977c9f17 100644 --- a/drivers/pci/iov.c +++ b/drivers/pci/iov.c @@ -164,15 +164,13 @@ static ssize_t sriov_vf_total_msix_show(struct device *dev, char *buf) { struct pci_dev *pdev = to_pci_dev(dev); - struct pci_driver *pdrv; u32 vf_total_msix = 0; device_lock(dev); - pdrv = to_pci_driver(dev->driver); - if (!pdrv || !pdrv->sriov_get_vf_total_msix) + if (!pdev->driver || !pdev->driver->sriov_get_vf_total_msix) goto unlock; - vf_total_msix = pdrv->sriov_get_vf_total_msix(pdev); + vf_total_msix = pdev->driver->sriov_get_vf_total_msix(pdev); unlock: device_unlock(dev); return sysfs_emit(buf, "%u\n", vf_total_msix); @@ -185,7 +183,6 @@ static ssize_t sriov_vf_msix_count_store(struct device *dev, { struct pci_dev *vf_dev = to_pci_dev(dev); struct pci_dev *pdev = pci_physfn(vf_dev); - struct pci_driver *pdrv; int val, ret = 0; if (kstrtoint(buf, 0, &val) < 0) @@ -195,14 +192,13 @@ static ssize_t sriov_vf_msix_count_store(struct device *dev, return -EINVAL; device_lock(&pdev->dev); - pdrv = to_pci_driver(dev->driver); - if (!pdrv || !pdrv->sriov_set_msix_vec_count) { + if (!pdev->driver || !pdev->driver->sriov_set_msix_vec_count) { ret = -EOPNOTSUPP; goto err_pdev; } device_lock(&vf_dev->dev); - if (to_pci_driver(vf_dev->dev.driver)) { + if (vf_dev->driver) { /* * A driver is already attached to this VF and has configured * itself based on the current MSI-X vector count. Changing @@ -212,7 +208,7 @@ static ssize_t sriov_vf_msix_count_store(struct device *dev, goto err_dev; } - ret = pdrv->sriov_set_msix_vec_count(vf_dev, val); + ret = pdev->driver->sriov_set_msix_vec_count(vf_dev, val); err_dev: device_unlock(&vf_dev->dev); @@ -379,7 +375,6 @@ static ssize_t sriov_numvfs_store(struct device *dev, const char *buf, size_t count) { struct pci_dev *pdev = to_pci_dev(dev); - struct pci_driver *pdrv; int ret = 0; u16 num_vfs; @@ -395,15 +390,14 @@ static ssize_t sriov_numvfs_store(struct device *dev, goto exit; /* is PF driver loaded */ - pdrv = to_pci_driver(dev->driver); - if (!pdrv) { + if (!pdev->driver) { pci_info(pdev, "no driver bound to device; cannot configure SR-IOV\n"); ret = -ENOENT; goto exit; } /* is PF driver loaded w/callback */ - if (!pdrv->sriov_configure) { + if (!pdev->driver->sriov_configure) { pci_info(pdev, "driver does not support SR-IOV configuration via sysfs\n"); ret = -ENOENT; goto exit; @@ -411,7 +405,7 @@ static ssize_t sriov_numvfs_store(struct device *dev, if (num_vfs == 0) { /* disable VFs */ - ret = pdrv->sriov_configure(pdev, 0); + ret = pdev->driver->sriov_configure(pdev, 0); goto exit; } @@ -423,7 +417,7 @@ static ssize_t sriov_numvfs_store(struct device *dev, goto exit; } - ret = pdrv->sriov_configure(pdev, num_vfs); + ret = pdev->driver->sriov_configure(pdev, num_vfs); if (ret < 0) goto exit; -- cgit v1.2.3