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

In order to flush the panthor_cleanup_wq before device destruction, we
simply register a drmm action. This action is intentionally inserted
before any of the subcomponent _init() function to make sure we flush
any cleanup work that might have been queued in there if the
initialization fails.

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_device.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/drivers/gpu/drm/panthor/panthor_device.c 
b/drivers/gpu/drm/panthor/panthor_device.c
index 7d336f160d1f..b7c55a6f4f08 100644
--- a/drivers/gpu/drm/panthor/panthor_device.c
+++ b/drivers/gpu/drm/panthor/panthor_device.c
@@ -167,6 +167,14 @@ static void panthor_device_free_page(struct drm_device 
*ddev, void *data)
        __free_page(data);
 }
 
+static void panthor_device_flush_cleanup_wq(struct drm_device *ddev, void 
*data)
+{
+       /* Make sure works queued to panthor_cleanup_wq are executed
+        * before the device is destroyed.
+        */
+       flush_workqueue(panthor_cleanup_wq);
+}
+
 int panthor_device_init(struct panthor_device *ptdev)
 {
        u32 *dummy_page_virt;
@@ -220,6 +228,10 @@ int panthor_device_init(struct panthor_device *ptdev)
        if (ret)
                return ret;
 
+       ret = drmm_add_action(&ptdev->base, panthor_device_flush_cleanup_wq, 
NULL);
+       if (ret)
+               return ret;
+
        ret = panthor_clk_init(ptdev);
        if (ret)
                return ret;

-- 
2.55.0

Reply via email to