All of lore.kernel.org
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Daniel Byrne" <daniel1.byrne@intel.com>
Cc: dmaengine@vger.kernel.org, vkoul@kernel.org, Frank.Li@kernel.org
Subject: Re: [PATCH 11/17] dmaengine: idxd: disable the device before its work queues are unregistered
Date: Mon, 19 Oct 2026 18:09:26 +0000	[thread overview]
Message-ID: <sashiko-outbox-178064@kernel.org> (raw)
In-Reply-To: <20261019150630.4026341-12-daniel1.byrne@intel.com>

Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [High] dmaengine: idxd: wqs freed before misc IRQ teardown in idxd_remove()
- [Medium] dmaengine: idxd: PASID detached before disabling bus mastering in idxd_remove()
--

commit 702a28ae3b6aeca10dbb038b18e88c5081667455
Author: Daniel Byrne <daniel1.byrne@intel.com>

dmaengine: idxd: disable the device before its work queues are unregistered

This commit moves idxd_shutdown() in idxd_remove() to run before
idxd_unregister_devices() so the device is disabled while the work queues
still exist, and sets idxd->state to IDXD_DEV_DISABLED after
pci_disable_device() before dropping the final reference to idxd_confdev.

> diff --git a/drivers/dma/idxd/init.c b/drivers/dma/idxd/init.c
> index c4319ac27bfb1..a037a6e763622 100644
> --- a/drivers/dma/idxd/init.c
> +++ b/drivers/dma/idxd/init.c
> @@ -1296,6 +1296,13 @@ static void idxd_remove(struct pci_dev *pdev)
>  	 * that driver while the queues still exist.
>  	 */
>  	device_release_driver(idxd_confdev(idxd));
> +	/*
> +	 * Disable the device while the queues still exist too. The
> +	 * sub-driver's remove leaves the device enabled when a command has
> +	 * timed out, a late completion can clear that state at any time,
> +	 * and the disable below then clears the queues' software state.
> +	 */
> +	idxd_shutdown(pdev);
>  	idxd_unregister_devices(idxd);

[Severity: High]
If a command has timed out and does not complete before idxd_shutdown()
runs, idxd_device_disable() in idxd_shutdown() will also fail, leaving the
device enabled in hardware while idxd_unregister_devices() frees all
idxd->wqs[i] before idxd_cleanup_interrupts() frees MSI-X vector 0. Can a
misc interrupt fire in this window and dereference freed idxd->wqs[i]?

Specifically, when IDXD_FLAG_CMD_TIMEDOUT is set, idxd_device_drv_remove()
skips idxd_device_evl_free(), leaving Event Log interrupts enabled in
hardware (gencfg.evl_en = 1, genctrl.evl_int_en = 1). In idxd_shutdown():

drivers/dma/idxd/init.c:idxd_shutdown() {
	rc = idxd_device_disable(idxd);
	if (rc)
		dev_err(&pdev->dev, "Disabling device failed\n");

	irq_entry = &idxd->ie;
	synchronize_irq(irq_entry->vector);
	idxd_mask_error_interrupts(idxd);
	flush_workqueue(idxd->wq);
}

synchronize_irq() is called before idxd_mask_error_interrupts(), and
idxd_mask_error_interrupts() only clears softerr_int_en and halt_int_en,
leaving EVL and IDXD_INTC_INT_HANDLE_REVOKED interrupts enabled while
MSI-X vector 0 (idxd_misc_thread) stays active until
idxd_cleanup_interrupts().

Once idxd_unregister_devices() unregisters and frees idxd->wqs[i], an
IDXD_INTC_EVL interrupt running idxd_misc_thread() -> process_evl_entries()
-> process_evl_entry() will index into the freed wq:

drivers/dma/idxd/irq.c:process_evl_entry() {
	...
	struct idxd_wq *wq = idxd->wqs[entry_head->wq_idx];

	if (!is_idxd_wq_user(wq) || !wq->wq) {
	...
}

Similarly, an IDXD_INTC_INT_HANDLE_REVOKED interrupt (or a halt/error
interrupt racing between synchronize_irq() and idxd_mask_error_interrupts())
can access freed idxd->wqs[i] or queue work onto idxd->wq after
flush_workqueue(idxd->wq) has already completed, which could then run
after pci_iounmap(pdev, idxd->reg_base).

Should idxd_cleanup_interrupts() (or disabling bus mastering / freeing IRQ
vector 0 before flushing idxd->wq) happen before idxd_unregister_devices()
frees the work queues?

>  	/*
>  	 * When ->release() is called for the idxd->conf_dev, it frees all
> @@ -1305,15 +1312,20 @@ static void idxd_remove(struct pci_dev *pdev)
>  	 */
>  	get_device(idxd_confdev(idxd));
>  	device_unregister(idxd_confdev(idxd));
> -	idxd_shutdown(pdev);
>  	idxd_device_remove_debugfs(idxd);
>  	perfmon_pmu_remove(idxd);
>  	idxd_cleanup_interrupts(idxd);
>  	if (device_pasid_enabled(idxd))
>  		idxd_disable_system_pasid(idxd);
>  	pci_iounmap(pdev, idxd->reg_base);
> -	put_device(idxd_confdev(idxd));
>  	pci_disable_device(pdev);
> +	/*
> +	 * Bus mastering is off, so nothing the device holds can complete.
> +	 * The store comes before the reference taken above is dropped:
> +	 * that reference is the last one, and its release frees the device.
> +	 */
> +	idxd->state = IDXD_DEV_DISABLED;
> +	put_device(idxd_confdev(idxd));
>  }

