diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c index 3cef835b375fd6a6adaacd1384987a5f905e9c46..ff1170dd172dddc9bcf671b9483d3ba797657af3 100644 --- a/drivers/pci/bus.c +++ b/drivers/pci/bus.c @@ -413,9 +413,11 @@ struct pci_bus *pci_bus_get(struct pci_bus *bus) get_device(&bus->dev); return bus; } +EXPORT_SYMBOL(pci_bus_get); void pci_bus_put(struct pci_bus *bus) { if (bus) put_device(&bus->dev); } +EXPORT_SYMBOL(pci_bus_put); diff --git a/drivers/pci/pcie/aer_inject.c b/drivers/pci/pcie/aer_inject.c index c2cbf425afc52ca8d28310c8ff58c87c913227b7..4dc1d95f085bc892edb5d1f769f7ce0394782276 100644 --- a/drivers/pci/pcie/aer_inject.c +++ b/drivers/pci/pcie/aer_inject.c @@ -26,6 +26,7 @@ #include #include "portdrv.h" +#include "../pci.h" /* Override the existing corrected and uncorrected error masks */ static bool aer_mask_override; @@ -307,6 +308,13 @@ static int pci_bus_set_aer_ops(struct pci_bus *bus) spin_lock_irqsave(&inject_lock, flags); if (ops == &aer_inj_pci_ops) goto out; + /* + * increments the reference count of the pci bus. Otherwise, when we + * restore the 'pci_ops' in 'aer_inject_exit', the 'pci_bus' may have + * been freed. + */ + pci_bus_get(bus); + pci_bus_ops_init(bus_ops, bus, ops); list_add(&bus_ops->list, &pci_bus_ops_list); bus_ops = NULL; @@ -527,6 +535,7 @@ static void __exit aer_inject_exit(void) while ((bus_ops = pci_bus_ops_pop())) { pci_bus_set_ops(bus_ops->bus, bus_ops->ops); + pci_bus_put(bus_ops->bus); kfree(bus_ops); }