Linux Confidential Computing Development
 help / color / mirror / Atom feed
From: "Aneesh Kumar K.V (Arm)" <aneesh.kumar@kernel.org>
To: linux-coco@lists.linux.dev
Cc: "Aneesh Kumar K.V (Arm)" <aneesh.kumar@kernel.org>,
	Ackerley Tng <ackerleytng@google.com>,
	Alex Williamson <alex@shazbot.org>,
	David Woodhouse <dwmw2@infradead.org>,
	David Hildenbrand <david@kernel.org>,
	Jason Gunthorpe <jgg@nvidia.com>,
	"Joerg Roedel (AMD)" <joro@8bytes.org>,
	Kevin Tian <kevin.tian@intel.com>,
	Paolo Bonzini <pbonzini@redhat.com>,
	Robin Murphy <robin.murphy@arm.com>,
	Sean Christopherson <seanjc@google.com>,
	Alexey Kardashevskiy <aik@amd.com>,
	Xu Yilun <yilun.xu@linux.intel.com>,
	Catalin Marinas <catalin.marinas@arm.com>,
	Suzuki K Poulose <suzuki.poulose@arm.com>,
	Steven Price <steven.price@arm.com>,
	Fred Griffoul <griffoul@gmail.com>,
	iommu@lists.linux.dev, kvm@vger.kernel.org,
	patches@lists.linux.dev
Subject: [RFC PATCH v4 21/25] vfio: Serialize guest_memfd attachment with device file operations
Date: Wed,  4 Nov 2026 20:33:18 +0530	[thread overview]
Message-ID: <20261104150322.3516320-22-aneesh.kumar@kernel.org> (raw)
In-Reply-To: <20261104150322.3516320-1-aneesh.kumar@kernel.org>

Attaching a VFIO device to guest_memfd must not race with VFIO file
operations that access its BARs or create mappings. The attachment state
must apply to every open VFIO file referring to the same device.

Hold the device's gmem_lock for reading across read, write, mmap and
normal ioctl dispatch, and for writing across provider attachment and
release. File operations already in progress finish before attachment
proceeds. Later operations observe the updated gmem_attached state while
holding the same lock, allowing driver checks to reject BAR access.

Hold dev_set->lock across the driver attach/release callbacks and updates
to gmem_attached as well. This lets hot reset check every affected device
for an attachment under the device-set lock without racing attachment or
release. Driver callbacks run with both locks held and must not reacquire
them.

Return EBUSY for VFIO mmap while guest_memfd is attached, including mmap
through another open VFIO file. Such a mapping would insert BAR PFNs
without checking guest_memfd attributes

Keep read, write and ioctl dispatch available to the driver. The PCI
checks reject operations that access BARs or disrupt their mappings while
preserving configuration queries, unrelated ioctls, feature probes and
cleanup.

Cc: Alex Williamson <alex@shazbot.org>
Cc: Sean Christopherson <seanjc@google.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: David Hildenbrand <david@kernel.org>
Signed-off-by: Aneesh Kumar K.V (Arm) <aneesh.kumar@kernel.org>
---
 drivers/vfio/pci/vfio_pci_config.c |  2 ++
 drivers/vfio/pci/vfio_pci_core.c   |  3 +++
 drivers/vfio/vfio_main.c           | 28 +++++++++++++++++++++++++++-
 include/linux/vfio.h               |  4 +++-
 4 files changed, 35 insertions(+), 2 deletions(-)

diff --git a/drivers/vfio/pci/vfio_pci_config.c b/drivers/vfio/pci/vfio_pci_config.c
index 014f865c1eaf..2cd855cc50bc 100644
--- a/drivers/vfio/pci/vfio_pci_config.c
+++ b/drivers/vfio/pci/vfio_pci_config.c
@@ -599,6 +599,8 @@ static int vfio_basic_config_write(struct vfio_pci_core_device *vdev, int pos,
 		}
 
 		/*
+		 * vfio_device_fops_write() holds gmem_lock for read, keeping
+		 * gmem_attached unchanged across this write.
 		 * Check BME and Memory Enable changes while holding memory_lock
 		 * for write, before updating hardware or vconfig. Return an
 		 * error rather than silently masking a rejected write.
diff --git a/drivers/vfio/pci/vfio_pci_core.c b/drivers/vfio/pci/vfio_pci_core.c
index 2789bfab4415..b8e574194f07 100644
--- a/drivers/vfio/pci/vfio_pci_core.c
+++ b/drivers/vfio/pci/vfio_pci_core.c
@@ -378,6 +378,9 @@ static int vfio_pci_runtime_pm_entry(struct vfio_pci_core_device *vdev,
 	/*
 	 * The vdev power related flags are protected with 'memory_lock'
 	 * semaphore.
+	 *
+	 * vfio_device_fops_unl_ioctl() holds gmem_lock for read,
+	 * preventing provider setup during this operation.
 	 */
 	ret = vfio_pci_begin_bar_state_change(vdev);
 	if (ret)
