Intel-XE Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Arvind Yadav" <arvind.yadav@intel.com>, intel-xe@lists.freedesktop.org
Subject: Re: [PATCH v2 2/3] CI_ONLY Mark VMs as closing before queue cleanup
Date: Fri, 13 Nov 2026 07:51:42 +0000	[thread overview]
Message-ID: <sashiko-outbox-212370@kernel.org> (raw)
In-Reply-To: <20261113073549.352746-3-arvind.yadav@intel.com>

Thank you for your contribution! Sashiko AI review found 1 potential
issue to consider:
- [High] drm/xe: NULL pointer dereference in xe_pagefault_print() on
  ack_fault failure
--

commit 213c218fbf049faac8f39a23293d5c3f7bb580b5
Author: Arvind Yadav <arvind.yadav@intel.com>

CI_ONLY Mark VMs as closing before queue cleanup

This commit introduces an XE_VM_FLAG_CLOSING state set before asynchronous
queue teardown to block new VM work and serialize cached page-fault
acknowledgments against VM closure.

> diff --git a/drivers/gpu/drm/xe/xe_pagefault.c b/drivers/gpu/drm/xe/xe_pagefault.c
> index 98cce0f12b123..ac05e7b6315de 100644
> --- a/drivers/gpu/drm/xe/xe_pagefault.c
> +++ b/drivers/gpu/drm/xe/xe_pagefault.c

[ ... ]

