Linux Confidential Computing Development
 help / color / mirror / Atom feed
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
Subject: [PATCH v8 06/15] iommufd/device: Hold a KVM file reference for the device lifetime
Date: Wed,  4 Nov 2026 21:46:23 +0530	[thread overview]
Message-ID: <20261104161632.3547423-7-aneesh.kumar@kernel.org> (raw)
In-Reply-To: <20261104161632.3547423-1-aneesh.kumar@kernel.org>

The KVM file stored in an iommufd_device currently relies on the
reference held by VFIO while the device is open. Normally, unbind waits
for outstanding device references before VFIO drops its KVM reference.
However, REMOVE_WAIT only waits for 60 seconds. If that timeout expires,
the device object remains in the iommufd xarray.

For example, an IOMMU_GET_HW_INFO ioctl can hold a device reference while
blocked on a userspace buffer fault:

  iommufd_fops_ioctl()
    iommufd_get_hw_info()
      iommufd_get_device()
        iommufd_get_object()
          iommufd_lock_obj()       /* takes users and wait_cnt refs */
      copy_to_user() / clear_user() /* may block before putting refs */

A concurrent final release of the VFIO device file takes this path:

  vfio_device_fops_release()
    vfio_df_unbind_iommufd()
      vfio_df_close()
        vfio_df_device_last_close()
          vfio_df_iommufd_unbind()
            vfio_iommufd_physical_unbind()
              iommufd_device_unbind()
                iommufd_object_destroy_user()
                  iommufd_object_remove(..., REMOVE_WAIT)
                    iommufd_object_dec_wait() /* timeout: -EBUSY */
                  WARN_ON(ret)
      vfio_device_put_kvm()
        fput(device->kvm)

iommufd_object_destroy_user() warns on -EBUSY but does not propagate it:
iommufd_device_unbind() returns void. Thus VFIO close effectively ignores
the unbind failure and proceeds to drop its KVM file reference even
though the iommufd_device is still alive and its ID remains usable.

Once the remaining KVM file references are released, a later ioctl on
the still-open iommufd can access the stale pointer:

  iommufd_fops_ioctl()
    iommufd_viommu_alloc_ioctl()
      iommufd_get_device()         /* finds the surviving device ID */
      get_file(idev->kvm_file)     /* accesses the freed KVM file */

Take a KVM file reference when binding the device and release it when
the iommufd_device is actually destroyed. Release it before the igroup
check in the destructor so that bind failure cleanup is covered too.
Document the ownership in the bind API and device structure.

Fixes: d8bb80c8f0e5 ("iommufd/device: Associate KVM file pointer with iommufd_device")
Signed-off-by: Aneesh Kumar K.V (Arm) <aneesh.kumar@kernel.org>
---
 drivers/iommu/iommufd/device.c          | 11 +++++++++--
 drivers/iommu/iommufd/iommufd_private.h |  2 +-
 2 files changed, 10 insertions(+), 3 deletions(-)

diff --git a/drivers/iommu/iommufd/device.c b/drivers/iommu/iommufd/device.c
index 935f42616a65..cd49acf5bd3f 100644
--- a/drivers/iommu/iommufd/device.c
+++ b/drivers/iommu/iommufd/device.c
@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /* Copyright (c) 2021-2022, NVIDIA CORPORATION & AFFILIATES
  */
+#include <linux/file.h>
 #include <linux/iommu.h>
 #include <linux/iommufd.h>
 #include <linux/pci-ats.h>
@@ -212,6 +213,9 @@ void iommufd_device_destroy(struct iommufd_object *obj)
 	struct iommufd_device *idev =
 		container_of(obj, struct iommufd_device, obj);
 
+	if (idev->kvm_file)
+		fput(idev->kvm_file);
+
 	/* igroup is NULL when destroy called during bind error cleanup */
 	if (!idev->igroup)
 		return;
@@ -306,6 +310,9 @@ static int iommufd_bind_noiommu(struct iommufd_device *idev)
  *
  * Binding a PCI device places the entire RID under iommufd control.
  *
