Skip to content

Commit 94c4aa2

Browse files
matt-auldrodrigovivi
authored andcommitted
drm/xe/client: add missing bo locking in show_meminfo()
bo_meminfo() wants to inspect bo state like tt and the ttm resource, however this state can change at any point leading to stuff like NPD and UAF, if the bo lock is not held. Grab the bo lock when calling bo_meminfo(), ensuring we drop any spinlocks first. In the case of object_idr we now also need to hold a ref. v2 (MattB) - Also add xe_bo_assert_held() Fixes: 0845233 ("drm/xe: Implement fdinfo memory stats printing") Signed-off-by: Matthew Auld <matthew.auld@intel.com> Cc: Himal Prasad Ghimiray <himal.prasad.ghimiray@intel.com> Cc: Tejas Upadhyay <tejas.upadhyay@intel.com> Cc: "Thomas Hellström" <thomas.hellstrom@linux.intel.com> Cc: <stable@vger.kernel.org> # v6.8+ Reviewed-by: Matthew Brost <matthew.brost@intel.com> Reviewed-by: Tejas Upadhyay <tejas.upadhyay@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240911155527.178910-6-matthew.auld@intel.com (cherry picked from commit 4f63d71) Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
1 parent 9bd7ff2 commit 94c4aa2

File tree

1 file changed

+36
-3
lines changed

1 file changed

+36
-3
lines changed

drivers/gpu/drm/xe/xe_drm_client.c

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include <linux/slab.h>
1111
#include <linux/types.h>
1212

13+
#include "xe_assert.h"
1314
#include "xe_bo.h"
1415
#include "xe_bo_types.h"
1516
#include "xe_device_types.h"
@@ -151,10 +152,13 @@ void xe_drm_client_add_bo(struct xe_drm_client *client,
151152
*/
152153
void xe_drm_client_remove_bo(struct xe_bo *bo)
153154
{
155+
struct xe_device *xe = ttm_to_xe_device(bo->ttm.bdev);
154156
struct xe_drm_client *client = bo->client;
155157

158+
xe_assert(xe, !kref_read(&bo->ttm.base.refcount));
159+
156160
spin_lock(&client->bos_lock);
157-
list_del(&bo->client_link);
161+
list_del_init(&bo->client_link);
158162
spin_unlock(&client->bos_lock);
159163

160164
xe_drm_client_put(client);
@@ -166,6 +170,8 @@ static void bo_meminfo(struct xe_bo *bo,
166170
u64 sz = bo->size;
167171
u32 mem_type;
168172

173+
xe_bo_assert_held(bo);
174+
169175
if (bo->placement.placement)
170176
mem_type = bo->placement.placement->mem_type;
171177
else
@@ -207,7 +213,20 @@ static void show_meminfo(struct drm_printer *p, struct drm_file *file)
207213
idr_for_each_entry(&file->object_idr, obj, id) {
208214
struct xe_bo *bo = gem_to_xe_bo(obj);
209215

210-
bo_meminfo(bo, stats);
216+
if (dma_resv_trylock(bo->ttm.base.resv)) {
217+
bo_meminfo(bo, stats);
218+
xe_bo_unlock(bo);
219+
} else {
220+
xe_bo_get(bo);
221+
spin_unlock(&file->table_lock);
222+
223+
xe_bo_lock(bo, false);
224+
bo_meminfo(bo, stats);
225+
xe_bo_unlock(bo);
226+
227+
xe_bo_put(bo);
228+
spin_lock(&file->table_lock);
229+
}
211230
}
212231
spin_unlock(&file->table_lock);
213232

@@ -217,7 +236,21 @@ static void show_meminfo(struct drm_printer *p, struct drm_file *file)
217236
if (!kref_get_unless_zero(&bo->ttm.base.refcount))
218237
continue;
219238

220-
bo_meminfo(bo, stats);
239+
if (dma_resv_trylock(bo->ttm.base.resv)) {
240+
bo_meminfo(bo, stats);
241+
xe_bo_unlock(bo);
242+
} else {
243+
spin_unlock(&client->bos_lock);
244+
245+
xe_bo_lock(bo, false);
246+
bo_meminfo(bo, stats);
247+
xe_bo_unlock(bo);
248+
249+
spin_lock(&client->bos_lock);
250+
/* The bo ref will prevent this bo from being removed from the list */
251+
xe_assert(xef->xe, !list_empty(&bo->client_link));
252+
}
253+
221254
xe_bo_put_deferred(bo, &deferred);
222255
}
223256
spin_unlock(&client->bos_lock);

0 commit comments

Comments
 (0)