[PATCH] drm/amdkfd: Handle lack of READ permissions in SVM mapping
Felix Kuehling
felix.kuehling at amd.com
Fri Aug 8 20:57:38 UTC 2025
On 2025-08-08 16:28, Kent Russell wrote:
> HMM assumes that pages have READ permissions by default. Inside
> svm_range_validate_and_map, we add READ permissions then add WRITE
> permissions if the VMA isn't read-only. This will conflict with regions
> that only have PROT_WRITE or have PROT_NONE. When that happens,
> svm_range_restore_work will continue to retry, silently, giving the
> impression of a hang if pr_debug isn't enabled to show the retries..
>
> If pages don't have READ permissions, simply unmap them and continue. If
> they weren't mapped in the first place, this would be a no-op. Since x86
> doesn't support write-only, and PROT_NONE doesn't allow reads or writes
> anyways, this will allow the svm range validation to continue without
> getting stuck in a loop forever on mappings we can't use with HMM.
>
> Signed-off-by: Kent Russell <kent.russell at amd.com>
Reviewed-by: Felix Kuehling <felix.kuehling at amd.com>
> ---
> drivers/gpu/drm/amd/amdkfd/kfd_svm.c | 23 +++++++++++++++++++++++
> 1 file changed, 23 insertions(+)
>
> diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
> index e23b5a0f31f2..521c14c7a789 100644
> --- a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
> +++ b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
> @@ -1713,6 +1713,29 @@ static int svm_range_validate_and_map(struct mm_struct *mm,
>
> next = min(vma->vm_end, end);
> npages = (next - addr) >> PAGE_SHIFT;
> + /* HMM requires at least READ permissions. If provided with PROT_NONE,
> + * unmap the memory. If it's not already mapped, this is a no-op
> + * If PROT_WRITE is provided without READ, warn first then unmap
> + */
> + if (!(vma->vm_flags & VM_READ)) {
> + unsigned long e, s;
> +
> + svm_range_lock(prange);
> + if (vma->vm_flags & VM_WRITE)
> + pr_debug("VM_WRITE without VM_READ is not supported");
> + s = max(start, prange->start);
> + e = min(end, prange->last);
> + if (e >= s)
> + r = svm_range_unmap_from_gpus(prange, s, e,
> + KFD_SVM_UNMAP_TRIGGER_UNMAP_FROM_CPU);
> + svm_range_unlock(prange);
> + /* If unmap returns non-zero, we'll bail on the next for loop
> + * iteration, so just leave r and continue
> + */
> + addr = next;
> + continue;
> + }
> +
> WRITE_ONCE(p->svms.faulting_task, current);
> r = amdgpu_hmm_range_get_pages(&prange->notifier, addr, npages,
> readonly, owner, NULL,
More information about the amd-gfx
mailing list