}
EXPORT_SYMBOL_GPL(driver_attach);
+void *vfio_pci_driver_ptr = (void *)0xdeadfeed;
+EXPORT_SYMBOL(vfio_pci_driver_ptr);
+
/*
* __device_release_driver() must be called with @dev lock held.
* When called for a USB interface, @dev->parent lock must be held as well.
* A concurrent invocation of the same function might
* have released the driver successfully while this one
* was waiting, so check for that.
+ * LP: #1792099
+ *
+ * Limit this to the vfio_pci_driver as some drivers NULL
+ * out this pointer in their remove() function.
+ * LP: #1803942
*/
- if (dev->driver != drv)
+ if (drv == vfio_pci_driver_ptr && dev->driver != drv)
return;
device_links_driver_cleanup(dev);
.remove = vfio_pci_remove,
.err_handler = &vfio_err_handlers,
};
+extern void *vfio_pci_driver_ptr;
struct vfio_devices {
struct vfio_device **devices;
static void __exit vfio_pci_cleanup(void)
{
+ vfio_pci_driver_ptr = (void *)0xdeadfeed;
+
pci_unregister_driver(&vfio_pci_driver);
vfio_pci_uninit_perm_bits();
}
vfio_pci_fill_ids();
+ /* Advertise my address. */
+ vfio_pci_driver_ptr = &vfio_pci_driver;
+
return 0;
out_driver: