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.

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 0182b72f1932..0b862d3c3605 100644
--- a/drivers/gpu/drm/panthor/panthor_mmu.c
+++ b/drivers/gpu/drm/panthor/panthor_mmu.c
@@ -3365,6 +3365,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 5832dccfc093..f18b2e03f2fd 100644
--- a/drivers/gpu/drm/panthor/panthor_sched.c
+++ b/drivers/gpu/drm/panthor/panthor_sched.c
@@ -4074,6 +4074,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