powerpc/eeh: Fix use-after-release of EEH driver

Correct two cases where eeh_pcid_get() is used to reference the driver's
module but the reference is dropped before the driver pointer is used.

In eeh_rmv_device() also refactor a little so that only two calls to
eeh_pcid_put() are needed, rather than three and the reference isn't
taken at all if it wasn't needed.

Signed-off-by: Sam Bobroff <sbobroff@linux.ibm.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
This commit is contained in:
Sam Bobroff 2018-05-25 13:11:30 +10:00 committed by Michael Ellerman
parent 796b9f5b31
commit 46d4be41b9
1 changed files with 16 additions and 12 deletions

View File

@ -458,9 +458,11 @@ static void *eeh_add_virt_device(void *data, void *userdata)
driver = eeh_pcid_get(dev);
if (driver) {
eeh_pcid_put(dev);
if (driver->err_handler)
if (driver->err_handler) {
eeh_pcid_put(dev);
return NULL;
}
eeh_pcid_put(dev);
}
#ifdef CONFIG_PCI_IOV
@ -497,17 +499,19 @@ static void *eeh_rmv_device(void *data, void *userdata)
if (eeh_dev_removed(edev))
return NULL;
driver = eeh_pcid_get(dev);
if (driver) {
eeh_pcid_put(dev);
if (removed &&
eeh_pe_passed(edev->pe))
return NULL;
if (removed &&
driver->err_handler &&
driver->err_handler->error_detected &&
driver->err_handler->slot_reset)
if (removed) {
if (eeh_pe_passed(edev->pe))
return NULL;
driver = eeh_pcid_get(dev);
if (driver) {
if (driver->err_handler &&
driver->err_handler->error_detected &&
driver->err_handler->slot_reset) {
eeh_pcid_put(dev);
return NULL;
}
eeh_pcid_put(dev);
}
}
/* Remove it from PCI subsystem */