All of lore.kernel.org
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Nareshkumar Gollakoti" <naresh.kumar.g@intel.com>,
	intel-xe@lists.freedesktop.org
Subject: Re: [PATCH 6/6] drm/xe/pagefault: add CPU mirror VMA for SVA faults without PRI
Date: Wed, 21 Oct 2026 04:35:01 +0000	[thread overview]
Message-ID: <sashiko-outbox-179786@kernel.org> (raw)
In-Reply-To: <20261021041117.1774877-7-naresh.kumar.g@intel.com>

Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [Critical] drm/xe: NULL deref and uninitialized PAT in xe_vm_alloc_cpu_addr_mirror_vma()
- [High] drm/xe: 4K VMA check before 64K mirror alloc in xe_pagefault_service()
--

commit c441331b0c386c437e9ad479c73465c57bd86054
Author: Nareshkumar Gollakoti <naresh.kumar.g@intel.com>

drm/xe/pagefault: add CPU mirror VMA for SVA faults without PRI

This commit adds on-demand creation of a cpu-address-mirror vma in
xe_pagefault_service() when servicing sva faults on platforms with ats/pasid
enabled but without pri support. It also introduces the
XE_PAGEFAULT_ERROR_VMA_ALLOC error code to report vma allocation failures.

> diff --git a/drivers/gpu/drm/xe/xe_pagefault.c b/drivers/gpu/drm/xe/xe_pagefault.c
> index 5247321c805ec..fbdf12d3d5580 100644
> --- a/drivers/gpu/drm/xe/xe_pagefault.c
> +++ b/drivers/gpu/drm/xe/xe_pagefault.c
[ ... ]
> @@ -298,6 +300,51 @@ static int xe_pagefault_service(struct xe_pagefault *pf)
>  	}
>  
>  	vma = xe_vm_find_vma_by_addr(vm, xe_pagefault_addr(pf));
> +
> +	/*
> +	 * ATS/PASID is negotiated but this hardware has no PRI, so there is
> +	 * no IOMMU self-healing path to fault the page in - the driver has
> +	 * to create the missing CPU-address-mirror binding itself and let
> +	 * the SVM path below service the fault.
> +	 */
> +	if (!vma && vm->sva_handle && xe_pci_svm_needs_sw_iopf(pdev)) {
> +		u64 page_size = vm->flags & XE_VM_FLAG_64K ? SZ_64K : SZ_4K;
> +		u64 start = ALIGN_DOWN(xe_pagefault_addr(pf), page_size);
> +		u64 end = start + page_size;
> +		int alloc_err = 0;
> +
> +		up_read(&vm->lock);
> +		down_write(&vm->lock);
> +		/* Lock was dropped, re-check: a racing fault may have won */
> +		vma = xe_vm_find_vma_by_addr(vm, xe_pagefault_addr(pf));

[Severity: High]
When vm->flags & XE_VM_FLAG_64K is set, xe_pagefault_service() aligns start
and end to SZ_64K, but xe_vm_find_vma_by_addr() in drivers/gpu/drm/xe/xe_vm.c
only checks a 4k range at the faulting address:

drivers/gpu/drm/xe/xe_vm.c:xe_vm_find_vma_by_addr() {
	return xe_vm_find_overlapping_vma(vm, page_addr, SZ_4K);
}

Because vm_bind_ioctl_check_args() in drivers/gpu/drm/xe/xe_vm.c and
madvise_args_are_sane() in drivers/gpu/drm/xe/xe_vm_madvise.c allow
4k-aligned mappings on 64k vms (xe_vm_bind_ioctl_validate_bo() only requires
64k alignment for bos with XE_BO_FLAG_INTERNAL_64K), another 4k-aligned vma
(such as a system-memory bo, userptr, sparse vma, or madvise-split vma) can
already exist elsewhere within [start, end).

If a fault hits an unmapped 4k page in that 64k window without first checking
xe_vm_find_overlapping_vma(vm, start, page_size), won't
xe_vm_alloc_cpu_addr_mirror_vma() -> xe_vm_alloc_vma() ->
drm_gpuvm_sm_map_ops_create() generate unmap or remap operations that destroy
the overlapping vma via xe_vma_destroy() without unbinding its page tables or
holding bo->ttm.base.resv, triggering xe_bo_assert_held(bo) in
xe_vma_destroy()?

> +		if (!vma) {
> +			if (xe_vm_is_closed_or_banned(vm)) {
> +				alloc_err = -ENOENT;
> +			} else {
> +				/* Merge with adjacent mirror VMAs instead of leaving singletons */
> +				xe_vm_find_cpu_addr_mirror_vma_range(vm, &start, &end);
> +				alloc_err = xe_vm_alloc_cpu_addr_mirror_vma(vm, start, end - start);

[Severity: Critical]
What happens in xe_pagefault_service() when a fault occurs at an address with
no immediately adjacent default-attribute mirror vma at start - SZ_4K or
end + 1 (such as the first sva page fault in the vm)?

In that case, xe_vm_find_cpu_addr_mirror_vma_range() leaves [start, end)
unchanged so the range does not overlap any existing gpuva in vm->gpuvm.

When xe_vm_alloc_cpu_addr_mirror_vma() calls xe_vm_alloc_vma(vm, &map_req,
false) in drivers/gpu/drm/xe/xe_vm.c, vma_flags is initialized to 0 and
default_pat is left uninitialized on the stack, because both are only
populated from an existing vma during DRM_GPUVA_OP_UNMAP or
DRM_GPUVA_OP_REMAP:

drivers/gpu/drm/xe/xe_vm.c:xe_vm_alloc_vma() {
	unsigned int vma_flags = 0;
	bool remap_op = false;
	struct xe_vma_mem_attr tmp_attr = {};
	u16 default_pat;
	...
		if (!is_madvise) {
			if (__op->op == DRM_GPUVA_OP_UNMAP) {
				vma = gpuva_to_vma(op->base.unmap.va);
				XE_WARN_ON(!xe_vma_has_default_mem_attrs(vma));
				default_pat = vma->attr.default_pat_index;
				vma_flags = vma->gpuva.flags;
			}

			if (__op->op == DRM_GPUVA_OP_REMAP) {
				vma = gpuva_to_vma(op->base.remap.unmap->va);
				default_pat = vma->attr.default_pat_index;
				vma_flags = vma->gpuva.flags;
			}

			if (__op->op == DRM_GPUVA_OP_MAP) {
				op->map.vma_flags |= vma_flags & XE_VMA_CREATE_MASK;
				op->map.pat_index = default_pat;
			}
		}
}

Because drm_gpuvm_sm_map_ops_create() only emits DRM_GPUVA_OP_MAP when no
existing gpuva overlaps [start, end), op->map.vma_flags remains 0 (missing
XE_VMA_SYSTEM_ALLOCATOR) and op->map.pat_index uses the uninitialized
default_pat variable.

From there, vm_bind_ioctl_ops_parse() -> new_vma() -> xe_vma_create() in
drivers/gpu/drm/xe/xe_vm.c sees !bo && !is_null && !is_cpu_addr_mirror,
allocates a struct xe_userptr_vma instead of a mirror vma, and calls
xe_userptr_setup() in drivers/gpu/drm/xe/xe_userptr.c:

drivers/gpu/drm/xe/xe_userptr.c:xe_userptr_setup() {
	...
	err = mmu_interval_notifier_insert(&userptr->notifier, current->mm,
					   start, range,
					   &vma_userptr_notifier_ops);
}

Since xe_pagefault_service() runs on a workqueue kthread where current->mm is
NULL, won't this cause a null pointer dereference inside
mmu_interval_notifier_insert()?

> +			}
[ ... ]

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261021041117.1774877-1-naresh.kumar.g@intel.com?part=6

  reply	other threads:[~2026-10-21  4:35 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-21  4:11 [PATCH 0/6] ATS/PASID SVA support and PRI-less fault servicing Nareshkumar Gollakoti
2026-10-21  4:11 ` [PATCH 1/6] drm/xe/pci: log ATS/PASID enablement state at probe Nareshkumar Gollakoti
2026-10-21  4:32   ` sashiko-bot
2026-10-21  4:11 ` [PATCH 2/6] drm/xe/vm: Setup SVA infrastructure for PASID support Nareshkumar Gollakoti
2026-10-21  4:30   ` sashiko-bot
2026-10-21  4:11 ` [PATCH 3/6] drm/xe/vm: add helper to retrieve VM SVA PASID Nareshkumar Gollakoti
2026-10-21  4:11 ` [PATCH 4/6] drm/xe/lrc: program CTX_SYS_PASID for ATS/PASID-enabled contexts Nareshkumar Gollakoti
2026-10-21  4:11 ` [PATCH 5/6] drm/xe/pci: add helper for ATS/PASID without PRI Nareshkumar Gollakoti
2026-10-21  4:11 ` [PATCH 6/6] drm/xe/pagefault: add CPU mirror VMA for SVA faults " Nareshkumar Gollakoti
2026-10-21  4:35   ` sashiko-bot [this message]
2026-10-21  4:21 ` ✗ CI.KUnit: failure for ATS/PASID SVA support and PRI-less fault servicing Patchwork
2026-10-21 15:25 ` [PATCH 0/6] " Thomas Hellström
2026-10-22  6:30   ` Kumar G, Naresh
2026-10-22 11:12     ` Thomas Hellström
2026-10-21 21:24 ` Matthew Brost

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=sashiko-outbox-179786@kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=intel-xe@lists.freedesktop.org \
    --cc=naresh.kumar.g@intel.com \
    --cc=sashiko-reviews@lists.linux.dev \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.