This is a note to let you know that I've just added the patch titled

    drm/ttm: Account for NULL and handle pages in ttm_pool_backup

to the 7.1-stable tree which can be found at:
    
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     drm-ttm-account-for-null-and-handle-pages-in-ttm_pool_backup.patch
and it can be found in the queue-7.1 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <[email protected]> know about it.


>From 5b7b3b6595ee77d01c7463757baed114786094dd Mon Sep 17 00:00:00 2001
From: Matthew Brost <[email protected]>
Date: Thu, 2 Jul 2026 14:48:15 -0700
Subject: drm/ttm: Account for NULL and handle pages in ttm_pool_backup
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

From: Matthew Brost <[email protected]>

commit 5b7b3b6595ee77d01c7463757baed114786094dd upstream.

Pages in ttm_pool_backup can be NULL or backup handles
(ttm_backup_page_ptr_is_handle()), neither of which can be passed to
set_pages_array_wb() or freed. Add a dedicated WB pass before the
dma/purge loop that walks allocations using the same i += num_pages
stride, skipping NULL and handle entries, and calls set_pages_array_wb()
once per contiguous run of real pages. Apply the same NULL/handle guard
to the dma/purge loop.

Fixes the following oops:

Oops: general protection fault, kernel NULL pointer dereference 0x0: 0000 [#1] 
SMP NOPTI
RIP: 0010:__cpa_process_fault+0xf8/0x770
RSP: 0018:ffffc90000a87718 EFLAGS: 00010287
RAX: 0000000000000000 RBX: ffffc90000a87868 RCX: 0000000000000000
RDX: 0000000000001000 RSI: 0005088000000000 RDI: ffffffff827c5f34
RBP: 0005088000000000 R08: ffffc90000a877cb R09: ffffc90000a877d0
R10: 0000000000000000 R11: 000000000000001b R12: 000ffffffffff000
R13: ffffc90000a87868 R14: ffffc90000a87868 R15: ffff88815b882ae0
FS:  0000000000000000(0000) GS:ffff8884ec840000(0000) knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00007f930b844000 CR3: 000000000262e003 CR4: 0000000008f70ef0
PKRU: 55555554
Call Trace:
 <TASK>
 __change_page_attr_set_clr+0x989/0xe90
 ? __purge_vmap_area_lazy+0x6c/0x3a0
 ? _vm_unmap_aliases+0x250/0x2a0
 set_pages_array_wb+0x7f/0x120
 ttm_pool_backup+0x4c9/0x5b0 [ttm]
 ? dma_resv_wait_timeout+0x3b/0xf0
 ttm_tt_backup+0x32/0x60 [ttm]
 ttm_bo_shrink+0x66/0x110 [ttm]
 xe_bo_shrink_purge+0x12b/0x1b0 [xe]
 xe_bo_shrink+0xbb/0x270 [xe]
 __xe_shrinker_walk+0xf7/0x160 [xe]
 xe_shrinker_walk+0x9d/0xc0 [xe]
 xe_shrinker_scan+0x11f/0x210 [xe]
 do_shrink_slab+0x13b/0x270
 shrink_slab+0xf1/0x400
 shrink_node+0x352/0x8a0
 balance_pgdat+0x32c/0x700
 kswapd+0x205/0x2f0
 ? __pfx_autoremove_wake_function+0x10/0x10
 ? __pfx_kswapd+0x10/0x10
 kthread+0xd1/0x110
 ? __pfx_kthread+0x10/0x10
 ret_from_fork+0x1b1/0x200
 ? __pfx_kthread+0x10/0x10
 ret_from_fork_asm+0x1a/0x30
 </TASK>

Cc: Christian Koenig <[email protected]>
Cc: Huang Rui <[email protected]>
Cc: Matthew Auld <[email protected]>
Cc: Matthew Brost <[email protected]>
Cc: Maarten Lankhorst <[email protected]>
Cc: Maxime Ripard <[email protected]>
Cc: Thomas Zimmermann <[email protected]>
Cc: David Airlie <[email protected]>
Cc: Simona Vetter <[email protected]>
Cc: Thomas Hellström <[email protected]>
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Fixes: b63d715b8090 ("drm/ttm/pool, drm/ttm/tt: Provide a helper to shrink 
pages")
Cc: [email protected]
Assisted-by: GitHub_Copilot:claude-opus-4.8
Signed-off-by: Matthew Brost <[email protected]>
Reviewed-by: Thomas Hellström <[email protected]>
Link: https://patch.msgid.link/[email protected]
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
 drivers/gpu/drm/ttm/ttm_pool.c |   34 ++++++++++++++++++++++++++++++----
 1 file changed, 30 insertions(+), 4 deletions(-)

--- a/drivers/gpu/drm/ttm/ttm_pool.c
+++ b/drivers/gpu/drm/ttm/ttm_pool.c
@@ -1051,9 +1051,31 @@ long ttm_pool_backup(struct ttm_pool *po
                return -EBUSY;
 
 #ifdef CONFIG_X86
-       /* Anything returned to the system needs to be cached. */
-       if (tt->caching != ttm_cached)
-               set_pages_array_wb(tt->pages, tt->num_pages);
+       /* Anything returned to the system needs to be cached. Walk allocations
+        * skipping NULL pages and issue set_pages_array_wb() per contiguous 
run.
+        */
+       if (tt->caching != ttm_cached) {
+               pgoff_t run_start = 0, run_count = 0;
+
+               for (i = 0; i < tt->num_pages; i += num_pages) {
+                       page = tt->pages[i];
+                       if (unlikely(!page || 
ttm_backup_page_ptr_is_handle(page))) {
+                               if (run_count) {
+                                       
set_pages_array_wb(&tt->pages[run_start],
+                                                          run_count);
+                                       run_count = 0;
+                               }
+                               num_pages = 1;
+                               continue;
+                       }
+                       num_pages = 1UL << ttm_pool_page_order(pool, page);
+                       if (!run_count)
+                               run_start = i;
+                       run_count += num_pages;
+               }
+               if (run_count)
+                       set_pages_array_wb(&tt->pages[run_start], run_count);
+       }
 #endif
 
        if (tt->dma_address || flags->purge) {
@@ -1061,7 +1083,7 @@ long ttm_pool_backup(struct ttm_pool *po
                        unsigned int order;
 
                        page = tt->pages[i];
-                       if (unlikely(!page)) {
+                       if (unlikely(!page || 
ttm_backup_page_ptr_is_handle(page))) {
                                num_pages = 1;
                                continue;
                        }
@@ -1104,6 +1126,10 @@ long ttm_pool_backup(struct ttm_pool *po
                if (unlikely(!page))
                        continue;
 
+               /* Already-handled entry from a previous attempt. */
+               if (unlikely(ttm_backup_page_ptr_is_handle(page)))
+                       continue;
+
                ttm_pool_split_for_swap(pool, page);
 
                shandle = ttm_backup_backup_page(backup, page, 
flags->writeback, i,


Patches currently in stable-queue which might be from [email protected] 
are

queue-7.1/drm-xe-guc-fix-buffer-overflow-in-steered-register-list-allocation.patch
queue-7.1/drm-i915-gem-add-missing-nospec-on-parallel-submit-slot.patch
queue-7.1/drm-xe-vf-add-drm_dev-guards-when-detaching-ccs-read.patch
queue-7.1/drm-xe-vm-fix-bo-prefetch-with-consult_mem_advise_pref_loc.patch
queue-7.1/drm-xe-display-skip-force_wc-and-vm_bound-check-for-external-dma-bufs.patch
queue-7.1/drm-ttm-account-for-null-and-handle-pages-in-ttm_pool_backup.patch
queue-7.1/drm-xe-pt-reset-current_op-in-xe_pt_update_ops_init.patch
queue-7.1/drm-xe-return-error-on-non-migratable-faults-requiring-devmem.patch
queue-7.1/drm-xe-vm-fix-svm-leak-on-resv-obj-alloc-failure-in-.patch
queue-7.1/drm-xe-fix-pte-index-in-xe_vm_populate_pgtable-for-chunked-binds.patch
queue-7.1/drm-xe-assign-queue-name-in-time-for-drm_sched_init.patch
queue-7.1/drm-xe-madvise-skip-invalidation-for-purgeable-state-updates.patch
queue-7.1/drm-xe-vf-fix-vf-ccs-attach-detach-race-with-in-flig.patch
queue-7.1/drm-gpusvm-publish-dpagemap-early-to-avoid-device-mapping-leak-on-error.patch
queue-7.1/drm-xe-guc-hold-device-ref-until-queue-teardown-comp.patch
queue-7.1/drm-xe-guc-keep-scheduler-timeline-name-alive.patch
queue-7.1/drm-i915-gt-fix-null-deref-on-sched_engine-alloc-failure.patch
queue-7.1/drm-xe-add-compact-pt-and-addr-mask-handling-for-page-reclaim.patch

Reply via email to