From: sashiko-bot@kernel.org
To: "Umesh Nerlige Ramappa" <umesh.nerlige.ramappa@intel.com>,
intel-xe@lists.freedesktop.org
Subject: Re: [PATCH v2 2/3] drm/xe/oa: Gate OA buffer mmap faults
Date: Fri, 30 Oct 2026 22:52:16 +0000 [thread overview]
Message-ID: <sashiko-outbox-191602@kernel.org> (raw)
In-Reply-To: <20261030223056.2266638-7-umesh.nerlige.ramappa@intel.com>
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [High] drm/xe/oa: ungated vm_ops->access in xe_oa_vm_ops via xe_bo_vm_access()
- [Medium] drm/xe/oa: race in xe_oa_buffer_fault() allows dummy page install on unplug
--
commit 64c07f18c9e0cff9e9ee88554ddca7219cc0526e
Author: Umesh Nerlige Ramappa <umesh.nerlige.ramappa@intel.com>
drm/xe/oa: Gate OA buffer mmap faults
This commit adds xe_oa_buffer_fault() and xe_oa_vm_ops to return
VM_FAULT_SIGBUS when faulting on a mapped OA buffer after stream->dead is set,
and rejects new mmaps in xe_oa_mmap() when the stream is dead. It also exposes
xe_bo_cpu_fault() and xe_bo_vm_access() for reuse in xe_oa_vm_ops.
> diff --git a/drivers/gpu/drm/xe/xe_oa.c b/drivers/gpu/drm/xe/xe_oa.c
> index 7e3ebba0300d6..4916101fce541 100644
> --- a/drivers/gpu/drm/xe/xe_oa.c
> +++ b/drivers/gpu/drm/xe/xe_oa.c
> @@ -1723,6 +1723,28 @@ static int xe_oa_release(struct inode *inode, struct file *file)
> return 0;
> }
>
> +static vm_fault_t xe_oa_buffer_fault(struct vm_fault *vmf)
> +{
> + struct xe_oa_stream *stream = vmf->vma->vm_file->private_data;
> +
> + /*
> + * Once the stream is dead its OA buffer may already be gone (or about
> + * to be). Refuse to (re-)install a PTE rather than letting the
> + * generic BO fault handler touch a buffer that's being torn down.
> + */
> + if (READ_ONCE(stream->dead))
> + return VM_FAULT_SIGBUS;
> +
> + return xe_bo_cpu_fault(vmf);
> +}
[Severity: Medium]
Can a page fault racing with device unplug, reset, or wedging bypass the
VM_FAULT_SIGBUS gate in xe_oa_buffer_fault() and install dummy zero-page PTEs
across the VMA via xe_bo_cpu_fault()?
In xe_oa_buffer_fault(), READ_ONCE(stream->dead) is checked locklessly outside
the drm_dev_enter() SRCU critical section before calling xe_bo_cpu_fault():
drivers/gpu/drm/xe/xe_bo.c:xe_bo_cpu_fault() {
...
if (xe_wedged(xe) || !drm_dev_enter(&xe->drm, &idx))
return ttm_bo_vm_dummy_page(vmf, vmf->vma->vm_page_prot);
...
}
If a fault passes the check in xe_oa_buffer_fault() right before
drm_dev_unplug() sets dev->unplugged in xe_device_remove(),
drm_dev_enter(&xe->drm, &idx) in xe_bo_cpu_fault() returns false and calls
ttm_bo_vm_dummy_page() without holding drm_unplug_srcu. Because
synchronize_srcu(&drm_unplug_srcu) does not wait for that fault,
unmap_mapping_range() and OA buffer teardown can finish before
ttm_bo_vm_dummy_page() completes prefaulting zero pages across [vma->vm_start,
vma->vm_end) and returning VM_FAULT_NOPAGE instead of VM_FAULT_SIGBUS.
Similarly, if the device is wedged via xe_wedge_declare() or
prepare_device_for_reset() while stream->dead and dev->unplugged are still
false, a fault on the OA buffer passes xe_oa_buffer_fault() and hits the
xe_wedged(xe) check in xe_bo_cpu_fault(), prefaulting dummy pages instead of
returning VM_FAULT_SIGBUS.
Additionally, in the follow-up commit ("drm/xe/oa: Quiesce OA streams on
driver unbind and PCI reset"), if a fault evaluates READ_ONCE(stream->dead) as
false and is preempted before evaluating
drm_dev_is_unplugged(&stream->oa->xe->drm) while xe_oa_fini() completes
xe_oa_quiesce() and sets oa->xe = NULL, could dereferencing stream->oa->xe
cause a NULL pointer dereference?
> +
> +static const struct vm_operations_struct xe_oa_vm_ops = {
> + .fault = xe_oa_buffer_fault,
> + .open = ttm_bo_vm_open,
> + .close = ttm_bo_vm_close,
> + .access = xe_bo_vm_access,
> +};
[Severity: High]
Should xe_oa_vm_ops also gate or omit .access instead of wiring it directly to
xe_bo_vm_access()?
In xe_oa_mmap(), the VMA is configured as read-only with VM_PFNMAP (and
drm_gem_mmap_obj() / ttm_bo_mmap_obj() sets VM_IO | VM_PFNMAP):
drivers/gpu/drm/xe/xe_oa.c:xe_oa_mmap() {
...
if (vma->vm_flags & (VM_WRITE | VM_EXEC | VM_SHARED | VM_MAYSHARE)) {
drm_dbg(&stream->oa->xe->drm, "mmap must be read only\n");
return -EINVAL;
}
vm_flags_mod(vma, VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP | VM_DONTCOPY,
VM_MAYWRITE | VM_MAYEXEC);
...
}
When userspace accesses this mapping through /proc/<pid>/mem, ptrace(),
process_vm_readv(), or process_vm_writev(), __access_remote_vm() fails in
get_user_page_vma_remote() and falls back to vma->vm_ops->access(), which
calls xe_bo_vm_access():
drivers/gpu/drm/xe/xe_bo.c:xe_bo_vm_access() {
struct ttm_buffer_object *ttm_bo = vma->vm_private_data;
struct xe_bo *bo = ttm_to_xe_bo(ttm_bo);
struct xe_device *xe = xe_bo_device(bo);
guard(xe_pm_runtime)(xe);
return ttm_bo_vm_access(vma, addr, buf, len, write);
}
Because vma->vm_private_data retains a GEM reference to the BO until the VMA
is unmapped, calling xe_bo_vm_access() after stream->dead is set bypasses the
stream->dead check, takes a runtime PM reference, and calls ttm_bo_vm_access()
-> xe_ttm_access_memory() on the torn-down OA buffer. When the OA buffer was
placed in VRAM (mert_wa_14026633728) and vram_fini() has cleared
vram->mapping to NULL during unbind, xe_ttm_access_memory() will dereference a
NULL vram->mapping pointer.
Furthermore, because __access_remote_vm() passes write = 1 on FOLL_WRITE and
neither xe_bo_vm_access() nor ttm_bo_vm_access() checks whether write is
non-zero, doesn't wiring .access to xe_bo_vm_access() also allow writing to
the read-only OA buffer via /proc/self/mem or process_vm_writev()?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261030223056.2266638-5-umesh.nerlige.ramappa@intel.com?part=2
next prev parent reply other threads:[~2026-10-30 22:52 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-30 22:30 [PATCH v2 0/3] Cleanup OA stream on PCI unbind/remove Umesh Nerlige Ramappa
2026-10-30 22:30 ` [PATCH v2 1/3] drm/xe/oa: Use the drm device address_space for the OA stream fd Umesh Nerlige Ramappa
2026-10-30 22:30 ` [PATCH v2 2/3] drm/xe/oa: Gate OA buffer mmap faults Umesh Nerlige Ramappa
2026-10-30 22:52 ` sashiko-bot [this message]
2026-10-30 22:31 ` [PATCH v2 3/3] drm/xe/oa: Quiesce OA streams on driver unbind and PCI reset Umesh Nerlige Ramappa
2026-10-30 23:14 ` sashiko-bot
2026-10-30 22:36 ` [PATCH v2 0/3] Cleanup OA stream on PCI unbind/remove Umesh Nerlige Ramappa
2026-10-30 22:40 ` ✓ CI.KUnit: success for " Patchwork
2026-10-30 23:14 ` ✓ Xe.CI.BAT: " Patchwork
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-191602@kernel.org \
--to=sashiko-bot@kernel.org \
--cc=intel-xe@lists.freedesktop.org \
--cc=sashiko-reviews@lists.linux.dev \
--cc=umesh.nerlige.ramappa@intel.com \
/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