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
next prev parent 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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox