All of lore.kernel.org
 help / color / mirror / Atom feed
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

  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 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.