From: "Aneesh Kumar K.V (Arm)" <aneesh.kumar@kernel.org>
To: iommu@lists.linux.dev
Cc: "Aneesh Kumar K.V (Arm)" <aneesh.kumar@kernel.org>,
Alex Williamson <alex@shazbot.org>,
Alexey Kardashevskiy <aik@amd.com>,
Bjorn Helgaas <bhelgaas@google.com>,
Catalin Marinas <catalin.marinas@arm.com>,
Jacob Pan <jacob.pan@linux.microsoft.com>,
Jason Gunthorpe <jgg@ziepe.ca>, Joerg Roedel <joro@8bytes.org>,
Jonathan Cameron <jic23@kernel.org>,
Jonathan Hunter <jonathanh@nvidia.com>,
Kevin Tian <kevin.tian@intel.com>,
Krishna Reddy <vdumpa@nvidia.com>, Lukas Wunner <lukas@wunner.de>,
Nicolin Chen <nicolinc@nvidia.com>,
Robin Murphy <robin.murphy@arm.com>,
Samuel Ortiz <sameo@rivosinc.com>,
Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>,
Steven Price <steven.price@arm.com>,
Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>,
Suzuki K Poulose <suzuki.poulose@arm.com>,
Thierry Reding <thierry.reding@kernel.org>,
Vasant Hegde <vasant.hegde@amd.com>,
Will Deacon <will@kernel.org>,
Xu Yilun <yilun.xu@linux.intel.com>,
kvm@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
linux-coco@lists.linux.dev, linux-kernel@vger.kernel.org,
linux-pci@vger.kernel.org, linux-tegra@vger.kernel.org,
Jonathan Cameron <jonathan.cameron@huawei.com>
Subject: [PATCH v7 16/16] PCI/TSM: wait for vdevice contexts before removing a DSM
Date: Thu, 8 Oct 2026 11:29:55 +0530 [thread overview]
Message-ID: <20261008055955.4014342-17-aneesh.kumar@kernel.org> (raw)
In-Reply-To: <20261008055955.4014342-1-aneesh.kumar@kernel.org>
A PF0 DSM can be removed while a sibling function still has a vdevice.
The context pins both the pci dev, but those references do not keep the
PF0 DOE mailbox alive. Ignoring -EBUSY from link disconnect lets PCI
continue to pci_doe_destroy(), leaving the vdevice with a stale mailbox
pointer.
This follows the VFIO PCI removal model: vfio_unregister_group_dev()
prevents new userspace opens and waits for existing users to release the
device before teardown proceeds. Likewise, DSM removal rejects new
contexts and waits for existing vdevice contexts to drain before
destroying the DOE mailbox.
Mark the DSM as removing so no new contexts or subfunctions can attach.
Wait for the last context to be released before disconnecting the link,
VFIO PCI also uses an eventfd to notify userspace that the device should
be released. This patch does not add an equivalent notification for
vdevice contexts; DSM removal waits for userspace to release them. Such
a notification can be added later if required.
Cc: Bjorn Helgaas <bhelgaas@google.com>
Cc: Jonathan Cameron <jonathan.cameron@huawei.com>
Cc: Alexey Kardashevskiy <aik@amd.com>
Cc: Xu Yilun <yilun.xu@linux.intel.com>
Cc: Lukas Wunner <lukas@wunner.de>
Cc: Samuel Ortiz <sameo@rivosinc.com>
Cc: Suzuki K Poulose <suzuki.poulose@arm.com>
Cc: Jason Gunthorpe <jgg@ziepe.ca>
Cc: Kevin Tian <kevin.tian@intel.com>
Signed-off-by: Aneesh Kumar K.V (Arm) <aneesh.kumar@kernel.org>
---
drivers/pci/tsm.c | 63 +++++++++++++++++++++++++++++++++++++++--
include/linux/pci-tsm.h | 5 ++++
2 files changed, 65 insertions(+), 3 deletions(-)
diff --git a/drivers/pci/tsm.c b/drivers/pci/tsm.c
index c8603867e09d..8aa74ba31932 100644
--- a/drivers/pci/tsm.c
+++ b/drivers/pci/tsm.c
@@ -10,10 +10,13 @@
#include <linux/bitfield.h>
#include <linux/iommufd.h>
+#include <linux/jiffies.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/pci-doe.h>
#include <linux/pci-tsm.h>
+#include <linux/pid.h>
+#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/sysfs.h>
#include <linux/tsm.h>
@@ -354,6 +357,12 @@ struct pci_tsm_context *pci_tsm_context_get(struct pci_dev *pdev,
return ERR_PTR(-ENOMEM);
guard(mutex)(&pf0->lock);
+ if (pf0->removing) {
+ kfree(context);
+ return ERR_PTR(-ENODEV);
+ }
+ if (!pf0->context_users)
+ reinit_completion(&pf0->contexts_drained);
pf0->context_users++;
context->pf0 = pf0;
context->pdev = pci_dev_get(pdev);
@@ -368,8 +377,11 @@ void pci_tsm_context_put(struct pci_tsm_context *context)
down_read(&pci_tsm_rwsem);
mutex_lock(&pf0->lock);
- if (!WARN_ON(!pf0->context_users))
- pf0->context_users--;
+ if (WARN_ON(!pf0->context_users))
+ goto out_unlock;
+ if (!--pf0->context_users)
+ complete_all(&pf0->contexts_drained);
+out_unlock:
mutex_unlock(&pf0->lock);
up_read(&pci_tsm_rwsem);
@@ -452,6 +464,9 @@ static ssize_t disconnect_store(struct device *dev,
tsm_dev = pdev->tsm->tsm_dev;
if (!sysfs_streq(buf, dev_name(&tsm_dev->dev)))
return -EINVAL;
+ if (is_link_tsm(tsm_dev) && is_pci_tsm_pf0(pdev) &&
+ to_pci_tsm_pf0(pdev->tsm)->removing)
+ return -ENODEV;
rc = pci_tsm_disconnect(pdev);
if (rc)
@@ -663,6 +678,9 @@ int pci_tsm_pf0_constructor(struct pci_dev *pdev, struct pci_tsm_pf0 *tsm,
struct tsm_dev *tsm_dev)
{
mutex_init(&tsm->lock);
+ init_completion(&tsm->contexts_drained);
+ tsm->context_users = 0;
+ tsm->removing = false;
tsm->doe_mb = pci_find_doe_mailbox(pdev, PCI_VENDOR_ID_PCI_SIG,
PCI_DOE_FEATURE_CMA);
if (!tsm->doe_mb) {
@@ -751,8 +769,44 @@ static void __pci_tsm_destroy(struct pci_dev *pdev, struct tsm_dev *tsm_dev)
void pci_tsm_destroy(struct pci_dev *pdev)
{
- guard(rwsem_write)(&pci_tsm_rwsem);
+ struct pci_tsm_pf0 *pf0 = NULL;
+ struct completion *drained;
+ bool interrupted = false;
+ long rc;
+
+ down_write(&pci_tsm_rwsem);
+ if (pdev->tsm && is_link_tsm(pdev->tsm->tsm_dev) &&
+ is_pci_tsm_pf0(pdev)) {
+ pf0 = to_pci_tsm_pf0(pdev->tsm);
+ drained = &pf0->contexts_drained;
+ mutex_lock(&pf0->lock);
+ pf0->removing = true;
+ mutex_unlock(&pf0->lock);
+
+ /* An unused DSM may never have completed contexts_drained. */
+ rc = pf0->context_users ?
+ try_wait_for_completion(drained) : 1;
+ /* Context release needs the read side of pci_tsm_rwsem. */
+ up_write(&pci_tsm_rwsem);
+ while (rc <= 0) {
+ if (interrupted) {
+ rc = wait_for_completion_timeout(drained, HZ * 10);
+ } else {
+ rc = wait_for_completion_interruptible_timeout(drained,
+ HZ * 10);
+ if (rc < 0) {
+ interrupted = true;
+ pci_warn(pdev, "Task \"%s\" (%d) blocked until vdevices are released\n",
+ current->comm, task_pid_nr(current));
+ }
+ }
+ if (!rc)
+ pci_warn(pdev, "TSM connection is in use, waiting for vdevices\n");
+ }
+ down_write(&pci_tsm_rwsem);
+ }
__pci_tsm_destroy(pdev, NULL);
+ up_write(&pci_tsm_rwsem);
}
void pci_tsm_init(struct pci_dev *pdev)
@@ -779,6 +833,9 @@ void pci_tsm_init(struct pci_dev *pdev)
*/
if (!dsm->tsm)
return;
+ if (is_link_tsm(dsm->tsm->tsm_dev) &&
+ to_pci_tsm_pf0(dsm->tsm)->removing)
+ return;
probe_fn(pdev, dsm);
}
diff --git a/include/linux/pci-tsm.h b/include/linux/pci-tsm.h
index b27f7cf99f22..3adc317d0f9b 100644
--- a/include/linux/pci-tsm.h
+++ b/include/linux/pci-tsm.h
@@ -1,6 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __PCI_TSM_H
#define __PCI_TSM_H
+#include <linux/completion.h>
#include <linux/mutex.h>
#include <linux/pci.h>
@@ -107,12 +108,16 @@ struct pci_tsm {
* @lock: mutual exclustion for pci_tsm_ops invocation
* @context_users: live per-function contexts on this PF0; a nonzero count
* blocks link disconnect
+ * @contexts_drained: completed when the last context is released
+ * @removing: reject new contexts while the DSM is being removed
* @doe_mb: PCIe Data Object Exchange mailbox
*/
struct pci_tsm_pf0 {
struct pci_tsm base_tsm;
struct mutex lock;
unsigned int context_users;
+ struct completion contexts_drained;
+ bool removing;
struct pci_doe_mb *doe_mb;
};
--
2.43.0
next prev parent reply other threads:[~2026-10-08 6:02 UTC|newest]
Thread overview: 33+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-08 5:59 [PATCH v7 00/16] iommufd: vIOMMUs and TSM guest requests for confidential guests Aneesh Kumar K.V (Arm)
2026-10-08 5:59 ` [PATCH v7 01/16] KVM: Introduce file_to_kvm_<arch>() infrastructure Aneesh Kumar K.V (Arm)
2026-10-08 6:11 ` sashiko-bot
2026-10-08 5:59 ` [PATCH v7 02/16] KVM: Add file back-pointer to struct kvm Aneesh Kumar K.V (Arm)
2026-10-08 6:16 ` sashiko-bot
2026-10-08 5:59 ` [PATCH v7 03/16] KVM: x86: Use file_to_kvm_x86() in SEV Aneesh Kumar K.V (Arm)
2026-10-08 6:07 ` sashiko-bot
2026-10-08 5:59 ` [PATCH v7 04/16] KVM/vfio: Use file-based reference counting for KVM Aneesh Kumar K.V (Arm)
2026-10-08 6:27 ` sashiko-bot
2026-10-08 5:59 ` [PATCH v7 05/16] KVM: Restrict kvm_get_kvm/kvm_put_kvm export to internal KVM modules Aneesh Kumar K.V (Arm)
2026-10-08 6:08 ` sashiko-bot
2026-10-08 5:59 ` [PATCH v7 06/16] KVM: Remove unused file_is_kvm Aneesh Kumar K.V (Arm)
2026-10-08 6:06 ` sashiko-bot
2026-10-08 5:59 ` [PATCH v7 07/16] iommufd/device: Associate KVM file pointer with iommufd_device Aneesh Kumar K.V (Arm)
2026-10-08 6:20 ` sashiko-bot
2026-10-08 5:59 ` [PATCH v7 08/16] iommufd/viommu: Keep a reference to the KVM file Aneesh Kumar K.V (Arm)
2026-10-08 6:10 ` sashiko-bot
2026-10-08 5:59 ` [PATCH v7 09/16] tsm: Remove the device from lookup before PCI teardown Aneesh Kumar K.V (Arm)
2026-10-08 6:15 ` sashiko-bot
2026-10-08 5:59 ` [PATCH v7 10/16] iommufd: Add the vdevice TSM request ioctl Aneesh Kumar K.V (Arm)
2026-10-08 6:10 ` sashiko-bot
2026-10-08 5:59 ` [PATCH v7 11/16] PCI/TSM: Remove the legacy guest request interface Aneesh Kumar K.V (Arm)
2026-10-08 6:11 ` sashiko-bot
2026-10-08 5:59 ` [PATCH v7 12/16] PCI/TSM: Add vIOMMU-bound contexts for vdevices Aneesh Kumar K.V (Arm)
2026-10-08 6:18 ` sashiko-bot
2026-10-08 5:59 ` [PATCH v7 13/16] iommufd/viommu: Select vIOMMU operations before allocation Aneesh Kumar K.V (Arm)
2026-10-08 6:27 ` sashiko-bot
2026-10-08 5:59 ` [PATCH v7 14/16] iommufd/viommu: Allow PCI TSM backends to provide vIOMMU operations Aneesh Kumar K.V (Arm)
2026-10-08 6:19 ` sashiko-bot
2026-10-08 5:59 ` [PATCH v7 15/16] iommufd: Allow vIOMMUs without a parent HWPT Aneesh Kumar K.V (Arm)
2026-10-08 6:24 ` sashiko-bot
2026-10-08 5:59 ` Aneesh Kumar K.V (Arm) [this message]
2026-10-08 6:25 ` [PATCH v7 16/16] PCI/TSM: wait for vdevice contexts before removing a DSM sashiko-bot
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=20261008055955.4014342-17-aneesh.kumar@kernel.org \
--to=aneesh.kumar@kernel.org \
--cc=aik@amd.com \
--cc=alex@shazbot.org \
--cc=bhelgaas@google.com \
--cc=catalin.marinas@arm.com \
--cc=iommu@lists.linux.dev \
--cc=jacob.pan@linux.microsoft.com \
--cc=jgg@ziepe.ca \
--cc=jic23@kernel.org \
--cc=jonathan.cameron@huawei.com \
--cc=jonathanh@nvidia.com \
--cc=joro@8bytes.org \
--cc=kevin.tian@intel.com \
--cc=kvm@vger.kernel.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-coco@lists.linux.dev \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pci@vger.kernel.org \
--cc=linux-tegra@vger.kernel.org \
--cc=lukas@wunner.de \
--cc=nicolinc@nvidia.com \
--cc=robin.murphy@arm.com \
--cc=sameo@rivosinc.com \
--cc=shameerali.kolothum.thodi@huawei.com \
--cc=steven.price@arm.com \
--cc=suravee.suthikulpanit@amd.com \
--cc=suzuki.poulose@arm.com \
--cc=thierry.reding@kernel.org \
--cc=vasant.hegde@amd.com \
--cc=vdumpa@nvidia.com \
--cc=will@kernel.org \
--cc=yilun.xu@linux.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