[PATCH] drm/qxl: Fix oops caused by missing free_irq on device teardown

From: Jianping Liu

Date: Wed Oct 28 2026 - 05:22:02 EST


From: Jianping Liu <frankjpliu@xxxxxxxxxxx>

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: stable@xxxxxxxxxx
Fixes: f64122c1f6ad ("drm: add new QXL driver. (v1.4)")
Signed-off-by: Jianping Liu <frankjpliu@xxxxxxxxxxx>
---
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