diff --git a/drivers/vfio/vfio_main.c b/drivers/vfio/vfio_main.c
index 838242f82fd2..787d9a661f75 100644
--- a/drivers/vfio/vfio_main.c
+++ b/drivers/vfio/vfio_main.c
@@ -289,12 +289,21 @@ static void *vfio_gmem_provider_attach(struct inode *inode, struct file *file,
 	if (!provider)
 		return ERR_PTR(-ENOMEM);
 
+	guard(rwsem_write)(&df->device->gmem_lock);
+	if (df->device->gmem_attached) {
+		kfree(provider);
+		return ERR_PTR(-EBUSY);
+	}
+
+	/* Publish attachment under both locks for device-set reset admission. */
+	guard(mutex)(&df->device->dev_set->lock);
 	data = ops->attach(inode, file, gmem);
 	if (IS_ERR(data)) {
 		kfree(provider);
 		return data;
 	}
 
+	df->device->gmem_attached = true;
 	provider->ops = ops;
 	provider->data = data;
 	/* Pin the driver operations through release(), including its return. */
@@ -306,7 +315,13 @@ static void vfio_gmem_provider_release(void *data)
 {
 	struct vfio_gmem_provider *provider = data;
 
-	provider->ops->release(provider->data);
+	struct vfio_device_file *df = provider->file->private_data;
+
+	scoped_guard(rwsem_write, &df->device->gmem_lock) {
+		guard(mutex)(&df->device->dev_set->lock);
+		provider->ops->release(provider->data);
+		df->device->gmem_attached = false;
+	}
 	fput(provider->file);
 	kfree(provider);
 }
@@ -1447,6 +1462,8 @@ static long vfio_device_fops_unl_ioctl(struct file *filep,
 	if (cmd == VFIO_DEVICE_BIND_IOMMUFD)
 		return vfio_df_ioctl_bind_iommufd(df, uptr);
 
+	guard(rwsem_read)(&device->gmem_lock);
+
 	/* Paired with smp_store_release() following vfio_df_open() */
 	if (!smp_load_acquire(&df->access_granted))
 		return -EINVAL;
@@ -1495,6 +1512,8 @@ static ssize_t vfio_device_fops_read(struct file *filep, char __user *buf,
 	struct vfio_device_file *df = filep->private_data;
 	struct vfio_device *device = df->device;
 
+	guard(rwsem_read)(&device->gmem_lock);
+
 	/* Paired with smp_store_release() following vfio_df_open() */
 	if (!smp_load_acquire(&df->access_granted))
 		return -EINVAL;
@@ -1512,6 +1531,8 @@ static ssize_t vfio_device_fops_write(struct file *filep,
 	struct vfio_device_file *df = filep->private_data;
 	struct vfio_device *device = df->device;
 
+	guard(rwsem_read)(&device->gmem_lock);
+
 	/* Paired with smp_store_release() following vfio_df_open() */
 	if (!smp_load_acquire(&df->access_granted))
 		return -EINVAL;
@@ -1527,10 +1548,15 @@ static int vfio_device_fops_mmap(struct file *filep, struct vm_area_struct *vma)
 	struct vfio_device_file *df = filep->private_data;
 	struct vfio_device *device = df->device;
 
+	guard(rwsem_read)(&device->gmem_lock);
+
 	/* Paired with smp_store_release() following vfio_df_open() */
 	if (!smp_load_acquire(&df->access_granted))
 		return -EINVAL;
 
+	if (device->gmem_attached)
+		return -EBUSY;
+
 	if (unlikely(!device->ops->mmap))
 		return -EINVAL;
 
diff --git a/include/linux/vfio.h b/include/linux/vfio.h
index 10fd5015ce1d..ceab68b76300 100644
--- a/include/linux/vfio.h
+++ b/include/linux/vfio.h
@@ -120,7 +120,9 @@ struct guest_memfd_provider_operations;
  *         if none was provided.
  * @dma_unmap: Called when userspace unmaps IOVA from the container
  *             this device is attached to.
- * @gmem_provider_ops: Optional driver guest_memfd resource operations
+ * @gmem_provider_ops: Optional driver guest_memfd resource operations. VFIO
+ *                     calls attach/release with gmem_lock held for write and
+ *                     dev_set->lock held; callbacks must not reacquire them.
  * @device_feature: Optional, fill in the VFIO_DEVICE_FEATURE ioctl
  */
 struct vfio_device_ops {
-- 
2.43.0


  parent reply	other threads:[~2026-11-04 15:05 UTC|newest]

Thread overview: 27+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-11-04 15:02 [RFC PATCH v4 00/25] KVM/VFIO: Add guest_memfd support for device MMIO Aneesh Kumar K.V (Arm)
2026-11-04 15:02 ` [RFC PATCH v4 01/25] KVM: guest_memfd: Let providers prepare memory regions Aneesh Kumar K.V (Arm)
2026-11-04 15:02 ` [RFC PATCH v4 02/25] KVM: guest_memfd: Dispatch conversion through backing operations Aneesh Kumar K.V (Arm)
2026-11-04 15:03 ` [RFC PATCH v4 03/25] KVM: guest_memfd: Let providers coordinate mapping changes Aneesh Kumar K.V (Arm)
2026-11-04 15:03 ` [RFC PATCH v4 04/25] KVM: guest_memfd: Dispatch revocation through backing operations Aneesh Kumar K.V (Arm)
2026-11-04 15:03 ` [RFC PATCH v4 05/25] KVM: guest_memfd: Split population by backing type Aneesh Kumar K.V (Arm)
2026-11-04 15:03 ` [RFC PATCH v4 06/25] KVM: guest_memfd: Support device-backed PFN providers Aneesh Kumar K.V (Arm)
2026-11-04 18:37   ` Fred Griffoul
2026-11-04 15:03 ` [RFC PATCH v4 07/25] KVM: guest_memfd: Support private/shared conversion of device memory Aneesh Kumar K.V (Arm)
2026-11-04 15:03 ` [RFC PATCH v4 08/25] KVM: guest_memfd: Track private device ranges after attribute updates Aneesh Kumar K.V (Arm)
2026-11-04 15:03 ` [RFC PATCH v4 09/25] KVM: guest_memfd: Support range revocation of device mappings Aneesh Kumar K.V (Arm)
2026-11-04 15:03 ` [RFC PATCH v4 10/25] KVM: guest_memfd: Add shared device mmap through PFN providers Aneesh Kumar K.V (Arm)
2026-11-04 15:03 ` [RFC PATCH v4 11/25] KVM: guest_memfd: Clear private device state on final close Aneesh Kumar K.V (Arm)
2026-11-04 15:03 ` [RFC PATCH v4 12/25] KVM: guest_memfd: Invalidate mappings before memslot unbind Aneesh Kumar K.V (Arm)
2026-11-04 15:03 ` [RFC PATCH v4 13/25] vfio: Track device use by guest_memfd Aneesh Kumar K.V (Arm)
2026-11-04 15:03 ` [RFC PATCH v4 14/25] vfio/pci: Add helpers to check and serialize BAR state changes Aneesh Kumar K.V (Arm)
2026-11-04 15:03 ` [RFC PATCH v4 15/25] vfio/pci: Check command enable changes before updating device state Aneesh Kumar K.V (Arm)
2026-11-04 15:03 ` [RFC PATCH v4 16/25] vfio/pci: Check whether BAR state changes are allowed before reset Aneesh Kumar K.V (Arm)
2026-11-04 15:03 ` [RFC PATCH v4 17/25] vfio/pci: Check low-power requests before updating device state Aneesh Kumar K.V (Arm)
2026-11-04 15:03 ` [RFC PATCH v4 18/25] vfio/pci: Track userspace BAR mappings Aneesh Kumar K.V (Arm)
2026-11-04 15:03 ` [RFC PATCH v4 19/25] vfio/pci: Restrict host BAR access for guest_memfd providers Aneesh Kumar K.V (Arm)
2026-11-04 15:03 ` [RFC PATCH v4 20/25] vfio: Dispatch guest_memfd provider operations through the device file Aneesh Kumar K.V (Arm)
2026-11-04 15:03 ` Aneesh Kumar K.V (Arm) [this message]
2026-11-04 15:03 ` [RFC PATCH v4 22/25] vfio/pci: Require D0 before providing guest_memfd BAR backing Aneesh Kumar K.V (Arm)
2026-11-04 15:03 ` [RFC PATCH v4 23/25] iommufd: Support MMIO provider attachment to vDEVICEs Aneesh Kumar K.V (Arm)
2026-11-04 15:03 ` [RFC PATCH v4 24/25] vfio/pci: Add a guest_memfd resource provider for MMIO BARs Aneesh Kumar K.V (Arm)
2026-11-04 15:03 ` [RFC PATCH v4 25/25] KVM: Document device-backed guest_memfd and VFIO usage 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=20261104150322.3516320-22-aneesh.kumar@kernel.org \
    --to=aneesh.kumar@kernel.org \
    --cc=ackerleytng@google.com \
    --cc=aik@amd.com \
    --cc=alex@shazbot.org \
    --cc=catalin.marinas@arm.com \
    --cc=david@kernel.org \
    --cc=dwmw2@infradead.org \
    --cc=griffoul@gmail.com \
    --cc=iommu@lists.linux.dev \
    --cc=jgg@nvidia.com \
    --cc=joro@8bytes.org \
    --cc=kevin.tian@intel.com \
    --cc=kvm@vger.kernel.org \
    --cc=linux-coco@lists.linux.dev \
    --cc=patches@lists.linux.dev \
    --cc=pbonzini@redhat.com \
    --cc=robin.murphy@arm.com \
    --cc=seanjc@google.com \
    --cc=steven.price@arm.com \
    --cc=suzuki.poulose@arm.com \
    --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