Since commit 541c8f2468b9 ("dma-buf: detach fence ops on signal v3"),
fence->ops may be set to NULL via RCU when a fence signals and has no
release/wait ops. ttm_bo_flush_all_fences() was not updated to handle
this and directly dereferences fence->ops->signaled, leading to a NULL
pointer dereference crash:

```
BUG: kernel NULL pointer dereference, address: 0000000000000018
RIP: 0010:ttm_bo_release+0x1bc/0x330 [ttm]
```

Since dma_fence_enable_sw_signaling() already handles the signaled case
internally (it checks DMA_FENCE_FLAG_SIGNALED_BIT before doing anything),
the ops->signaled pre-check is redundant. Simply remove it and call
dma_fence_enable_sw_signaling() unconditionally for each fence.

Closes: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/15759
Fixes: 541c8f2468b9 ("dma-buf: detach fence ops on signal v3")
Cc: Christian König <[email protected]>
Signed-off-by: Sebastian Brzezinka <[email protected]>
---
 drivers/gpu/drm/ttm/ttm_bo.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c
index acb9197db879..0485ad00a3df 100644
--- a/drivers/gpu/drm/ttm/ttm_bo.c
+++ b/drivers/gpu/drm/ttm/ttm_bo.c
@@ -222,10 +222,8 @@ static void ttm_bo_flush_all_fences(struct 
ttm_buffer_object *bo)
        struct dma_fence *fence;
 
        dma_resv_iter_begin(&cursor, resv, DMA_RESV_USAGE_BOOKKEEP);
-       dma_resv_for_each_fence_unlocked(&cursor, fence) {
-               if (!fence->ops->signaled)
-                       dma_fence_enable_sw_signaling(fence);
-       }
+       dma_resv_for_each_fence_unlocked(&cursor, fence)
+               dma_fence_enable_sw_signaling(fence);
        dma_resv_iter_end(&cursor);
 }
 
-- 
2.52.0

Reply via email to