]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
drm/amdgpu: Handle GPU page faults correctly on non-4K page systems
authorDonet Tom <donettom@linux.ibm.com>
Mon, 23 Mar 2026 04:28:36 +0000 (09:58 +0530)
committerAlex Deucher <alexander.deucher@amd.com>
Tue, 24 Mar 2026 17:55:29 +0000 (13:55 -0400)
During a GPU page fault, the driver restores the SVM range and then maps it
into the GPU page tables. The current implementation passes a GPU-page-size
(4K-based) PFN to svm_range_restore_pages() to restore the range.

SVM ranges are tracked using system-page-size PFNs. On systems where the
system page size is larger than 4K, using GPU-page-size PFNs to restore the
range causes two problems:

Range lookup fails:
Because the restore function receives PFNs in GPU (4K) units, the SVM
range lookup does not find the existing range. This will result in a
duplicate SVM range being created.

VMA lookup failure:
The restore function also tries to locate the VMA for the faulting address.
It converts the GPU-page-size PFN into an address using the system page
size, which results in an incorrect address on non-4K page-size systems.
As a result, the VMA lookup fails with the message: "address 0xxxx VMA is
removed".

This patch passes the system-page-size PFN to svm_range_restore_pages() so
that the SVM range is restored correctly on non-4K page systems.

Acked-by: Christian König <christian.koenig@amd.com>
Signed-off-by: Donet Tom <donettom@linux.ibm.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit 074fe395fb13247b057f60004c7ebcca9f38ef46)

drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c

index d54afeb7b2a79d42c94d079b33171884fc5df409..a677e38a493b43d3ee52dd51469640c8a623e39a 100644 (file)
@@ -2974,14 +2974,14 @@ bool amdgpu_vm_handle_fault(struct amdgpu_device *adev, u32 pasid,
        if (!root)
                return false;
 
-       addr /= AMDGPU_GPU_PAGE_SIZE;
-
        if (is_compute_context && !svm_range_restore_pages(adev, pasid, vmid,
-           node_id, addr, ts, write_fault)) {
+           node_id, addr >> PAGE_SHIFT, ts, write_fault)) {
                amdgpu_bo_unref(&root);
                return true;
        }
 
+       addr /= AMDGPU_GPU_PAGE_SIZE;
+
        r = amdgpu_bo_reserve(root, true);
        if (r)
                goto error_unref;