bin_bo_alloc() arms the out-of-memory interrupt once it has allocated the
binner BO, and accessing a V3D register requires the block to be powered.
vc4_submit_cl_ioctl() already holds a runtime PM reference by the time it
reaches vc4_get_bcl(), but vc4_create_bo_ioctl() reaches vc4_grab_bin_bo()
without one, so the write can land on a suspended device.

Take the reference in vc4_v3d_bin_bo_get(), which covers both callers, and
take it before bin_bo_lock so that runtime PM is never waited for with the
mutex held.

Fixes: 35c8b4b2c0fe ("drm/vc4: Allocate binner bo when starting to use the V3D")
Signed-off-by: Maíra Canal <[email protected]>
---
 drivers/gpu/drm/vc4/vc4_v3d.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/vc4/vc4_v3d.c b/drivers/gpu/drm/vc4/vc4_v3d.c
index b943a003bcbc..9aa8985e0428 100644
--- a/drivers/gpu/drm/vc4/vc4_v3d.c
+++ b/drivers/gpu/drm/vc4/vc4_v3d.c
@@ -305,11 +305,15 @@ static int bin_bo_alloc(struct vc4_dev *vc4)
 
 int vc4_v3d_bin_bo_get(struct vc4_dev *vc4, bool *used)
 {
-       int ret = 0;
+       int ret;
 
        if (WARN_ON_ONCE(vc4->gen > VC4_GEN_4))
                return -ENODEV;
 
+       ret = vc4_v3d_pm_get(vc4);
+       if (ret)
+               return ret;
+
        mutex_lock(&vc4->bin_bo_lock);
 
        if (used && *used)
@@ -325,6 +329,7 @@ int vc4_v3d_bin_bo_get(struct vc4_dev *vc4, bool *used)
 
 complete:
        mutex_unlock(&vc4->bin_bo_lock);
+       vc4_v3d_pm_put(vc4);
 
        return ret;
 }

-- 
2.55.0

Reply via email to