From: Jianping Liu <[email protected]>

After qxl.ko is unloaded, reading /proc/interrupts triggers an oops.
qxl_irq_init() requests the PCI IRQ with the DRM device as dev_id, but
qxl_device_fini() never frees it. The IRQ action therefore stays
registered, and its name still points into the unloaded module.

To fix the oops, free the IRQ in qxl_device_fini() with the same
dev_id passed to request_irq().

Cc: [email protected]
Fixes: f64122c1f6ad ("drm: add new QXL driver. (v1.4)")
Signed-off-by: Jianping Liu <[email protected]>
---
 drivers/gpu/drm/qxl/qxl_kms.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/gpu/drm/qxl/qxl_kms.c b/drivers/gpu/drm/qxl/qxl_kms.c
index 461b7ab9ad5c..e6c3d5ebd7c4 100644
--- a/drivers/gpu/drm/qxl/qxl_kms.c
+++ b/drivers/gpu/drm/qxl/qxl_kms.c
@@ -284,6 +284,8 @@ int qxl_device_init(struct qxl_device *qdev,
 void qxl_device_fini(struct qxl_device *qdev)
 {
        int cur_idx;
+       struct drm_device *ddev = &qdev->ddev;
+       struct pci_dev *pdev = to_pci_dev(ddev->dev);
 
        /* check if qxl_device_init() was successful (gc_work is initialized 
last) */
        if (!qdev->gc_work.func)
@@ -306,6 +308,7 @@ void qxl_device_fini(struct qxl_device *qdev)
        wait_event_timeout(qdev->release_event,
                           atomic_read(&qdev->release_count) == 0,
                           HZ);
+       free_irq(pdev->irq, ddev);
        flush_work(&qdev->gc_work);
        qxl_surf_evict(qdev);
        qxl_vram_evict(qdev);
-- 
2.43.7

Reply via email to