+ * If @kvm_file is provided, a reference is held until the device object is
+ * destroyed.
+ *
  * The caller must undo this with iommufd_device_unbind()
  */
 struct iommufd_device *iommufd_device_bind(struct iommufd_ctx *ictx,
@@ -322,8 +329,8 @@ struct iommufd_device *iommufd_device_bind(struct iommufd_ctx *ictx,
 
 	idev->ictx = ictx;
 	idev->dev = dev;
-	/* VFIO holds the file reference while the device is open. */
-	idev->kvm_file = kvm_file;
+	/* Hold the VM file for the lifetime of this object. */
+	idev->kvm_file = kvm_file ? get_file(kvm_file) : NULL;
 
 	if (!iommufd_device_is_noiommu(idev))
 		rc = iommufd_bind_iommu(idev);
diff --git a/drivers/iommu/iommufd/iommufd_private.h b/drivers/iommu/iommufd/iommufd_private.h
index 2560b4faa6f9..63a6dcee21dc 100644
--- a/drivers/iommu/iommufd/iommufd_private.h
+++ b/drivers/iommu/iommufd/iommufd_private.h
@@ -509,7 +509,7 @@ struct iommufd_device {
 	struct list_head group_item;
 	/* always the physical device */
 	struct device *dev;
-	/* ..and the VM file if available */
+	/* Owned reference to the VM file, if available */
 	struct file *kvm_file;
 	bool enforce_cache_coherency;
 	struct iommufd_vdevice *vdev;
-- 
2.43.0


  parent reply	other threads:[~2026-11-04 16:17 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-11-04 16:16 [PATCH v8 00/15] iommufd: TSM-backed virtual IOMMUs for confidential guests Aneesh Kumar K.V (Arm)
2026-11-04 16:16 ` [PATCH v8 01/15] PCI/TSM: Move core code into its own directory Aneesh Kumar K.V (Arm)
2026-11-04 16:16 ` [PATCH v8 02/15] virt: coco: tsm: Remove the device from lookup before PCI teardown Aneesh Kumar K.V (Arm)
2026-11-04 16:16 ` [PATCH v8 03/15] virt: coco: tsm: Complete PCI registration before publishing the device Aneesh Kumar K.V (Arm)
2026-11-04 16:16 ` [PATCH v8 04/15] virt: coco: tsm: Require PCI operations when registering a TSM Aneesh Kumar K.V (Arm)
2026-11-04 16:16 ` [PATCH v8 05/15] iommufd/device: Associate KVM file pointer with iommufd_device Aneesh Kumar K.V (Arm)
2026-11-04 16:16 ` Aneesh Kumar K.V (Arm) [this message]
2026-11-04 16:16 ` [PATCH v8 07/15] iommufd/viommu: Keep a reference to the KVM file Aneesh Kumar K.V (Arm)
2026-11-04 16:35   ` Jacob Pan
2026-11-04 16:16 ` [PATCH v8 08/15] iommufd: Add a vDEVICE operation ioctl framework Aneesh Kumar K.V (Arm)
2026-11-04 16:16 ` [PATCH v8 09/15] PCI/TSM: Remove the legacy guest request interface Aneesh Kumar K.V (Arm)
2026-11-04 16:16 ` [PATCH v8 10/15] PCI/TSM: Add vIOMMU-bound device contexts Aneesh Kumar K.V (Arm)
2026-11-04 16:16 ` [PATCH v8 11/15] iommufd/viommu: Select vIOMMU operations before allocation Aneesh Kumar K.V (Arm)
2026-11-04 16:16 ` [PATCH v8 12/15] iommufd/viommu: Allow PCI TSM backends to provide vIOMMU operations Aneesh Kumar K.V (Arm)
2026-11-04 16:16 ` [PATCH v8 13/15] iommufd/viommu: Allow vIOMMUs without a parent HWPT Aneesh Kumar K.V (Arm)
2026-11-04 19:03   ` Nicolin Chen
2026-11-04 19:31     ` Jason Gunthorpe
2026-11-04 16:16 ` [PATCH v8 14/15] PCI/TSM: Wait for device contexts before removing a DSM Aneesh Kumar K.V (Arm)
2026-11-04 16:16 ` [PATCH v8 15/15] PCI/TSM: Wait for users during unregister Aneesh Kumar K.V (Arm)

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=20261104161632.3547423-7-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=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