> @@ -678,32 +678,35 @@ static void xe_pagefault_queue_work(struct work_struct *w)
>  
>  	while (xe_pagefault_queue_pop(pf_queue, &pf, pf_work->id)) {
>  		const struct xe_pagefault_ops *ops = pf->producer.ops;
> +		struct xe_vm *ack_vm = NULL;
>  		void *private = pf->producer.private;
>  		struct xe_gt *gt = pf->gt;
>  		u32 asid = FIELD_GET(XE_PAGEFAULT_ASID_MASK, pf->consumer.id);
> +		struct xe_pagefault original = {
> +			.gt = gt,
> +			.consumer = {
> +				.page_addr = pf->consumer.page_addr,
> +				.access_type = pf->consumer.access_type,
> +				.fault_type_level = pf->consumer.fault_type_level,
> +				.engine_class_instance =
> +					pf->consumer.engine_class_instance,
> +				.id = pf->consumer.id,
> +			},
> +		};
> +		struct xe_pagefault *report_pf = pf;
>  		int err = 0;
>  		bool invalidated = false;
> +		bool cache_hit = false;
>  
>  		/* Last fault same address, ack immediately */
>  		if (xe_pagefault_match(pf, cache_start, cache_end, cache_asid)) {
> -			xe_gt_stats_incr(gt, XE_GT_STATS_ID_LAST_PAGEFAULT_COUNT, 1);
> +			cache_hit = true;
>  			goto ack_fault;
>  		}
>  
>  		err = xe_pagefault_service(pf);
>  
> -		if (err) {
> -			if (!(pf->consumer.access_type & XE_PAGEFAULT_ACCESS_PREFETCH)) {
> -				xe_pagefault_save_to_vm(gt_to_xe(gt), pf);
> -				xe_pagefault_cache_start_invalidate(cache_start);
> -				xe_pagefault_print(pf);
> -				xe_log_err_info(pf->gt, PAGEFAULT, err, "Unsuccessful response\n");
> -			} else {
> -				xe_gt_stats_incr(pf->gt, XE_GT_STATS_ID_INVALID_PREFETCH_PAGEFAULT_COUNT, 1);
> -				xe_gt_dbg(pf->gt, "Prefetch Fault response: Unsuccessful %pe\n",
> -					  ERR_PTR(err));
> -			}
> -		} else {
> +		if (!err) {
>  			/* Cache valid fault locally */
>  			cache_start = xe_pagefault_start_addr(pf);
>  			cache_end = xe_pagefault_end_addr(pf);
> @@ -711,6 +714,55 @@ static void xe_pagefault_queue_work(struct work_struct *w)
>  		}
>  
>  ack_fault:
> +		/*
> +		 * Cache hits bypass fault service. Serialize successful replies
> +		 * with VM close, including replies to matching chained faults.
> +		 * Take vm->lock before ack_fault_begin() takes the CT lock and
> +		 * hold it until ack_fault_end() flushes the reply batch.
> +		 */
> +		if (!err) {
> +			/*
> +			 * Successful service may replace the fault fields with
> +			 * the resolved range. Use the original fields to report
> +			 * a failure detected here. Do not restore the live entry,
> +			 * which also contains queue state and chain links.
> +			 */
> +			report_pf = &original;
> +			ack_vm = xe_pagefault_asid_to_vm(report_pf, asid);
> +			if (IS_ERR(ack_vm)) {
> +				err = PTR_ERR(ack_vm);
> +				ack_vm = NULL;
> +			} else {
> +				down_read(&ack_vm->lock);
> +				if (xe_vm_is_closed_or_banned(ack_vm)) {
> +					xe_pagefault_set_error(report_pf,
> +							       XE_PAGEFAULT_ERROR_VM_CLOSED);
> +					err = -ENOENT;
> +					up_read(&ack_vm->lock);
> +					xe_vm_put(ack_vm);
> +					ack_vm = NULL;
> +				}
> +			}
> +		}
> +
> +		if (err) {
> +			xe_pagefault_cache_start_invalidate(cache_start);
> +			if (!(report_pf->consumer.access_type &
> +			      XE_PAGEFAULT_ACCESS_PREFETCH)) {
> +				xe_pagefault_save_to_vm(xe, report_pf);
> +				xe_pagefault_print(report_pf);

[Severity: High]
Does xe_pagefault_print(report_pf) dereference a NULL pf->producer.ops
pointer when the post-service ASID lookup or VM state check fails?

original only initializes .gt and .consumer, leaving original.producer
zero-initialized.  When report_pf is set to &original and the check at
ack_fault sets err, xe_pagefault_print(report_pf) dereferences
pf->producer.ops->print:

drivers/gpu/drm/xe/xe_pagefault.c:xe_pagefault_print() {
	enum xe_pagefault_error err = xe_pagefault_get_error(pf);

	if (WARN_ON_ONCE(!pf->producer.ops->print))
		return;

	pf->producer.ops->print(pf, xe_pagefault_error_to_str(err));
}

In addition, xe_guc_pagefault_print() reads pf->producer.msg to decode the
fault details, so original also needs .producer = pf->producer.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261113073549.352746-1-arvind.yadav@intel.com?part=2

  reply	other threads:[~2026-11-13  7:51 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-11-13  7:35 [PATCH v2 0/3] CI-ONLY Fix VM teardown and migration queue recovery Arvind Yadav
2026-11-13  7:35 ` [PATCH v2 1/3] CI_ONLY: Hold a device reference across deferred VM Arvind Yadav
2026-11-13  7:48   ` sashiko-bot
2026-11-13  7:35 ` [PATCH v2 2/3] CI_ONLY Mark VMs as closing before queue cleanup Arvind Yadav
2026-11-13  7:51   ` sashiko-bot [this message]
2026-11-13  7:35 ` [PATCH v2 3/3] CI-ONLY:Defer VM teardown until exec " Arvind Yadav
2026-11-13  8:32   ` sashiko-bot
2026-11-13  7:43 ` ✗ CI.checkpatch: warning for CI-ONLY Fix VM teardown and migration queue recovery (rev2) Patchwork
2026-11-13  7:45 ` ✓ CI.KUnit: success " Patchwork
2026-11-13  8:16 ` ✓ 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-212370@kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=arvind.yadav@intel.com \
    --cc=intel-xe@lists.freedesktop.org \
    --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