[Severity: Medium]
In the same command timeout case where the device remains enabled in
hardware until pci_disable_device(pdev) turns off bus mastering, is it
safe to call idxd_disable_system_pasid(idxd) before pci_disable_device(pdev)?

drivers/dma/idxd/init.c:idxd_disable_system_pasid() {
	...
	iommu_detach_device_pasid(domain, dev, idxd->pasid);
	iommu_free_global_pasid(idxd->pasid);

	idxd_set_user_intr(idxd, 0);
	...
}

Because bus mastering is still active when idxd_disable_system_pasid()
runs, could in-flight descriptors on the still-enabled device issue DMA
with idxd->pasid after it has been detached and freed, or could
idxd_set_user_intr() write GENCFG while the device is still enabled?

듯

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261019150630.4026341-1-daniel1.byrne@intel.com?part=11

  reply	other threads:[~2026-10-19 18:09 UTC|newest]

Thread overview: 29+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-19 15:06 [PATCH 00/17] [PATCH 00/17] dmaengine: idxd: fixes found by an in-kernel polling client Daniel Byrne
2026-10-19 15:06 ` [PATCH 01/17] dmaengine: idxd: don't queue EVL fault work for kernel WQs Daniel Byrne
2026-10-19 15:06 ` [PATCH 02/17] dmaengine: idxd: detach the user fault workqueue under the event log lock Daniel Byrne
2026-10-19 15:06 ` [PATCH 03/17] dmaengine: idxd: refuse a memcpy longer than the WQ max transfer size Daniel Byrne
2026-10-19 21:19   ` Frank Li
2026-10-19 15:06 ` [PATCH 04/17] dmaengine: idxd: list a new channel only once it is complete Daniel Byrne
2026-10-19 15:06 ` [PATCH 05/17] dmaengine: idxd: unbind the device driver before its work queues go away Daniel Byrne
2026-10-19 15:06 ` [PATCH 06/17] dmaengine: idxd: keep the interrupt handle across terminate_all Daniel Byrne
2026-10-19 15:06 ` [PATCH 07/17] dmaengine: idxd: bound device command waits and fail fast after a timeout Daniel Byrne
2026-10-19 17:05   ` sashiko-bot
2026-10-19 15:06 ` [PATCH 08/17] dmaengine: idxd: compare the device disable status code whole Daniel Byrne
2026-10-19 15:06 ` [PATCH 09/17] dmaengine: idxd: quarantine terminate_all's descriptor slots until the device has drained Daniel Byrne
2026-10-19 17:26   ` sashiko-bot
2026-10-19 15:06 ` [PATCH 10/17] dmaengine: idxd: return -ETIMEDOUT from drains and resets and leak what the device may still write Daniel Byrne
2026-10-19 17:50   ` sashiko-bot
2026-10-19 15:06 ` [PATCH 11/17] dmaengine: idxd: disable the device before its work queues are unregistered Daniel Byrne
2026-10-19 18:09   ` sashiko-bot [this message]
2026-10-19 15:06 ` [PATCH 12/17] dmaengine: idxd: hold device commands off while the reset re-creates its interrupts Daniel Byrne
2026-10-19 18:19   ` sashiko-bot
2026-10-19 15:06 ` [PATCH 13/17] dmaengine: idxd: fix the double free of a descriptor whose submission failed Daniel Byrne
2026-10-19 15:06 ` [PATCH 14/17] dmaengine: idxd: complete an iaa_crypto descriptor through its own driver on abort and flush Daniel Byrne
2026-10-19 18:56   ` sashiko-bot
2026-10-19 15:06 ` [PATCH 15/17] dmaengine: idxd: flush the work queues on every halt type Daniel Byrne
2026-10-19 19:17   ` sashiko-bot
2026-10-19 15:06 ` [PATCH 16/17] dmaengine: idxd: keep client callbacks on a halt flush and cancel resubmissions after a terminate Daniel Byrne
2026-10-19 19:36   ` sashiko-bot
2026-10-19 15:06 ` [PATCH 17/17] dmaengine: idxd: run the interrupt-handle revoke under the queue lock Daniel Byrne
2026-10-19 19:53   ` sashiko-bot
2026-10-19 19:09 ` [PATCH 00/17] [PATCH 00/17] dmaengine: idxd: fixes found by an in-kernel polling client Frank Li

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-178064@kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=Frank.Li@kernel.org \
    --cc=daniel1.byrne@intel.com \
    --cc=dmaengine@vger.kernel.org \
    --cc=sashiko-reviews@lists.linux.dev \
    --cc=vkoul@kernel.org \
    /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.