* FAILED: patch "[PATCH] drm/ttm: Drop tt->restore after successful restore" failed to apply to 6.18-stable tree
@ 2026-09-09 11:54 gregkh
2026-09-12 14:34 ` [PATCH 6.18.y 1/2] drm/ttm: Tidy usage of local variables a little bit Sasha Levin
0 siblings, 1 reply; 6+ messages in thread
From: gregkh @ 2026-09-09 11:54 UTC (permalink / raw)
To: matthew.brost, airlied, christian.koenig, maarten.lankhorst,
matthew.auld, mripard, ray.huang, simona, thomas.hellstrom,
tzimmermann
Cc: stable
The patch below does not apply to the 6.18-stable tree.
If someone wants it applied there, or to any other stable or longterm
tree, then please email the backport, including the original git commit
id to <stable@vger.kernel.org>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-6.18.y
git checkout FETCH_HEAD
git cherry-pick -x 941ac10529b3be5965a88d432a161ab459672ba8
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<stable@vger.kernel.org>' --in-reply-to '2026090936-stew-difficult-cba0@gregkh' --subject-prefix 'PATCH 6.18.y' 'HEAD^..'
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 941ac10529b3be5965a88d432a161ab459672ba8 Mon Sep 17 00:00:00 2001
From: Matthew Brost <matthew.brost@intel.com>
Date: Tue, 16 Jun 2026 18:55:31 -0700
Subject: [PATCH] drm/ttm: Drop tt->restore after successful restore
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
ttm_pool_restore_and_alloc() can successfully complete the restore
process via ttm_pool_restore_commit(), but tt->restore is not dropped
afterward. As a result, subsequent backup/restore flows observe what
appears to be a completed restore, while in reality shmem handles are
still installed in tt->pages, leading to the stack trace below.
Fix this by freeing and dropping tt->restore in
ttm_pool_restore_and_alloc() upon successful completion of the restore.
20545 [ 309.784531] RIP: 0010:sg_alloc_append_table_from_pages+0x38c/0x490
20547 [ 309.809570] RSP: 0018:ffffc9000623b838 EFLAGS: 00010206
20548 [ 309.814827] RAX: 0000000000001000 RBX: ffff88816e42a160 RCX: 0000000000000000
20549 [ 309.821986] RDX: 0000000000002000 RSI: 0000000000000003 RDI: 0000000000001000
20550 [ 309.829147] RBP: ffff88816e42a168 R08: 0000000000000002 R09: 000000007ffff000
20551 [ 309.836310] R10: ffffc9000623b928 R11: 0000000000000000 R12: 000000007ffff000
20552 [ 309.843471] R13: ffff88815ba5a100 R14: 0000000000000000 R15: 0000000000000001
20553 [ 309.850634] FS: 00007f9ff305e700(0000) GS:ffff888276c94000(0000) knlGS:0000000000000000
20554 [ 309.858749] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
20555 [ 309.864519] CR2: 00007f9fca701000 CR3: 00000001565e2005 CR4: 0000000008f70ef0
20556 [ 309.871678] PKRU: 55555558
20557 [ 309.874403] Call Trace:
20558 [ 309.876866] <TASK>
20559 [ 309.878988] sg_alloc_table_from_pages_segment+0x60/0x100
20560 [ 309.884415] ? ttm_resource_manager_usage+0x36/0x60 [ttm]
20561 [ 309.889845] ? xe_tt_map_sg+0x7d/0xd0 [xe]
20562 [ 309.894045] xe_tt_map_sg+0x7d/0xd0 [xe]
20563 [ 309.898037] xe_bo_move+0x927/0xaa0 [xe]
20564 [ 309.902029] ttm_bo_handle_move_mem+0xba/0x170 [ttm]
20565 [ 309.907022] ttm_bo_validate+0xbe/0x190 [ttm]
20566 [ 309.911405] xe_bo_validate+0x9a/0x120 [xe]
20567 [ 309.915663] xe_gpuvm_validate+0xd9/0x140 [xe]
20568 [ 309.920206] drm_gpuvm_validate+0x2f0/0x5b0 [drm_gpuvm]
20569 [ 309.925459] ? drm_exec_lock_obj+0x63/0x210 [drm_exec]
20570 [ 309.930627] xe_vm_validate_rebind+0x46/0xb0 [xe]
20571 [ 309.935428] xe_exec_fn+0x20/0x40 [xe]
20572 [ 309.939249] drm_gpuvm_exec_lock+0x78/0xc0 [drm_gpuvm]
20573 [ 309.944410] xe_validation_exec_lock+0x5a/0xa0 [xe]
20574 [ 309.949385] xe_exec_ioctl+0x806/0xc30 [xe]
20575 [ 309.953639] ? ttwu_queue_wakelist+0xd9/0xf0
20576 [ 309.957935] ? __pfx_xe_exec_fn+0x10/0x10 [xe]
20577 [ 309.962449] ? __wake_up_common+0x73/0xa0
20578 [ 309.966482] ? __pfx_xe_exec_ioctl+0x10/0x10 [xe]
20579 [ 309.971263] drm_ioctl_kernel+0xa3/0x100
20580 [ 309.975209] drm_ioctl+0x213/0x440
20581 [ 309.978637] ? __pfx_xe_exec_ioctl+0x10/0x10 [xe]
20582 [ 309.983415] xe_drm_ioctl+0x67/0xd0 [xe]
20583 [ 309.987408] __x64_sys_ioctl+0x7f/0xd0
Cc: Thomas Hellström <thomas.hellstrom@linux.intel.com>
Cc: Christian Koenig <christian.koenig@amd.com>
Cc: Huang Rui <ray.huang@amd.com>
Cc: Matthew Auld <matthew.auld@intel.com>
Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Cc: Maxime Ripard <mripard@kernel.org>
Cc: Thomas Zimmermann <tzimmermann@suse.de>
Cc: David Airlie <airlied@gmail.com>
Cc: Simona Vetter <simona@ffwll.ch>
Cc: dri-devel@lists.freedesktop.org
Cc: linux-kernel@vger.kernel.org
Cc: stable@vger.kernel.org
Fixes: b63d715b8090 ("drm/ttm/pool, drm/ttm/tt: Provide a helper to shrink pages")
Signed-off-by: Matthew Brost <matthew.brost@intel.com>
Reviewed-by: Thomas Hellström <thomas.hellstrom@linux.intel.com>
Link: https://patch.msgid.link/20260617015531.1164189-1-matthew.brost@intel.com
diff --git a/drivers/gpu/drm/ttm/ttm_pool.c b/drivers/gpu/drm/ttm/ttm_pool.c
index 39fdd50b1ee2..682ae4f40424 100644
--- a/drivers/gpu/drm/ttm/ttm_pool.c
+++ b/drivers/gpu/drm/ttm/ttm_pool.c
@@ -907,6 +907,7 @@ int ttm_pool_restore_and_alloc(struct ttm_pool *pool, struct ttm_tt *tt,
{
struct ttm_pool_tt_restore *restore = tt->restore;
struct ttm_pool_alloc_state alloc;
+ int ret;
if (WARN_ON(!ttm_tt_is_backed_up(tt)))
return -EINVAL;
@@ -930,14 +931,22 @@ int ttm_pool_restore_and_alloc(struct ttm_pool *pool, struct ttm_tt *tt,
} else {
alloc = restore->snapshot_alloc;
if (ttm_pool_restore_valid(restore)) {
- int ret = ttm_pool_restore_commit(restore, tt->backup,
- ctx, &alloc);
+ ret = ttm_pool_restore_commit(restore, tt->backup,
+ ctx, &alloc);
if (ret)
return ret;
}
- if (!alloc.remaining_pages)
+ if (!alloc.remaining_pages) {
+ ret = ttm_pool_apply_caching(&alloc);
+ if (ret)
+ return ret;
+
+ kfree(tt->restore);
+ tt->restore = NULL;
+
return 0;
+ }
}
return __ttm_pool_alloc(pool, tt, ctx, &alloc, restore);
^ permalink raw reply related [flat|nested] 6+ messages in thread* [PATCH 6.18.y 1/2] drm/ttm: Tidy usage of local variables a little bit 2026-09-09 11:54 FAILED: patch "[PATCH] drm/ttm: Drop tt->restore after successful restore" failed to apply to 6.18-stable tree gregkh @ 2026-09-12 14:34 ` Sasha Levin 2026-09-12 14:34 ` [PATCH 6.18.y 2/2] drm/ttm: Drop tt->restore after successful restore Sasha Levin 2026-09-12 20:40 ` [PATCH 6.18.y 1/2] drm/ttm: Tidy usage of local variables a little bit Thadeu Lima de Souza Cascardo 0 siblings, 2 replies; 6+ messages in thread From: Sasha Levin @ 2026-09-12 14:34 UTC (permalink / raw) To: stable Cc: Tvrtko Ursulin, Thadeu Lima de Souza Cascardo, Christian König, Tvrtko Ursulin, Sasha Levin From: Tvrtko Ursulin <tvrtko.ursulin@igalia.com> [ Upstream commit c06da4b3573a2d3c906c185450d0b1059d02820e ] At the moment the TTM code has a few places which exibit sub-optimal patterns regarding local variable usage: * Having a local with some object cached but not always using it. * Having a local for a single use object member access. * Failed opportunities to use a local to cache a pointer. Lets tidy this a little bit and apply some more consistency. It is mostly for consistency and redability but I have also checked that there are not negative code generation effects. In fact there are more positives: add/remove: 0/0 grow/shrink: 3/9 up/down: 12/-175 (-163) Function old new delta ttm_pool_restore_and_alloc 415 423 +8 ttm_bo_vunmap 147 149 +2 ttm_bo_evict 521 523 +2 ttm_bo_vm_fault_reserved 972 970 -2 ttm_bo_vm_dummy_page 155 152 -3 ttm_bo_vm_fault 203 196 -7 ttm_bo_populate 158 150 -8 ttm_bo_move_memcpy 600 592 -8 ttm_bo_kmap 667 644 -23 ttm_bo_shrink 333 305 -28 ttm_bo_release 750 720 -30 ttm_bo_swapout_cb 691 625 -66 Total: Before=42717, After=42554, chg -0.38% Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@igalia.com> Reviewed-by: Thadeu Lima de Souza Cascardo <cascardo@igalia.com> Link: https://lore.kernel.org/r/20250919131530.91247-5-tvrtko.ursulin@igalia.com Acked-by: Christian König <christian.koenig@amd.com> Signed-off-by: Tvrtko Ursulin <tursulin@ursulin.net> [tursulin: fixup conflict in ttm_bo_move_pipeline_evict] Stable-dep-of: 941ac10529b3 ("drm/ttm: Drop tt->restore after successful restore") Signed-off-by: Sasha Levin <sashal@kernel.org> --- drivers/gpu/drm/ttm/ttm_bo.c | 62 +++++++++++++++--------------- drivers/gpu/drm/ttm/ttm_bo_util.c | 47 +++++++++++----------- drivers/gpu/drm/ttm/ttm_bo_vm.c | 12 +++--- drivers/gpu/drm/ttm/ttm_pool.c | 26 +++++++------ drivers/gpu/drm/ttm/ttm_resource.c | 6 +-- 5 files changed, 77 insertions(+), 76 deletions(-) diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c index cf0e785aa9d3c..d3f0f5e32a351 100644 --- a/drivers/gpu/drm/ttm/ttm_bo.c +++ b/drivers/gpu/drm/ttm/ttm_bo.c @@ -266,8 +266,8 @@ static void ttm_bo_release(struct kref *kref) 30 * HZ); } - if (bo->bdev->funcs->release_notify) - bo->bdev->funcs->release_notify(bo); + if (bdev->funcs->release_notify) + bdev->funcs->release_notify(bo); drm_vma_offset_remove(bdev->vma_manager, &bo->base.vma_node); ttm_mem_io_free(bdev, bo->resource); @@ -281,7 +281,7 @@ static void ttm_bo_release(struct kref *kref) ttm_bo_flush_all_fences(bo); bo->deleted = true; - spin_lock(&bo->bdev->lru_lock); + spin_lock(&bdev->lru_lock); /* * Make pinned bos immediately available to @@ -297,7 +297,7 @@ static void ttm_bo_release(struct kref *kref) } kref_init(&bo->kref); - spin_unlock(&bo->bdev->lru_lock); + spin_unlock(&bdev->lru_lock); INIT_WORK(&bo->delayed_delete, ttm_bo_delayed_delete); @@ -358,7 +358,6 @@ static int ttm_bo_bounce_temp_buffer(struct ttm_buffer_object *bo, static int ttm_bo_evict(struct ttm_buffer_object *bo, struct ttm_operation_ctx *ctx) { - struct ttm_device *bdev = bo->bdev; struct ttm_resource *evict_mem; struct ttm_placement placement; struct ttm_place hop; @@ -369,7 +368,7 @@ static int ttm_bo_evict(struct ttm_buffer_object *bo, dma_resv_assert_held(bo->base.resv); placement.num_placement = 0; - bdev->funcs->evict_flags(bo, &placement); + bo->bdev->funcs->evict_flags(bo, &placement); if (!placement.num_placement) { ret = ttm_bo_wait_ctx(bo, ctx); @@ -422,16 +421,16 @@ bool ttm_bo_eviction_valuable(struct ttm_buffer_object *bo, const struct ttm_place *place) { struct ttm_resource *res = bo->resource; - struct ttm_device *bdev = bo->bdev; dma_resv_assert_held(bo->base.resv); - if (bo->resource->mem_type == TTM_PL_SYSTEM) + + if (res->mem_type == TTM_PL_SYSTEM) return true; /* Don't evict this BO if it's outside of the * requested placement range */ - return ttm_resource_intersects(bdev, res, place, bo->base.size); + return ttm_resource_intersects(bo->bdev, res, place, bo->base.size); } EXPORT_SYMBOL(ttm_bo_eviction_valuable); @@ -1105,10 +1104,13 @@ struct ttm_bo_swapout_walk { static s64 ttm_bo_swapout_cb(struct ttm_lru_walk *walk, struct ttm_buffer_object *bo) { - struct ttm_place place = {.mem_type = bo->resource->mem_type}; + struct ttm_resource *res = bo->resource; + struct ttm_place place = { .mem_type = res->mem_type }; struct ttm_bo_swapout_walk *swapout_walk = container_of(walk, typeof(*swapout_walk), walk); struct ttm_operation_ctx *ctx = walk->arg.ctx; + struct ttm_device *bdev = bo->bdev; + struct ttm_tt *tt = bo->ttm; s64 ret; /* @@ -1117,20 +1119,19 @@ ttm_bo_swapout_cb(struct ttm_lru_walk *walk, struct ttm_buffer_object *bo) * The driver may use the fact that we're moving from SYSTEM * as an indication that we're about to swap out. */ - if (bo->pin_count || !bo->bdev->funcs->eviction_valuable(bo, &place)) { + if (bo->pin_count || !bdev->funcs->eviction_valuable(bo, &place)) { ret = -EBUSY; goto out; } - if (!bo->ttm || !ttm_tt_is_populated(bo->ttm) || - bo->ttm->page_flags & TTM_TT_FLAG_EXTERNAL || - bo->ttm->page_flags & TTM_TT_FLAG_SWAPPED) { + if (!tt || !ttm_tt_is_populated(tt) || + tt->page_flags & (TTM_TT_FLAG_EXTERNAL | TTM_TT_FLAG_SWAPPED)) { ret = -EBUSY; goto out; } if (bo->deleted) { - pgoff_t num_pages = bo->ttm->num_pages; + pgoff_t num_pages = tt->num_pages; ret = ttm_bo_wait_ctx(bo, ctx); if (ret) @@ -1144,7 +1145,7 @@ ttm_bo_swapout_cb(struct ttm_lru_walk *walk, struct ttm_buffer_object *bo) /* * Move to system cached */ - if (bo->resource->mem_type != TTM_PL_SYSTEM) { + if (res->mem_type != TTM_PL_SYSTEM) { struct ttm_resource *evict_mem; struct ttm_place hop; @@ -1171,21 +1172,21 @@ ttm_bo_swapout_cb(struct ttm_lru_walk *walk, struct ttm_buffer_object *bo) goto out; ttm_bo_unmap_virtual(bo); - if (bo->bdev->funcs->swap_notify) - bo->bdev->funcs->swap_notify(bo); + if (bdev->funcs->swap_notify) + bdev->funcs->swap_notify(bo); - if (ttm_tt_is_populated(bo->ttm)) { - spin_lock(&bo->bdev->lru_lock); - ttm_resource_del_bulk_move(bo->resource, bo); - spin_unlock(&bo->bdev->lru_lock); + if (ttm_tt_is_populated(tt)) { + spin_lock(&bdev->lru_lock); + ttm_resource_del_bulk_move(res, bo); + spin_unlock(&bdev->lru_lock); - ret = ttm_tt_swapout(bo->bdev, bo->ttm, swapout_walk->gfp_flags); + ret = ttm_tt_swapout(bdev, tt, swapout_walk->gfp_flags); - spin_lock(&bo->bdev->lru_lock); + spin_lock(&bdev->lru_lock); if (ret) - ttm_resource_add_bulk_move(bo->resource, bo); - ttm_resource_move_to_lru_tail(bo->resource); - spin_unlock(&bo->bdev->lru_lock); + ttm_resource_add_bulk_move(res, bo); + ttm_resource_move_to_lru_tail(res); + spin_unlock(&bdev->lru_lock); } out: @@ -1258,6 +1259,7 @@ void ttm_bo_tt_destroy(struct ttm_buffer_object *bo) int ttm_bo_populate(struct ttm_buffer_object *bo, struct ttm_operation_ctx *ctx) { + struct ttm_device *bdev = bo->bdev; struct ttm_tt *tt = bo->ttm; bool swapped; int ret; @@ -1268,16 +1270,16 @@ int ttm_bo_populate(struct ttm_buffer_object *bo, return 0; swapped = ttm_tt_is_swapped(tt); - ret = ttm_tt_populate(bo->bdev, tt, ctx); + ret = ttm_tt_populate(bdev, tt, ctx); if (ret) return ret; if (swapped && !ttm_tt_is_swapped(tt) && !bo->pin_count && bo->resource) { - spin_lock(&bo->bdev->lru_lock); + spin_lock(&bdev->lru_lock); ttm_resource_add_bulk_move(bo->resource, bo); ttm_resource_move_to_lru_tail(bo->resource); - spin_unlock(&bo->bdev->lru_lock); + spin_unlock(&bdev->lru_lock); } return 0; diff --git a/drivers/gpu/drm/ttm/ttm_bo_util.c b/drivers/gpu/drm/ttm/ttm_bo_util.c index acbbca9d5c92f..85bb9f9f1f616 100644 --- a/drivers/gpu/drm/ttm/ttm_bo_util.c +++ b/drivers/gpu/drm/ttm/ttm_bo_util.c @@ -174,13 +174,13 @@ int ttm_bo_move_memcpy(struct ttm_buffer_object *bo, dst_iter = ttm_kmap_iter_linear_io_init(&_dst_iter.io, bdev, dst_mem); if (PTR_ERR(dst_iter) == -EINVAL && dst_man->use_tt) - dst_iter = ttm_kmap_iter_tt_init(&_dst_iter.tt, bo->ttm); + dst_iter = ttm_kmap_iter_tt_init(&_dst_iter.tt, ttm); if (IS_ERR(dst_iter)) return PTR_ERR(dst_iter); src_iter = ttm_kmap_iter_linear_io_init(&_src_iter.io, bdev, src_mem); if (PTR_ERR(src_iter) == -EINVAL && src_man->use_tt) - src_iter = ttm_kmap_iter_tt_init(&_src_iter.tt, bo->ttm); + src_iter = ttm_kmap_iter_tt_init(&_src_iter.tt, ttm); if (IS_ERR(src_iter)) { ret = PTR_ERR(src_iter); goto out_src_iter; @@ -318,11 +318,11 @@ static int ttm_bo_ioremap(struct ttm_buffer_object *bo, { struct ttm_resource *mem = bo->resource; - if (bo->resource->bus.addr) { + if (mem->bus.addr) { map->bo_kmap_type = ttm_bo_map_premapped; - map->virtual = ((u8 *)bo->resource->bus.addr) + offset; + map->virtual = ((u8 *)mem->bus.addr) + offset; } else { - resource_size_t res = bo->resource->bus.offset + offset; + resource_size_t res = mem->bus.offset + offset; map->bo_kmap_type = ttm_bo_map_iomap; if (mem->bus.caching == ttm_write_combined) @@ -349,7 +349,7 @@ static int ttm_bo_kmap_ttm(struct ttm_buffer_object *bo, }; struct ttm_tt *ttm = bo->ttm; struct ttm_resource_manager *man = - ttm_manager_type(bo->bdev, bo->resource->mem_type); + ttm_manager_type(bo->bdev, mem->mem_type); pgprot_t prot; int ret; @@ -428,20 +428,21 @@ int ttm_bo_kmap(struct ttm_buffer_object *bo, unsigned long start_page, unsigned long num_pages, struct ttm_bo_kmap_obj *map) { + struct ttm_resource *res = bo->resource; unsigned long offset, size; int ret; map->virtual = NULL; map->bo = bo; - if (num_pages > PFN_UP(bo->resource->size)) + if (num_pages > PFN_UP(res->size)) return -EINVAL; - if ((start_page + num_pages) > PFN_UP(bo->resource->size)) + if ((start_page + num_pages) > PFN_UP(res->size)) return -EINVAL; - ret = ttm_mem_io_reserve(bo->bdev, bo->resource); + ret = ttm_mem_io_reserve(bo->bdev, res); if (ret) return ret; - if (!bo->resource->bus.is_iomem) { + if (!res->bus.is_iomem) { return ttm_bo_kmap_ttm(bo, start_page, num_pages, map); } else { offset = start_page << PAGE_SHIFT; @@ -581,7 +582,7 @@ void ttm_bo_vunmap(struct ttm_buffer_object *bo, struct iosys_map *map) iounmap(map->vaddr_iomem); iosys_map_clear(map); - ttm_mem_io_free(bo->bdev, bo->resource); + ttm_mem_io_free(bo->bdev, mem); } EXPORT_SYMBOL(ttm_bo_vunmap); @@ -644,10 +645,9 @@ static int ttm_bo_move_to_ghost(struct ttm_buffer_object *bo, static void ttm_bo_move_pipeline_evict(struct ttm_buffer_object *bo, struct dma_fence *fence) { - struct ttm_device *bdev = bo->bdev; struct ttm_resource_manager *from; - from = ttm_manager_type(bdev, bo->resource->mem_type); + from = ttm_manager_type(bo->bdev, bo->resource->mem_type); /** * BO doesn't have a TTM we need to bind/unbind. Just remember @@ -719,8 +719,8 @@ EXPORT_SYMBOL(ttm_bo_move_accel_cleanup); void ttm_bo_move_sync_cleanup(struct ttm_buffer_object *bo, struct ttm_resource *new_mem) { - struct ttm_device *bdev = bo->bdev; - struct ttm_resource_manager *man = ttm_manager_type(bdev, new_mem->mem_type); + struct ttm_resource_manager *man = + ttm_manager_type(bo->bdev, new_mem->mem_type); int ret; ret = ttm_bo_wait_free_node(bo, man->use_tt); @@ -824,13 +824,12 @@ static int ttm_lru_walk_ticketlock(struct ttm_bo_lru_cursor *curs, struct ttm_buffer_object *bo) { struct ttm_lru_walk_arg *arg = curs->arg; - struct dma_resv *resv = bo->base.resv; int ret; if (arg->ctx->interruptible) - ret = dma_resv_lock_interruptible(resv, arg->ticket); + ret = dma_resv_lock_interruptible(bo->base.resv, arg->ticket); else - ret = dma_resv_lock(resv, arg->ticket); + ret = dma_resv_lock(bo->base.resv, arg->ticket); if (!ret) { curs->needs_unlock = true; @@ -1074,7 +1073,7 @@ long ttm_bo_shrink(struct ttm_operation_ctx *ctx, struct ttm_buffer_object *bo, .num_placement = 1, .placement = &sys_placement_flags, }; - struct ttm_tt *tt = bo->ttm; + struct ttm_device *bdev = bo->bdev; long lret; dma_resv_assert_held(bo->base.resv); @@ -1096,19 +1095,19 @@ long ttm_bo_shrink(struct ttm_operation_ctx *ctx, struct ttm_buffer_object *bo, return lret; if (bo->bulk_move) { - spin_lock(&bo->bdev->lru_lock); + spin_lock(&bdev->lru_lock); ttm_resource_del_bulk_move(bo->resource, bo); - spin_unlock(&bo->bdev->lru_lock); + spin_unlock(&bdev->lru_lock); } - lret = ttm_tt_backup(bo->bdev, tt, (struct ttm_backup_flags) + lret = ttm_tt_backup(bdev, bo->ttm, (struct ttm_backup_flags) {.purge = flags.purge, .writeback = flags.writeback}); if (lret <= 0 && bo->bulk_move) { - spin_lock(&bo->bdev->lru_lock); + spin_lock(&bdev->lru_lock); ttm_resource_add_bulk_move(bo->resource, bo); - spin_unlock(&bo->bdev->lru_lock); + spin_unlock(&bdev->lru_lock); } if (lret < 0 && lret != -EINTR) diff --git a/drivers/gpu/drm/ttm/ttm_bo_vm.c b/drivers/gpu/drm/ttm/ttm_bo_vm.c index e6abc7b40b189..a80510489c456 100644 --- a/drivers/gpu/drm/ttm/ttm_bo_vm.c +++ b/drivers/gpu/drm/ttm/ttm_bo_vm.c @@ -186,7 +186,6 @@ vm_fault_t ttm_bo_vm_fault_reserved(struct vm_fault *vmf, { struct vm_area_struct *vma = vmf->vma; struct ttm_buffer_object *bo = vma->vm_private_data; - struct ttm_device *bdev = bo->bdev; unsigned long page_offset; unsigned long page_last; unsigned long pfn; @@ -205,7 +204,7 @@ vm_fault_t ttm_bo_vm_fault_reserved(struct vm_fault *vmf, if (unlikely(ret != 0)) return ret; - err = ttm_mem_io_reserve(bdev, bo->resource); + err = ttm_mem_io_reserve(bo->bdev, bo->resource); if (unlikely(err != 0)) return VM_FAULT_SIGBUS; @@ -293,7 +292,6 @@ vm_fault_t ttm_bo_vm_dummy_page(struct vm_fault *vmf, pgprot_t prot) { struct vm_area_struct *vma = vmf->vma; struct ttm_buffer_object *bo = vma->vm_private_data; - struct drm_device *ddev = bo->base.dev; vm_fault_t ret = VM_FAULT_NOPAGE; unsigned long address; unsigned long pfn; @@ -305,7 +303,8 @@ vm_fault_t ttm_bo_vm_dummy_page(struct vm_fault *vmf, pgprot_t prot) return VM_FAULT_OOM; /* Set the page to be freed using drmm release action */ - if (drmm_add_action_or_reset(ddev, ttm_bo_release_dummy_page, page)) + if (drmm_add_action_or_reset(bo->base.dev, ttm_bo_release_dummy_page, + page)) return VM_FAULT_OOM; pfn = page_to_pfn(page); @@ -322,10 +321,9 @@ EXPORT_SYMBOL(ttm_bo_vm_dummy_page); vm_fault_t ttm_bo_vm_fault(struct vm_fault *vmf) { struct vm_area_struct *vma = vmf->vma; - pgprot_t prot; struct ttm_buffer_object *bo = vma->vm_private_data; - struct drm_device *ddev = bo->base.dev; vm_fault_t ret; + pgprot_t prot; int idx; ret = ttm_bo_vm_reserve(bo, vmf); @@ -333,7 +331,7 @@ vm_fault_t ttm_bo_vm_fault(struct vm_fault *vmf) return ret; prot = vma->vm_page_prot; - if (drm_dev_enter(ddev, &idx)) { + if (drm_dev_enter(bo->base.dev, &idx)) { ret = ttm_bo_vm_fault_reserved(vmf, prot, TTM_BO_VM_NUM_PREFAULT); drm_dev_exit(idx); } else { diff --git a/drivers/gpu/drm/ttm/ttm_pool.c b/drivers/gpu/drm/ttm/ttm_pool.c index 01083720e4e7f..1f52a1f59d7b7 100644 --- a/drivers/gpu/drm/ttm/ttm_pool.c +++ b/drivers/gpu/drm/ttm/ttm_pool.c @@ -836,32 +836,34 @@ EXPORT_SYMBOL(ttm_pool_alloc); int ttm_pool_restore_and_alloc(struct ttm_pool *pool, struct ttm_tt *tt, const struct ttm_operation_ctx *ctx) { + struct ttm_pool_tt_restore *restore = tt->restore; struct ttm_pool_alloc_state alloc; if (WARN_ON(!ttm_tt_is_backed_up(tt))) return -EINVAL; - if (!tt->restore) { + if (!restore) { gfp_t gfp = GFP_KERNEL | __GFP_NOWARN; ttm_pool_alloc_state_init(tt, &alloc); if (ctx->gfp_retry_mayfail) gfp |= __GFP_RETRY_MAYFAIL; - tt->restore = kzalloc(sizeof(*tt->restore), gfp); - if (!tt->restore) + restore = kzalloc(sizeof(*restore), gfp); + if (!restore) return -ENOMEM; - tt->restore->snapshot_alloc = alloc; - tt->restore->pool = pool; - tt->restore->restored_pages = 1; - } else { - struct ttm_pool_tt_restore *restore = tt->restore; - int ret; + restore->snapshot_alloc = alloc; + restore->pool = pool; + restore->restored_pages = 1; + tt->restore = restore; + } else { alloc = restore->snapshot_alloc; - if (ttm_pool_restore_valid(tt->restore)) { - ret = ttm_pool_restore_commit(restore, tt->backup, ctx, &alloc); + if (ttm_pool_restore_valid(restore)) { + int ret = ttm_pool_restore_commit(restore, tt->backup, + ctx, &alloc); + if (ret) return ret; } @@ -869,7 +871,7 @@ int ttm_pool_restore_and_alloc(struct ttm_pool *pool, struct ttm_tt *tt, return 0; } - return __ttm_pool_alloc(pool, tt, ctx, &alloc, tt->restore); + return __ttm_pool_alloc(pool, tt, ctx, &alloc, restore); } /** diff --git a/drivers/gpu/drm/ttm/ttm_resource.c b/drivers/gpu/drm/ttm/ttm_resource.c index 2a05fbd075465..8396cab34cb03 100644 --- a/drivers/gpu/drm/ttm/ttm_resource.c +++ b/drivers/gpu/drm/ttm/ttm_resource.c @@ -620,11 +620,11 @@ ttm_resource_cursor_check_bulk(struct ttm_resource_cursor *cursor, struct ttm_lru_item *next_lru) { struct ttm_resource *next = ttm_lru_item_to_res(next_lru); - struct ttm_lru_bulk_move *bulk = NULL; - struct ttm_buffer_object *bo = next->bo; + struct ttm_lru_bulk_move *bulk; lockdep_assert_held(&cursor->man->bdev->lru_lock); - bulk = bo->bulk_move; + + bulk = next->bo->bulk_move; if (cursor->bulk != bulk) { if (bulk) { -- 2.53.0 ^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 6.18.y 2/2] drm/ttm: Drop tt->restore after successful restore 2026-09-12 14:34 ` [PATCH 6.18.y 1/2] drm/ttm: Tidy usage of local variables a little bit Sasha Levin @ 2026-09-12 14:34 ` Sasha Levin 2026-09-12 20:40 ` [PATCH 6.18.y 1/2] drm/ttm: Tidy usage of local variables a little bit Thadeu Lima de Souza Cascardo 1 sibling, 0 replies; 6+ messages in thread From: Sasha Levin @ 2026-09-12 14:34 UTC (permalink / raw) To: stable Cc: Matthew Brost, Thomas Hellström, Christian Koenig, Huang Rui, Matthew Auld, Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter, dri-devel, linux-kernel, Sasha Levin From: Matthew Brost <matthew.brost@intel.com> [ Upstream commit 941ac10529b3be5965a88d432a161ab459672ba8 ] ttm_pool_restore_and_alloc() can successfully complete the restore process via ttm_pool_restore_commit(), but tt->restore is not dropped afterward. As a result, subsequent backup/restore flows observe what appears to be a completed restore, while in reality shmem handles are still installed in tt->pages, leading to the stack trace below. Fix this by freeing and dropping tt->restore in ttm_pool_restore_and_alloc() upon successful completion of the restore. 20545 [ 309.784531] RIP: 0010:sg_alloc_append_table_from_pages+0x38c/0x490 20547 [ 309.809570] RSP: 0018:ffffc9000623b838 EFLAGS: 00010206 20548 [ 309.814827] RAX: 0000000000001000 RBX: ffff88816e42a160 RCX: 0000000000000000 20549 [ 309.821986] RDX: 0000000000002000 RSI: 0000000000000003 RDI: 0000000000001000 20550 [ 309.829147] RBP: ffff88816e42a168 R08: 0000000000000002 R09: 000000007ffff000 20551 [ 309.836310] R10: ffffc9000623b928 R11: 0000000000000000 R12: 000000007ffff000 20552 [ 309.843471] R13: ffff88815ba5a100 R14: 0000000000000000 R15: 0000000000000001 20553 [ 309.850634] FS: 00007f9ff305e700(0000) GS:ffff888276c94000(0000) knlGS:0000000000000000 20554 [ 309.858749] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 20555 [ 309.864519] CR2: 00007f9fca701000 CR3: 00000001565e2005 CR4: 0000000008f70ef0 20556 [ 309.871678] PKRU: 55555558 20557 [ 309.874403] Call Trace: 20558 [ 309.876866] <TASK> 20559 [ 309.878988] sg_alloc_table_from_pages_segment+0x60/0x100 20560 [ 309.884415] ? ttm_resource_manager_usage+0x36/0x60 [ttm] 20561 [ 309.889845] ? xe_tt_map_sg+0x7d/0xd0 [xe] 20562 [ 309.894045] xe_tt_map_sg+0x7d/0xd0 [xe] 20563 [ 309.898037] xe_bo_move+0x927/0xaa0 [xe] 20564 [ 309.902029] ttm_bo_handle_move_mem+0xba/0x170 [ttm] 20565 [ 309.907022] ttm_bo_validate+0xbe/0x190 [ttm] 20566 [ 309.911405] xe_bo_validate+0x9a/0x120 [xe] 20567 [ 309.915663] xe_gpuvm_validate+0xd9/0x140 [xe] 20568 [ 309.920206] drm_gpuvm_validate+0x2f0/0x5b0 [drm_gpuvm] 20569 [ 309.925459] ? drm_exec_lock_obj+0x63/0x210 [drm_exec] 20570 [ 309.930627] xe_vm_validate_rebind+0x46/0xb0 [xe] 20571 [ 309.935428] xe_exec_fn+0x20/0x40 [xe] 20572 [ 309.939249] drm_gpuvm_exec_lock+0x78/0xc0 [drm_gpuvm] 20573 [ 309.944410] xe_validation_exec_lock+0x5a/0xa0 [xe] 20574 [ 309.949385] xe_exec_ioctl+0x806/0xc30 [xe] 20575 [ 309.953639] ? ttwu_queue_wakelist+0xd9/0xf0 20576 [ 309.957935] ? __pfx_xe_exec_fn+0x10/0x10 [xe] 20577 [ 309.962449] ? __wake_up_common+0x73/0xa0 20578 [ 309.966482] ? __pfx_xe_exec_ioctl+0x10/0x10 [xe] 20579 [ 309.971263] drm_ioctl_kernel+0xa3/0x100 20580 [ 309.975209] drm_ioctl+0x213/0x440 20581 [ 309.978637] ? __pfx_xe_exec_ioctl+0x10/0x10 [xe] 20582 [ 309.983415] xe_drm_ioctl+0x67/0xd0 [xe] 20583 [ 309.987408] __x64_sys_ioctl+0x7f/0xd0 Cc: Thomas Hellström <thomas.hellstrom@linux.intel.com> Cc: Christian Koenig <christian.koenig@amd.com> Cc: Huang Rui <ray.huang@amd.com> Cc: Matthew Auld <matthew.auld@intel.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Maxime Ripard <mripard@kernel.org> Cc: Thomas Zimmermann <tzimmermann@suse.de> Cc: David Airlie <airlied@gmail.com> Cc: Simona Vetter <simona@ffwll.ch> Cc: dri-devel@lists.freedesktop.org Cc: linux-kernel@vger.kernel.org Cc: stable@vger.kernel.org Fixes: b63d715b8090 ("drm/ttm/pool, drm/ttm/tt: Provide a helper to shrink pages") Signed-off-by: Matthew Brost <matthew.brost@intel.com> Reviewed-by: Thomas Hellström <thomas.hellstrom@linux.intel.com> Link: https://patch.msgid.link/20260617015531.1164189-1-matthew.brost@intel.com Signed-off-by: Sasha Levin <sashal@kernel.org> --- drivers/gpu/drm/ttm/ttm_pool.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/ttm/ttm_pool.c b/drivers/gpu/drm/ttm/ttm_pool.c index 1f52a1f59d7b7..dd5666eb4692b 100644 --- a/drivers/gpu/drm/ttm/ttm_pool.c +++ b/drivers/gpu/drm/ttm/ttm_pool.c @@ -838,6 +838,7 @@ int ttm_pool_restore_and_alloc(struct ttm_pool *pool, struct ttm_tt *tt, { struct ttm_pool_tt_restore *restore = tt->restore; struct ttm_pool_alloc_state alloc; + int ret; if (WARN_ON(!ttm_tt_is_backed_up(tt))) return -EINVAL; @@ -861,14 +862,22 @@ int ttm_pool_restore_and_alloc(struct ttm_pool *pool, struct ttm_tt *tt, } else { alloc = restore->snapshot_alloc; if (ttm_pool_restore_valid(restore)) { - int ret = ttm_pool_restore_commit(restore, tt->backup, - ctx, &alloc); + ret = ttm_pool_restore_commit(restore, tt->backup, + ctx, &alloc); if (ret) return ret; } - if (!alloc.remaining_pages) + if (!alloc.remaining_pages) { + ret = ttm_pool_apply_caching(&alloc); + if (ret) + return ret; + + kfree(tt->restore); + tt->restore = NULL; + return 0; + } } return __ttm_pool_alloc(pool, tt, ctx, &alloc, restore); -- 2.53.0 ^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH 6.18.y 1/2] drm/ttm: Tidy usage of local variables a little bit 2026-09-12 14:34 ` [PATCH 6.18.y 1/2] drm/ttm: Tidy usage of local variables a little bit Sasha Levin 2026-09-12 14:34 ` [PATCH 6.18.y 2/2] drm/ttm: Drop tt->restore after successful restore Sasha Levin @ 2026-09-12 20:40 ` Thadeu Lima de Souza Cascardo 2026-09-15 2:03 ` Sasha Levin 1 sibling, 1 reply; 6+ messages in thread From: Thadeu Lima de Souza Cascardo @ 2026-09-12 20:40 UTC (permalink / raw) To: Sasha Levin; +Cc: stable, Tvrtko Ursulin, Christian König, Tvrtko Ursulin On Sat, Sep 12, 2026 at 10:34:17AM -0400, Sasha Levin wrote: > From: Tvrtko Ursulin <tvrtko.ursulin@igalia.com> > > [ Upstream commit c06da4b3573a2d3c906c185450d0b1059d02820e ] > Hi, Sasha. You need to apply 91d7e9df4259 ("drm/ttm: Fix bo resource use-after-free") too, otherwise this introduces a UAF. Regards. Cascardo. > At the moment the TTM code has a few places which exibit sub-optimal > patterns regarding local variable usage: > > * Having a local with some object cached but not always using it. > * Having a local for a single use object member access. > * Failed opportunities to use a local to cache a pointer. > > Lets tidy this a little bit and apply some more consistency. > > It is mostly for consistency and redability but I have also checked that > there are not negative code generation effects. In fact there are more > positives: > > add/remove: 0/0 grow/shrink: 3/9 up/down: 12/-175 (-163) > Function old new delta > ttm_pool_restore_and_alloc 415 423 +8 > ttm_bo_vunmap 147 149 +2 > ttm_bo_evict 521 523 +2 > ttm_bo_vm_fault_reserved 972 970 -2 > ttm_bo_vm_dummy_page 155 152 -3 > ttm_bo_vm_fault 203 196 -7 > ttm_bo_populate 158 150 -8 > ttm_bo_move_memcpy 600 592 -8 > ttm_bo_kmap 667 644 -23 > ttm_bo_shrink 333 305 -28 > ttm_bo_release 750 720 -30 > ttm_bo_swapout_cb 691 625 -66 > Total: Before=42717, After=42554, chg -0.38% > > Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@igalia.com> > Reviewed-by: Thadeu Lima de Souza Cascardo <cascardo@igalia.com> > Link: https://lore.kernel.org/r/20250919131530.91247-5-tvrtko.ursulin@igalia.com > Acked-by: Christian König <christian.koenig@amd.com> > Signed-off-by: Tvrtko Ursulin <tursulin@ursulin.net> > [tursulin: fixup conflict in ttm_bo_move_pipeline_evict] > Stable-dep-of: 941ac10529b3 ("drm/ttm: Drop tt->restore after successful restore") > Signed-off-by: Sasha Levin <sashal@kernel.org> > --- > drivers/gpu/drm/ttm/ttm_bo.c | 62 +++++++++++++++--------------- > drivers/gpu/drm/ttm/ttm_bo_util.c | 47 +++++++++++----------- > drivers/gpu/drm/ttm/ttm_bo_vm.c | 12 +++--- > drivers/gpu/drm/ttm/ttm_pool.c | 26 +++++++------ > drivers/gpu/drm/ttm/ttm_resource.c | 6 +-- > 5 files changed, 77 insertions(+), 76 deletions(-) > > diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c > index cf0e785aa9d3c..d3f0f5e32a351 100644 > --- a/drivers/gpu/drm/ttm/ttm_bo.c > +++ b/drivers/gpu/drm/ttm/ttm_bo.c > @@ -266,8 +266,8 @@ static void ttm_bo_release(struct kref *kref) > 30 * HZ); > } > > - if (bo->bdev->funcs->release_notify) > - bo->bdev->funcs->release_notify(bo); > + if (bdev->funcs->release_notify) > + bdev->funcs->release_notify(bo); > > drm_vma_offset_remove(bdev->vma_manager, &bo->base.vma_node); > ttm_mem_io_free(bdev, bo->resource); > @@ -281,7 +281,7 @@ static void ttm_bo_release(struct kref *kref) > ttm_bo_flush_all_fences(bo); > bo->deleted = true; > > - spin_lock(&bo->bdev->lru_lock); > + spin_lock(&bdev->lru_lock); > > /* > * Make pinned bos immediately available to > @@ -297,7 +297,7 @@ static void ttm_bo_release(struct kref *kref) > } > > kref_init(&bo->kref); > - spin_unlock(&bo->bdev->lru_lock); > + spin_unlock(&bdev->lru_lock); > > INIT_WORK(&bo->delayed_delete, ttm_bo_delayed_delete); > > @@ -358,7 +358,6 @@ static int ttm_bo_bounce_temp_buffer(struct ttm_buffer_object *bo, > static int ttm_bo_evict(struct ttm_buffer_object *bo, > struct ttm_operation_ctx *ctx) > { > - struct ttm_device *bdev = bo->bdev; > struct ttm_resource *evict_mem; > struct ttm_placement placement; > struct ttm_place hop; > @@ -369,7 +368,7 @@ static int ttm_bo_evict(struct ttm_buffer_object *bo, > dma_resv_assert_held(bo->base.resv); > > placement.num_placement = 0; > - bdev->funcs->evict_flags(bo, &placement); > + bo->bdev->funcs->evict_flags(bo, &placement); > > if (!placement.num_placement) { > ret = ttm_bo_wait_ctx(bo, ctx); > @@ -422,16 +421,16 @@ bool ttm_bo_eviction_valuable(struct ttm_buffer_object *bo, > const struct ttm_place *place) > { > struct ttm_resource *res = bo->resource; > - struct ttm_device *bdev = bo->bdev; > > dma_resv_assert_held(bo->base.resv); > - if (bo->resource->mem_type == TTM_PL_SYSTEM) > + > + if (res->mem_type == TTM_PL_SYSTEM) > return true; > > /* Don't evict this BO if it's outside of the > * requested placement range > */ > - return ttm_resource_intersects(bdev, res, place, bo->base.size); > + return ttm_resource_intersects(bo->bdev, res, place, bo->base.size); > } > EXPORT_SYMBOL(ttm_bo_eviction_valuable); > > @@ -1105,10 +1104,13 @@ struct ttm_bo_swapout_walk { > static s64 > ttm_bo_swapout_cb(struct ttm_lru_walk *walk, struct ttm_buffer_object *bo) > { > - struct ttm_place place = {.mem_type = bo->resource->mem_type}; > + struct ttm_resource *res = bo->resource; > + struct ttm_place place = { .mem_type = res->mem_type }; > struct ttm_bo_swapout_walk *swapout_walk = > container_of(walk, typeof(*swapout_walk), walk); > struct ttm_operation_ctx *ctx = walk->arg.ctx; > + struct ttm_device *bdev = bo->bdev; > + struct ttm_tt *tt = bo->ttm; > s64 ret; > > /* > @@ -1117,20 +1119,19 @@ ttm_bo_swapout_cb(struct ttm_lru_walk *walk, struct ttm_buffer_object *bo) > * The driver may use the fact that we're moving from SYSTEM > * as an indication that we're about to swap out. > */ > - if (bo->pin_count || !bo->bdev->funcs->eviction_valuable(bo, &place)) { > + if (bo->pin_count || !bdev->funcs->eviction_valuable(bo, &place)) { > ret = -EBUSY; > goto out; > } > > - if (!bo->ttm || !ttm_tt_is_populated(bo->ttm) || > - bo->ttm->page_flags & TTM_TT_FLAG_EXTERNAL || > - bo->ttm->page_flags & TTM_TT_FLAG_SWAPPED) { > + if (!tt || !ttm_tt_is_populated(tt) || > + tt->page_flags & (TTM_TT_FLAG_EXTERNAL | TTM_TT_FLAG_SWAPPED)) { > ret = -EBUSY; > goto out; > } > > if (bo->deleted) { > - pgoff_t num_pages = bo->ttm->num_pages; > + pgoff_t num_pages = tt->num_pages; > > ret = ttm_bo_wait_ctx(bo, ctx); > if (ret) > @@ -1144,7 +1145,7 @@ ttm_bo_swapout_cb(struct ttm_lru_walk *walk, struct ttm_buffer_object *bo) > /* > * Move to system cached > */ > - if (bo->resource->mem_type != TTM_PL_SYSTEM) { > + if (res->mem_type != TTM_PL_SYSTEM) { > struct ttm_resource *evict_mem; > struct ttm_place hop; > > @@ -1171,21 +1172,21 @@ ttm_bo_swapout_cb(struct ttm_lru_walk *walk, struct ttm_buffer_object *bo) > goto out; > > ttm_bo_unmap_virtual(bo); > - if (bo->bdev->funcs->swap_notify) > - bo->bdev->funcs->swap_notify(bo); > + if (bdev->funcs->swap_notify) > + bdev->funcs->swap_notify(bo); > > - if (ttm_tt_is_populated(bo->ttm)) { > - spin_lock(&bo->bdev->lru_lock); > - ttm_resource_del_bulk_move(bo->resource, bo); > - spin_unlock(&bo->bdev->lru_lock); > + if (ttm_tt_is_populated(tt)) { > + spin_lock(&bdev->lru_lock); > + ttm_resource_del_bulk_move(res, bo); > + spin_unlock(&bdev->lru_lock); > > - ret = ttm_tt_swapout(bo->bdev, bo->ttm, swapout_walk->gfp_flags); > + ret = ttm_tt_swapout(bdev, tt, swapout_walk->gfp_flags); > > - spin_lock(&bo->bdev->lru_lock); > + spin_lock(&bdev->lru_lock); > if (ret) > - ttm_resource_add_bulk_move(bo->resource, bo); > - ttm_resource_move_to_lru_tail(bo->resource); > - spin_unlock(&bo->bdev->lru_lock); > + ttm_resource_add_bulk_move(res, bo); > + ttm_resource_move_to_lru_tail(res); > + spin_unlock(&bdev->lru_lock); > } > > out: > @@ -1258,6 +1259,7 @@ void ttm_bo_tt_destroy(struct ttm_buffer_object *bo) > int ttm_bo_populate(struct ttm_buffer_object *bo, > struct ttm_operation_ctx *ctx) > { > + struct ttm_device *bdev = bo->bdev; > struct ttm_tt *tt = bo->ttm; > bool swapped; > int ret; > @@ -1268,16 +1270,16 @@ int ttm_bo_populate(struct ttm_buffer_object *bo, > return 0; > > swapped = ttm_tt_is_swapped(tt); > - ret = ttm_tt_populate(bo->bdev, tt, ctx); > + ret = ttm_tt_populate(bdev, tt, ctx); > if (ret) > return ret; > > if (swapped && !ttm_tt_is_swapped(tt) && !bo->pin_count && > bo->resource) { > - spin_lock(&bo->bdev->lru_lock); > + spin_lock(&bdev->lru_lock); > ttm_resource_add_bulk_move(bo->resource, bo); > ttm_resource_move_to_lru_tail(bo->resource); > - spin_unlock(&bo->bdev->lru_lock); > + spin_unlock(&bdev->lru_lock); > } > > return 0; > diff --git a/drivers/gpu/drm/ttm/ttm_bo_util.c b/drivers/gpu/drm/ttm/ttm_bo_util.c > index acbbca9d5c92f..85bb9f9f1f616 100644 > --- a/drivers/gpu/drm/ttm/ttm_bo_util.c > +++ b/drivers/gpu/drm/ttm/ttm_bo_util.c > @@ -174,13 +174,13 @@ int ttm_bo_move_memcpy(struct ttm_buffer_object *bo, > > dst_iter = ttm_kmap_iter_linear_io_init(&_dst_iter.io, bdev, dst_mem); > if (PTR_ERR(dst_iter) == -EINVAL && dst_man->use_tt) > - dst_iter = ttm_kmap_iter_tt_init(&_dst_iter.tt, bo->ttm); > + dst_iter = ttm_kmap_iter_tt_init(&_dst_iter.tt, ttm); > if (IS_ERR(dst_iter)) > return PTR_ERR(dst_iter); > > src_iter = ttm_kmap_iter_linear_io_init(&_src_iter.io, bdev, src_mem); > if (PTR_ERR(src_iter) == -EINVAL && src_man->use_tt) > - src_iter = ttm_kmap_iter_tt_init(&_src_iter.tt, bo->ttm); > + src_iter = ttm_kmap_iter_tt_init(&_src_iter.tt, ttm); > if (IS_ERR(src_iter)) { > ret = PTR_ERR(src_iter); > goto out_src_iter; > @@ -318,11 +318,11 @@ static int ttm_bo_ioremap(struct ttm_buffer_object *bo, > { > struct ttm_resource *mem = bo->resource; > > - if (bo->resource->bus.addr) { > + if (mem->bus.addr) { > map->bo_kmap_type = ttm_bo_map_premapped; > - map->virtual = ((u8 *)bo->resource->bus.addr) + offset; > + map->virtual = ((u8 *)mem->bus.addr) + offset; > } else { > - resource_size_t res = bo->resource->bus.offset + offset; > + resource_size_t res = mem->bus.offset + offset; > > map->bo_kmap_type = ttm_bo_map_iomap; > if (mem->bus.caching == ttm_write_combined) > @@ -349,7 +349,7 @@ static int ttm_bo_kmap_ttm(struct ttm_buffer_object *bo, > }; > struct ttm_tt *ttm = bo->ttm; > struct ttm_resource_manager *man = > - ttm_manager_type(bo->bdev, bo->resource->mem_type); > + ttm_manager_type(bo->bdev, mem->mem_type); > pgprot_t prot; > int ret; > > @@ -428,20 +428,21 @@ int ttm_bo_kmap(struct ttm_buffer_object *bo, > unsigned long start_page, unsigned long num_pages, > struct ttm_bo_kmap_obj *map) > { > + struct ttm_resource *res = bo->resource; > unsigned long offset, size; > int ret; > > map->virtual = NULL; > map->bo = bo; > - if (num_pages > PFN_UP(bo->resource->size)) > + if (num_pages > PFN_UP(res->size)) > return -EINVAL; > - if ((start_page + num_pages) > PFN_UP(bo->resource->size)) > + if ((start_page + num_pages) > PFN_UP(res->size)) > return -EINVAL; > > - ret = ttm_mem_io_reserve(bo->bdev, bo->resource); > + ret = ttm_mem_io_reserve(bo->bdev, res); > if (ret) > return ret; > - if (!bo->resource->bus.is_iomem) { > + if (!res->bus.is_iomem) { > return ttm_bo_kmap_ttm(bo, start_page, num_pages, map); > } else { > offset = start_page << PAGE_SHIFT; > @@ -581,7 +582,7 @@ void ttm_bo_vunmap(struct ttm_buffer_object *bo, struct iosys_map *map) > iounmap(map->vaddr_iomem); > iosys_map_clear(map); > > - ttm_mem_io_free(bo->bdev, bo->resource); > + ttm_mem_io_free(bo->bdev, mem); > } > EXPORT_SYMBOL(ttm_bo_vunmap); > > @@ -644,10 +645,9 @@ static int ttm_bo_move_to_ghost(struct ttm_buffer_object *bo, > static void ttm_bo_move_pipeline_evict(struct ttm_buffer_object *bo, > struct dma_fence *fence) > { > - struct ttm_device *bdev = bo->bdev; > struct ttm_resource_manager *from; > > - from = ttm_manager_type(bdev, bo->resource->mem_type); > + from = ttm_manager_type(bo->bdev, bo->resource->mem_type); > > /** > * BO doesn't have a TTM we need to bind/unbind. Just remember > @@ -719,8 +719,8 @@ EXPORT_SYMBOL(ttm_bo_move_accel_cleanup); > void ttm_bo_move_sync_cleanup(struct ttm_buffer_object *bo, > struct ttm_resource *new_mem) > { > - struct ttm_device *bdev = bo->bdev; > - struct ttm_resource_manager *man = ttm_manager_type(bdev, new_mem->mem_type); > + struct ttm_resource_manager *man = > + ttm_manager_type(bo->bdev, new_mem->mem_type); > int ret; > > ret = ttm_bo_wait_free_node(bo, man->use_tt); > @@ -824,13 +824,12 @@ static int ttm_lru_walk_ticketlock(struct ttm_bo_lru_cursor *curs, > struct ttm_buffer_object *bo) > { > struct ttm_lru_walk_arg *arg = curs->arg; > - struct dma_resv *resv = bo->base.resv; > int ret; > > if (arg->ctx->interruptible) > - ret = dma_resv_lock_interruptible(resv, arg->ticket); > + ret = dma_resv_lock_interruptible(bo->base.resv, arg->ticket); > else > - ret = dma_resv_lock(resv, arg->ticket); > + ret = dma_resv_lock(bo->base.resv, arg->ticket); > > if (!ret) { > curs->needs_unlock = true; > @@ -1074,7 +1073,7 @@ long ttm_bo_shrink(struct ttm_operation_ctx *ctx, struct ttm_buffer_object *bo, > .num_placement = 1, > .placement = &sys_placement_flags, > }; > - struct ttm_tt *tt = bo->ttm; > + struct ttm_device *bdev = bo->bdev; > long lret; > > dma_resv_assert_held(bo->base.resv); > @@ -1096,19 +1095,19 @@ long ttm_bo_shrink(struct ttm_operation_ctx *ctx, struct ttm_buffer_object *bo, > return lret; > > if (bo->bulk_move) { > - spin_lock(&bo->bdev->lru_lock); > + spin_lock(&bdev->lru_lock); > ttm_resource_del_bulk_move(bo->resource, bo); > - spin_unlock(&bo->bdev->lru_lock); > + spin_unlock(&bdev->lru_lock); > } > > - lret = ttm_tt_backup(bo->bdev, tt, (struct ttm_backup_flags) > + lret = ttm_tt_backup(bdev, bo->ttm, (struct ttm_backup_flags) > {.purge = flags.purge, > .writeback = flags.writeback}); > > if (lret <= 0 && bo->bulk_move) { > - spin_lock(&bo->bdev->lru_lock); > + spin_lock(&bdev->lru_lock); > ttm_resource_add_bulk_move(bo->resource, bo); > - spin_unlock(&bo->bdev->lru_lock); > + spin_unlock(&bdev->lru_lock); > } > > if (lret < 0 && lret != -EINTR) > diff --git a/drivers/gpu/drm/ttm/ttm_bo_vm.c b/drivers/gpu/drm/ttm/ttm_bo_vm.c > index e6abc7b40b189..a80510489c456 100644 > --- a/drivers/gpu/drm/ttm/ttm_bo_vm.c > +++ b/drivers/gpu/drm/ttm/ttm_bo_vm.c > @@ -186,7 +186,6 @@ vm_fault_t ttm_bo_vm_fault_reserved(struct vm_fault *vmf, > { > struct vm_area_struct *vma = vmf->vma; > struct ttm_buffer_object *bo = vma->vm_private_data; > - struct ttm_device *bdev = bo->bdev; > unsigned long page_offset; > unsigned long page_last; > unsigned long pfn; > @@ -205,7 +204,7 @@ vm_fault_t ttm_bo_vm_fault_reserved(struct vm_fault *vmf, > if (unlikely(ret != 0)) > return ret; > > - err = ttm_mem_io_reserve(bdev, bo->resource); > + err = ttm_mem_io_reserve(bo->bdev, bo->resource); > if (unlikely(err != 0)) > return VM_FAULT_SIGBUS; > > @@ -293,7 +292,6 @@ vm_fault_t ttm_bo_vm_dummy_page(struct vm_fault *vmf, pgprot_t prot) > { > struct vm_area_struct *vma = vmf->vma; > struct ttm_buffer_object *bo = vma->vm_private_data; > - struct drm_device *ddev = bo->base.dev; > vm_fault_t ret = VM_FAULT_NOPAGE; > unsigned long address; > unsigned long pfn; > @@ -305,7 +303,8 @@ vm_fault_t ttm_bo_vm_dummy_page(struct vm_fault *vmf, pgprot_t prot) > return VM_FAULT_OOM; > > /* Set the page to be freed using drmm release action */ > - if (drmm_add_action_or_reset(ddev, ttm_bo_release_dummy_page, page)) > + if (drmm_add_action_or_reset(bo->base.dev, ttm_bo_release_dummy_page, > + page)) > return VM_FAULT_OOM; > > pfn = page_to_pfn(page); > @@ -322,10 +321,9 @@ EXPORT_SYMBOL(ttm_bo_vm_dummy_page); > vm_fault_t ttm_bo_vm_fault(struct vm_fault *vmf) > { > struct vm_area_struct *vma = vmf->vma; > - pgprot_t prot; > struct ttm_buffer_object *bo = vma->vm_private_data; > - struct drm_device *ddev = bo->base.dev; > vm_fault_t ret; > + pgprot_t prot; > int idx; > > ret = ttm_bo_vm_reserve(bo, vmf); > @@ -333,7 +331,7 @@ vm_fault_t ttm_bo_vm_fault(struct vm_fault *vmf) > return ret; > > prot = vma->vm_page_prot; > - if (drm_dev_enter(ddev, &idx)) { > + if (drm_dev_enter(bo->base.dev, &idx)) { > ret = ttm_bo_vm_fault_reserved(vmf, prot, TTM_BO_VM_NUM_PREFAULT); > drm_dev_exit(idx); > } else { > diff --git a/drivers/gpu/drm/ttm/ttm_pool.c b/drivers/gpu/drm/ttm/ttm_pool.c > index 01083720e4e7f..1f52a1f59d7b7 100644 > --- a/drivers/gpu/drm/ttm/ttm_pool.c > +++ b/drivers/gpu/drm/ttm/ttm_pool.c > @@ -836,32 +836,34 @@ EXPORT_SYMBOL(ttm_pool_alloc); > int ttm_pool_restore_and_alloc(struct ttm_pool *pool, struct ttm_tt *tt, > const struct ttm_operation_ctx *ctx) > { > + struct ttm_pool_tt_restore *restore = tt->restore; > struct ttm_pool_alloc_state alloc; > > if (WARN_ON(!ttm_tt_is_backed_up(tt))) > return -EINVAL; > > - if (!tt->restore) { > + if (!restore) { > gfp_t gfp = GFP_KERNEL | __GFP_NOWARN; > > ttm_pool_alloc_state_init(tt, &alloc); > if (ctx->gfp_retry_mayfail) > gfp |= __GFP_RETRY_MAYFAIL; > > - tt->restore = kzalloc(sizeof(*tt->restore), gfp); > - if (!tt->restore) > + restore = kzalloc(sizeof(*restore), gfp); > + if (!restore) > return -ENOMEM; > > - tt->restore->snapshot_alloc = alloc; > - tt->restore->pool = pool; > - tt->restore->restored_pages = 1; > - } else { > - struct ttm_pool_tt_restore *restore = tt->restore; > - int ret; > + restore->snapshot_alloc = alloc; > + restore->pool = pool; > + restore->restored_pages = 1; > > + tt->restore = restore; > + } else { > alloc = restore->snapshot_alloc; > - if (ttm_pool_restore_valid(tt->restore)) { > - ret = ttm_pool_restore_commit(restore, tt->backup, ctx, &alloc); > + if (ttm_pool_restore_valid(restore)) { > + int ret = ttm_pool_restore_commit(restore, tt->backup, > + ctx, &alloc); > + > if (ret) > return ret; > } > @@ -869,7 +871,7 @@ int ttm_pool_restore_and_alloc(struct ttm_pool *pool, struct ttm_tt *tt, > return 0; > } > > - return __ttm_pool_alloc(pool, tt, ctx, &alloc, tt->restore); > + return __ttm_pool_alloc(pool, tt, ctx, &alloc, restore); > } > > /** > diff --git a/drivers/gpu/drm/ttm/ttm_resource.c b/drivers/gpu/drm/ttm/ttm_resource.c > index 2a05fbd075465..8396cab34cb03 100644 > --- a/drivers/gpu/drm/ttm/ttm_resource.c > +++ b/drivers/gpu/drm/ttm/ttm_resource.c > @@ -620,11 +620,11 @@ ttm_resource_cursor_check_bulk(struct ttm_resource_cursor *cursor, > struct ttm_lru_item *next_lru) > { > struct ttm_resource *next = ttm_lru_item_to_res(next_lru); > - struct ttm_lru_bulk_move *bulk = NULL; > - struct ttm_buffer_object *bo = next->bo; > + struct ttm_lru_bulk_move *bulk; > > lockdep_assert_held(&cursor->man->bdev->lru_lock); > - bulk = bo->bulk_move; > + > + bulk = next->bo->bulk_move; > > if (cursor->bulk != bulk) { > if (bulk) { > -- > 2.53.0 > ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 6.18.y 1/2] drm/ttm: Tidy usage of local variables a little bit 2026-09-12 20:40 ` [PATCH 6.18.y 1/2] drm/ttm: Tidy usage of local variables a little bit Thadeu Lima de Souza Cascardo @ 2026-09-15 2:03 ` Sasha Levin 2026-09-17 10:15 ` Greg KH 0 siblings, 1 reply; 6+ messages in thread From: Sasha Levin @ 2026-09-15 2:03 UTC (permalink / raw) To: stable Cc: Sasha Levin, Tvrtko Ursulin, Christian König, Tvrtko Ursulin, Thadeu Lima de Souza Cascardo > You need to apply 91d7e9df4259 ("drm/ttm: Fix bo resource use-after-free") > too, otherwise this introduces a UAF. Agreed, and thanks for catching it. 91d7e9df4259 ("drm/ttm: Fix bo resource use-after-free") fixes c06da4b3573a ("drm/ttm: Tidy usage of local variables a little bit"), which is not in 6.18.y yet, so it has nothing to apply against today. I will take it together with the series rather than on its own, so the two land in the same release. -- Thanks, Sasha ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 6.18.y 1/2] drm/ttm: Tidy usage of local variables a little bit 2026-09-15 2:03 ` Sasha Levin @ 2026-09-17 10:15 ` Greg KH 0 siblings, 0 replies; 6+ messages in thread From: Greg KH @ 2026-09-17 10:15 UTC (permalink / raw) To: Sasha Levin Cc: stable, Tvrtko Ursulin, Christian König, Tvrtko Ursulin, Thadeu Lima de Souza Cascardo On Mon, Sep 14, 2026 at 10:03:21PM -0400, Sasha Levin wrote: > > You need to apply 91d7e9df4259 ("drm/ttm: Fix bo resource use-after-free") > > too, otherwise this introduces a UAF. > > Agreed, and thanks for catching it. 91d7e9df4259 ("drm/ttm: Fix bo resource > use-after-free") fixes c06da4b3573a ("drm/ttm: Tidy usage of local variables a > little bit"), which is not in 6.18.y yet, so it has nothing to apply against > today. I will take it together with the series rather than on its own, so the > two land in the same release. I've done this now, thanks. greg k-h ^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2026-09-17 10:29 UTC | newest] Thread overview: 6+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-09-09 11:54 FAILED: patch "[PATCH] drm/ttm: Drop tt->restore after successful restore" failed to apply to 6.18-stable tree gregkh 2026-09-12 14:34 ` [PATCH 6.18.y 1/2] drm/ttm: Tidy usage of local variables a little bit Sasha Levin 2026-09-12 14:34 ` [PATCH 6.18.y 2/2] drm/ttm: Drop tt->restore after successful restore Sasha Levin 2026-09-12 20:40 ` [PATCH 6.18.y 1/2] drm/ttm: Tidy usage of local variables a little bit Thadeu Lima de Souza Cascardo 2026-09-15 2:03 ` Sasha Levin 2026-09-17 10:15 ` Greg KH
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox