Re: [PATCH v4 4/8] drm/xe/bo: Handle CPU faults on purged buffer objects

Matthew Brost
2026-01-20T17:23:43Z

On Tue, Jan 20, 2026 at 11:38:50AM +0530, Arvind Yadav wrote:
> Return error when CPU attempts to access a purged buffer object.
> Purged BOs have their backing store reclaimed by the kernel, making
> CPU access invalid. The fault handler returns SIGBUS to userspace,
> matching i915 semantics.
>
> The purged check is added to both CPU fault paths:
> - Fastpath (xe_bo_cpu_fault_fastpath): Returns error immediately
> under dma-resv lock, preventing attempts to migrate/validate freed pages
> - Slowpath (xe_bo_cpu_fault): Returns -EFAULT under drm_exec lock,
> converted to VM_FAULT_SIGBUS
>
> Without the fastpath check, accessing existing mmap mappings of purged BOs
> would trigger xe_bo_fault_migrate() on freed backing store, causing kernel
> hangs or crashes.
>
> v2:
> - Added xe_bo_is_purged(bo) instead of atomic_read.
> - Avoids leaks and keeps drm_dev_exit() while returning.
>
> v3:
> - Move xe_bo_is_purged check under a dma-resv lock (Matthew Brost)
>
> v4:
> - Add purged check to fastpath (xe_bo_cpu_fault_fastpath) to prevent
> hang when accessing existing mmap of purged BO
>
> Cc: Matthew Brost <matthew.brost@intel.com>

Reviewed-by: Matthew Brost <matthew.brost@intel.com>

> Cc: Thomas Hellström <thomas.hellstrom@linux.intel.com>
> Cc: Himal Prasad Ghimiray <himal.prasad.ghimiray@intel.com>
> Signed-off-by: Arvind Yadav <arvind.yadav@intel.com>
> ---
> drivers/gpu/drm/xe/xe_bo.c | 12 ++++++++++++
> 1 file changed, 12 insertions(+)
>
> diff --git a/drivers/gpu/drm/xe/xe_bo.c b/drivers/gpu/drm/xe/xe_bo.c
> index d0a6d340b255..cc547915161d 100644
> --- a/drivers/gpu/drm/xe/xe_bo.c
> +++ b/drivers/gpu/drm/xe/xe_bo.c
> @@ -1934,6 +1934,12 @@ static vm_fault_t xe_bo_cpu_fault_fastpath(struct vm_fault *vmf, struct xe_devic
> if (!dma_resv_trylock(tbo->base.resv))
> goto out_validation;
>
> + /* Purged BOs have no backing store - fault to userspace */
> + if (xe_bo_is_purged(bo)) {
> + ret = VM_FAULT_SIGBUS;
> + goto out_unlock;
> + }
> +
> if (xe_ttm_bo_is_imported(tbo)) {
> ret = VM_FAULT_SIGBUS;
> drm_dbg(&xe->drm, "CPU trying to access an imported buffer object.\n");
> @@ -2024,6 +2030,12 @@ static vm_fault_t xe_bo_cpu_fault(struct vm_fault *vmf)
> if (err)
> break;
>
> + /* Purged BOs have no backing store - fault to userspace */
> + if (xe_bo_is_purged(bo)) {
> + err = -EFAULT;
> + break;
> + }
> +
> if (xe_ttm_bo_is_imported(tbo)) {
> err = -EFAULT;
> drm_dbg(&xe->drm, "CPU trying to access an imported buffer object.\n");
> --
> 2.43.0
>