If we don't do that, we might face various UAFs, because the resource
referenced by these work items might be gone by the time they get
executed.

In each subcomponent making use of the panthor_cleanup_wq, we add a
flush_workqueue() at the end of the _unplug() function. Note that this
assumes no more work items from this subcomponent gets queued after
that point, which is not yet guaranteed, but this will be fixed in
upcoming changes.

Fixes: de8548813824 ("drm/panthor: Add the scheduler logical block")
Fixes: 647810ec2476 ("drm/panthor: Add the MMU/VM logical block")
Reported-by: [email protected]
Closes: 
https://sashiko.dev/#/patchset/[email protected]?part=2
Signed-off-by: Boris Brezillon <[email protected]>
---
 drivers/gpu/drm/panthor/panthor_mmu.c   | 6 ++++++
 drivers/gpu/drm/panthor/panthor_sched.c | 6 ++++++
 2 files changed, 12 insertions(+)

diff --git a/drivers/gpu/drm/panthor/panthor_mmu.c 
b/drivers/gpu/drm/panthor/panthor_mmu.c
index d43ba1c7cd2a..1385ee28bee5 100644
--- a/drivers/gpu/drm/panthor/panthor_mmu.c
+++ b/drivers/gpu/drm/panthor/panthor_mmu.c
@@ -3367,6 +3367,12 @@ void panthor_mmu_unplug(struct panthor_device *ptdev)
                }
        }
        mutex_unlock(&ptdev->mmu->as.slots_lock);
+
+       /* Ensure any pending job cleanup work are executed before returning,
+        * otherwise those might access objects that are gone if the work is
+        * executed after other components are unplugged.
+        */
+       flush_workqueue(panthor_cleanup_wq);
 }
 
 static void panthor_mmu_release_wq(struct drm_device *ddev, void *res)
diff --git a/drivers/gpu/drm/panthor/panthor_sched.c 
b/drivers/gpu/drm/panthor/panthor_sched.c
index 42adfc76b9e1..a6d57dc1b43e 100644
--- a/drivers/gpu/drm/panthor/panthor_sched.c
+++ b/drivers/gpu/drm/panthor/panthor_sched.c
@@ -4049,6 +4049,12 @@ void panthor_sched_unplug(struct panthor_device *ptdev)
                sched->pm.has_ref = false;
        }
        mutex_unlock(&sched->lock);
+
+       /* Ensure any pending group release work are executed before returning,
+        * otherwise those might access objects that are gone if the work is
+        * executed after other components are unplugged.
+        */
+       flush_workqueue(panthor_cleanup_wq);
 }
 
 static void panthor_sched_fini(struct drm_device *ddev, void *res)

-- 
2.55.0

Reply via email to