Skip to content

Commit e0217c5

Browse files
committed
Revert "PCI: Use to_pci_driver() instead of pci_dev->driver"
This reverts commit 2a4d940. 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 2a4d940 ("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. 2a4d940 and b5f9c64 ("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: 2a4d940 ("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 <[email protected]> Tested-by: Robert Święcki <[email protected]> Signed-off-by: Bjorn Helgaas <[email protected]>
1 parent 68da4e0 commit e0217c5

File tree

4 files changed

+37
-45
lines changed

4 files changed

+37
-45
lines changed

drivers/pci/iov.c

Lines changed: 9 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -164,15 +164,13 @@ static ssize_t sriov_vf_total_msix_show(struct device *dev,
164164
char *buf)
165165
{
166166
struct pci_dev *pdev = to_pci_dev(dev);
167-
struct pci_driver *pdrv;
168167
u32 vf_total_msix = 0;
169168

170169
device_lock(dev);
171-
pdrv = to_pci_driver(dev->driver);
172-
if (!pdrv || !pdrv->sriov_get_vf_total_msix)
170+
if (!pdev->driver || !pdev->driver->sriov_get_vf_total_msix)
173171
goto unlock;
174172

175-
vf_total_msix = pdrv->sriov_get_vf_total_msix(pdev);
173+
vf_total_msix = pdev->driver->sriov_get_vf_total_msix(pdev);
176174
unlock:
177175
device_unlock(dev);
178176
return sysfs_emit(buf, "%u\n", vf_total_msix);
@@ -185,7 +183,6 @@ static ssize_t sriov_vf_msix_count_store(struct device *dev,
185183
{
186184
struct pci_dev *vf_dev = to_pci_dev(dev);
187185
struct pci_dev *pdev = pci_physfn(vf_dev);
188-
struct pci_driver *pdrv;
189186
int val, ret = 0;
190187

191188
if (kstrtoint(buf, 0, &val) < 0)
@@ -195,14 +192,13 @@ static ssize_t sriov_vf_msix_count_store(struct device *dev,
195192
return -EINVAL;
196193

197194
device_lock(&pdev->dev);
198-
pdrv = to_pci_driver(dev->driver);
199-
if (!pdrv || !pdrv->sriov_set_msix_vec_count) {
195+
if (!pdev->driver || !pdev->driver->sriov_set_msix_vec_count) {
200196
ret = -EOPNOTSUPP;
201197
goto err_pdev;
202198
}
203199

204200
device_lock(&vf_dev->dev);
205-
if (to_pci_driver(vf_dev->dev.driver)) {
201+
if (vf_dev->driver) {
206202
/*
207203
* A driver is already attached to this VF and has configured
208204
* 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,
212208
goto err_dev;
213209
}
214210

215-
ret = pdrv->sriov_set_msix_vec_count(vf_dev, val);
211+
ret = pdev->driver->sriov_set_msix_vec_count(vf_dev, val);
216212

217213
err_dev:
218214
device_unlock(&vf_dev->dev);
@@ -379,7 +375,6 @@ static ssize_t sriov_numvfs_store(struct device *dev,
379375
const char *buf, size_t count)
380376
{
381377
struct pci_dev *pdev = to_pci_dev(dev);
382-
struct pci_driver *pdrv;
383378
int ret = 0;
384379
u16 num_vfs;
385380

@@ -395,23 +390,22 @@ static ssize_t sriov_numvfs_store(struct device *dev,
395390
goto exit;
396391

397392
/* is PF driver loaded */
398-
pdrv = to_pci_driver(dev->driver);
399-
if (!pdrv) {
393+
if (!pdev->driver) {
400394
pci_info(pdev, "no driver bound to device; cannot configure SR-IOV\n");
401395
ret = -ENOENT;
402396
goto exit;
403397
}
404398

405399
/* is PF driver loaded w/callback */
406-
if (!pdrv->sriov_configure) {
400+
if (!pdev->driver->sriov_configure) {
407401
pci_info(pdev, "driver does not support SR-IOV configuration via sysfs\n");
408402
ret = -ENOENT;
409403
goto exit;
410404
}
411405

412406
if (num_vfs == 0) {
413407
/* disable VFs */
414-
ret = pdrv->sriov_configure(pdev, 0);
408+
ret = pdev->driver->sriov_configure(pdev, 0);
415409
goto exit;
416410
}
417411

@@ -423,7 +417,7 @@ static ssize_t sriov_numvfs_store(struct device *dev,
423417
goto exit;
424418
}
425419

426-
ret = pdrv->sriov_configure(pdev, num_vfs);
420+
ret = pdev->driver->sriov_configure(pdev, num_vfs);
427421
if (ret < 0)
428422
goto exit;
429423

drivers/pci/pci-driver.c

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -457,7 +457,7 @@ static int pci_device_probe(struct device *dev)
457457
static void pci_device_remove(struct device *dev)
458458
{
459459
struct pci_dev *pci_dev = to_pci_dev(dev);
460-
struct pci_driver *drv = to_pci_driver(dev->driver);
460+
struct pci_driver *drv = pci_dev->driver;
461461

462462
if (drv->remove) {
463463
pm_runtime_get_sync(dev);
@@ -493,7 +493,7 @@ static void pci_device_remove(struct device *dev)
493493
static void pci_device_shutdown(struct device *dev)
494494
{
495495
struct pci_dev *pci_dev = to_pci_dev(dev);
496-
struct pci_driver *drv = to_pci_driver(dev->driver);
496+
struct pci_driver *drv = pci_dev->driver;
497497

498498
pm_runtime_resume(dev);
499499

@@ -589,7 +589,7 @@ static int pci_pm_reenable_device(struct pci_dev *pci_dev)
589589
static int pci_legacy_suspend(struct device *dev, pm_message_t state)
590590
{
591591
struct pci_dev *pci_dev = to_pci_dev(dev);
592-
struct pci_driver *drv = to_pci_driver(dev->driver);
592+
struct pci_driver *drv = pci_dev->driver;
593593

594594
if (drv && drv->suspend) {
595595
pci_power_t prev = pci_dev->current_state;
@@ -630,7 +630,7 @@ static int pci_legacy_suspend_late(struct device *dev, pm_message_t state)
630630
static int pci_legacy_resume(struct device *dev)
631631
{
632632
struct pci_dev *pci_dev = to_pci_dev(dev);
633-
struct pci_driver *drv = to_pci_driver(dev->driver);
633+
struct pci_driver *drv = pci_dev->driver;
634634

635635
pci_fixup_device(pci_fixup_resume, pci_dev);
636636

@@ -649,7 +649,7 @@ static void pci_pm_default_suspend(struct pci_dev *pci_dev)
649649

650650
static bool pci_has_legacy_pm_support(struct pci_dev *pci_dev)
651651
{
652-
struct pci_driver *drv = to_pci_driver(pci_dev->dev.driver);
652+
struct pci_driver *drv = pci_dev->driver;
653653
bool ret = drv && (drv->suspend || drv->resume);
654654

655655
/*
@@ -1242,11 +1242,11 @@ static int pci_pm_runtime_suspend(struct device *dev)
12421242
int error;
12431243

12441244
/*
1245-
* If the device has no driver, we leave it in D0, but it may go to
1246-
* D3cold when the bridge above it runtime suspends. Save its
1247-
* config space in case that happens.
1245+
* If pci_dev->driver is not set (unbound), we leave the device in D0,
1246+
* but it may go to D3cold when the bridge above it runtime suspends.
1247+
* Save its config space in case that happens.
12481248
*/
1249-
if (!to_pci_driver(dev->driver)) {
1249+
if (!pci_dev->driver) {
12501250
pci_save_state(pci_dev);
12511251
return 0;
12521252
}
@@ -1303,7 +1303,7 @@ static int pci_pm_runtime_resume(struct device *dev)
13031303
*/
13041304
pci_restore_standard_config(pci_dev);
13051305

1306-
if (!to_pci_driver(dev->driver))
1306+
if (!pci_dev->driver)
13071307
return 0;
13081308

13091309
pci_fixup_device(pci_fixup_resume_early, pci_dev);
@@ -1322,13 +1322,14 @@ static int pci_pm_runtime_resume(struct device *dev)
13221322

13231323
static int pci_pm_runtime_idle(struct device *dev)
13241324
{
1325+
struct pci_dev *pci_dev = to_pci_dev(dev);
13251326
const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
13261327

13271328
/*
1328-
* If the device has no driver, it should always remain in D0
1329-
* regardless of the runtime PM status
1329+
* If pci_dev->driver is not set (unbound), the device should
1330+
* always remain in D0 regardless of the runtime PM status
13301331
*/
1331-
if (!to_pci_driver(dev->driver))
1332+
if (!pci_dev->driver)
13321333
return 0;
13331334

13341335
if (!pm)
@@ -1435,10 +1436,8 @@ static struct pci_driver pci_compat_driver = {
14351436
*/
14361437
struct pci_driver *pci_dev_driver(const struct pci_dev *dev)
14371438
{
1438-
struct pci_driver *drv = to_pci_driver(dev->dev.driver);
1439-
1440-
if (drv)
1441-
return drv;
1439+
if (dev->driver)
1440+
return dev->driver;
14421441
else {
14431442
int i;
14441443
for (i = 0; i <= PCI_ROM_RESOURCE; i++)

drivers/pci/pci.c

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5123,14 +5123,13 @@ EXPORT_SYMBOL_GPL(pci_dev_unlock);
51235123

51245124
static void pci_dev_save_and_disable(struct pci_dev *dev)
51255125
{
5126-
struct pci_driver *drv = to_pci_driver(dev->dev.driver);
51275126
const struct pci_error_handlers *err_handler =
5128-
drv ? drv->err_handler : NULL;
5127+
dev->driver ? dev->driver->err_handler : NULL;
51295128

51305129
/*
5131-
* drv->err_handler->reset_prepare() is protected against races
5132-
* with ->remove() by the device lock, which must be held by the
5133-
* caller.
5130+
* dev->driver->err_handler->reset_prepare() is protected against
5131+
* races with ->remove() by the device lock, which must be held by
5132+
* the caller.
51345133
*/
51355134
if (err_handler && err_handler->reset_prepare)
51365135
err_handler->reset_prepare(dev);
@@ -5155,15 +5154,15 @@ static void pci_dev_save_and_disable(struct pci_dev *dev)
51555154

51565155
static void pci_dev_restore(struct pci_dev *dev)
51575156
{
5158-
struct pci_driver *drv = to_pci_driver(dev->dev.driver);
51595157
const struct pci_error_handlers *err_handler =
5160-
drv ? drv->err_handler : NULL;
5158+
dev->driver ? dev->driver->err_handler : NULL;
51615159

51625160
pci_restore_state(dev);
51635161

51645162
/*
5165-
* drv->err_handler->reset_done() is protected against races with
5166-
* ->remove() by the device lock, which must be held by the caller.
5163+
* dev->driver->err_handler->reset_done() is protected against
5164+
* races with ->remove() by the device lock, which must be held by
5165+
* the caller.
51675166
*/
51685167
if (err_handler && err_handler->reset_done)
51695168
err_handler->reset_done(dev);

drivers/pci/pcie/err.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ static int report_error_detected(struct pci_dev *dev,
5454
const struct pci_error_handlers *err_handler;
5555

5656
device_lock(&dev->dev);
57-
pdrv = to_pci_driver(dev->dev.driver);
57+
pdrv = dev->driver;
5858
if (!pci_dev_set_io_state(dev, state) ||
5959
!pdrv ||
6060
!pdrv->err_handler ||
@@ -98,7 +98,7 @@ static int report_mmio_enabled(struct pci_dev *dev, void *data)
9898
const struct pci_error_handlers *err_handler;
9999

100100
device_lock(&dev->dev);
101-
pdrv = to_pci_driver(dev->dev.driver);
101+
pdrv = dev->driver;
102102
if (!pdrv ||
103103
!pdrv->err_handler ||
104104
!pdrv->err_handler->mmio_enabled)
@@ -119,7 +119,7 @@ static int report_slot_reset(struct pci_dev *dev, void *data)
119119
const struct pci_error_handlers *err_handler;
120120

121121
device_lock(&dev->dev);
122-
pdrv = to_pci_driver(dev->dev.driver);
122+
pdrv = dev->driver;
123123
if (!pdrv ||
124124
!pdrv->err_handler ||
125125
!pdrv->err_handler->slot_reset)
@@ -139,7 +139,7 @@ static int report_resume(struct pci_dev *dev, void *data)
139139
const struct pci_error_handlers *err_handler;
140140

141141
device_lock(&dev->dev);
142-
pdrv = to_pci_driver(dev->dev.driver);
142+
pdrv = dev->driver;
143143
if (!pci_dev_set_io_state(dev, pci_channel_io_normal) ||
144144
!pdrv ||
145145
!pdrv->err_handler ||

0 commit comments

Comments
 (0)