]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
drm/panthor: Fix theoretical IOMEM access in suspended state
authorBoris Brezillon <boris.brezillon@collabora.com>
Thu, 25 Jun 2026 12:40:31 +0000 (14:40 +0200)
committerLiviu Dudau <liviu.dudau@arm.com>
Tue, 30 Jun 2026 14:26:55 +0000 (15:26 +0100)
In theory, our hardirq handler can be called while the device (and
thus the panthor_irq) is suspended, because the IRQ line is shared.
In practice though, in all the designs we've seen, the line is only
shared within the GPU, and because sub-component suspend state is
consistent (all-suspended or all-resumed), we shouldn't end up with
an interrupt triggered while we're suspended.

Fix the problem anyway, if nothing else, for our sanity.

Fixes: 0b2d86670a84 ("drm/panthor: Rework panthor_irq::suspended into panthor_irq::state")
Reported-by: sashiko-bot@kernel.org
Closes: https://sashiko.dev/#/patchset/20260625-panthor-signal-from-irq-v4-0-3d2908912afa@collabora.com?part=1
Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
Reviewed-by: Liviu Dudau <liviu.dudau@arm.com>
Signed-off-by: Liviu Dudau <liviu.dudau@arm.com>
Link: https://patch.msgid.link/20260625-panthor-misc-fixes-v1-5-b67ed973fea6@collabora.com
drivers/gpu/drm/panthor/panthor_device.h

index a412a50eec76c761c0b61d23d2f40fd283cb8097..291e0de154bcb196514633b173b97b048d67ec8e 100644 (file)
@@ -509,9 +509,6 @@ static irqreturn_t panthor_ ## __name ## _irq_raw_handler(int irq, void *data)
        struct panthor_irq *pirq = data;                                                        \
        enum panthor_irq_state old_state;                                                       \
                                                                                                \
-       if (!gpu_read(pirq->iomem, INT_STAT))                                                   \
-               return IRQ_NONE;                                                                \
-                                                                                               \
        guard(spinlock_irqsave)(&pirq->mask_lock);                                              \
        old_state = atomic_cmpxchg(&pirq->state,                                                \
                                   PANTHOR_IRQ_STATE_ACTIVE,                                    \
@@ -519,6 +516,13 @@ static irqreturn_t panthor_ ## __name ## _irq_raw_handler(int irq, void *data)
        if (old_state != PANTHOR_IRQ_STATE_ACTIVE)                                              \
                return IRQ_NONE;                                                                \
                                                                                                \
+       if (!gpu_read(pirq->iomem, INT_STAT)) {                                                 \
+               atomic_cmpxchg(&pirq->state,                                                    \
+                              PANTHOR_IRQ_STATE_PROCESSING,                                    \
+                              PANTHOR_IRQ_STATE_ACTIVE);                                       \
+               return IRQ_NONE;                                                                \
+       }                                                                                       \
+                                                                                               \
        gpu_write(pirq->iomem, INT_MASK, 0);                                                    \
        return IRQ_WAKE_THREAD;                                                                 \
 }                                                                                              \