]> www.infradead.org Git - users/dwmw2/linux.git/commitdiff
drm/msm/a7xx: Call CP_RESET_CONTEXT_STATE
authorConnor Abbott <cwabbott0@gmail.com>
Tue, 20 May 2025 22:28:06 +0000 (18:28 -0400)
committerRob Clark <robin.clark@oss.qualcomm.com>
Mon, 9 Jun 2025 19:48:55 +0000 (12:48 -0700)
Calling this packet is necessary when we switch contexts because there
are various pieces of state used by userspace to synchronize between BR
and BV that are persistent across submits and we need to make sure that
they are in a "safe" state when switching contexts. Otherwise a
userspace submission in one context could cause another context to
function incorrectly and hang, effectively a denial of service (although
without leaking data). This was missed during initial a7xx bringup.

Fixes: af66706accdf ("drm/msm/a6xx: Add skeleton A7xx support")
Signed-off-by: Connor Abbott <cwabbott0@gmail.com>
Patchwork: https://patchwork.freedesktop.org/patch/654924/
Signed-off-by: Rob Clark <robin.clark@oss.qualcomm.com>
drivers/gpu/drm/msm/adreno/a6xx_gpu.c

index a7ffd92de3bb76c5c04b6621ec68938ffe3911b2..491fde0083a202bec7c6b3bca88d0e5a717a6560 100644 (file)
@@ -130,6 +130,20 @@ static void a6xx_set_pagetable(struct a6xx_gpu *a6xx_gpu,
                OUT_RING(ring, lower_32_bits(rbmemptr(ring, fence)));
                OUT_RING(ring, upper_32_bits(rbmemptr(ring, fence)));
                OUT_RING(ring, submit->seqno - 1);
+
+               OUT_PKT7(ring, CP_THREAD_CONTROL, 1);
+               OUT_RING(ring, CP_SET_THREAD_BOTH);
+
+               /* Reset state used to synchronize BR and BV */
+               OUT_PKT7(ring, CP_RESET_CONTEXT_STATE, 1);
+               OUT_RING(ring,
+                        CP_RESET_CONTEXT_STATE_0_CLEAR_ON_CHIP_TS |
+                        CP_RESET_CONTEXT_STATE_0_CLEAR_RESOURCE_TABLE |
+                        CP_RESET_CONTEXT_STATE_0_CLEAR_BV_BR_COUNTER |
+                        CP_RESET_CONTEXT_STATE_0_RESET_GLOBAL_LOCAL_TS);
+
+               OUT_PKT7(ring, CP_THREAD_CONTROL, 1);
+               OUT_RING(ring, CP_SET_THREAD_BR);
        }
 
        if (!sysprof) {