Re: [PATCH v10 0/6] iommufd: Enable noiommu mode for cdev

From: Jacob Pan

Date: Tue Jul 07 2026 - 14:49:05 EST


Hi Alex,

On Mon, 6 Jul 2026 15:51:24 -0600
Alex Williamson <alex@xxxxxxxxxxx> wrote:

> On Mon, 6 Jul 2026 16:54:03 -0300
> Jason Gunthorpe <jgg@xxxxxxxxxx> wrote:
>
> > On Mon, Jul 06, 2026 at 11:48:28AM -0700, Jacob Pan wrote:
> > > VFIO's unsafe_noiommu_mode has long provided a way for userspace
> > > drivers to operate on platforms lacking a hardware IOMMU. Today,
> > > IOMMUFD also supports No-IOMMU mode for group-based devices under
> > > vfio_compat mode. However, IOMMUFD's native character device
> > > (cdev) does not yet support No-IOMMU mode, which is the purpose
> > > of this patch.
> > >
> > > In summary, we have:
> > >
> > > |-------------------------+------+---------------|
> > > | Device access mode | VFIO | IOMMUFD |
> > > |-------------------------+------+---------------|
> > > | group /dev/vfio/$GROUP | Yes | Yes |
> > > |-------------------------+------+---------------|
> > > | cdev /dev/vfio/devices/ | No | This patch |
> > > |-------------------------+------+---------------|
> > >
> > > Beyond enabling cdev for IOMMUFD, this patch also addresses the
> > > following deficiencies in the current No-IOMMU mode suggested by
> > > Jason[1]:
> > > - Devices operating under No-IOMMU mode are limited to
> > > device-level UAPI access, without container or IOAS-level
> > > capabilities. Consequently, user-space drivers lack structured
> > > mechanisms for page pinning and often resort to mlock(), which is
> > > less robust than pin_user_pages() used for devices backed by a
> > > physical IOMMU. For example, mlock() does not prevent page
> > > migration.
> > > - There is no architectural mechanism for obtaining physical
> > > addresses for DMA. As a workaround, user-space drivers frequently
> > > rely on /proc/pagemap tricks or hardcoded values.
> > >
> > > By allowing noiommu device access to IOMMUFD IOAS and HWPT
> > > objects, this patch brings No-IOMMU mode closer to full
> > > citizenship within the IOMMU subsystem. In addition to addressing
> > > the two deficiencies mentioned above, the expectation is that it
> > > will also enable No-IOMMU devices to seamlessly participate in
> > > live update sessions via KHO [2].
> > >
> > > Furthermore, these devices will use the IOMMUFD-based ownership
> > > checking model for VFIO_DEVICE_PCI_HOT_RESET, eliminating the
> > > need for an iommufd_access object as required in a previous
> > > attempt [3].
> > >
> > > ChangeLog:
> > > v10:
> > > - Rebased to v7.2-rc2, no intended code change
> >
> > My impression is we are good on this now, right? I would like to
> > pick it up?
>
> There are a couple Sashiko findings. The PAGE_SIZE issue seems like a
> false positive. The AMD based page tables necessarily expose 4K, but
> pinning is obviously at PAGE_SIZE, so returning multiples of PAGE_SIZE
> is arguably correct.
>
> The PASID issue seems more like a uAPI hygiene question, and it might
> be the correct answer to return error for values other than
> IOMMU_NO_PASID. Your call.
>
> Fine otherwise from a vfio perspective. Thanks,
>
> Alex
I agree this is worth rejecting explicitly.

No-IOMMU only supports allocating paging domain and cannot allocate a
PASID-capable domain. The practical path I found is
VFIO_DEVICE_ATTACH_IOMMUFD_PT with VFIO_DEVICE_ATTACH_PASID set, where
userspace supplies the PASID at attach time.

Jason, I tested the change below. If you are okay with it, could you fold it
in? Otherwise I can spin v11.


Date: Tue, 7 Jul 2026 11:33:26 -0700 Subject: [PATCH]
iommufd: Validate HWPT compatibility before noiommu attach

Fixes: 2c6cf6ab1564 ("iommufd: Allow binding to a noiommu device")

Signed-off-by: Jacob Pan <jacob.pan@xxxxxxxxxxxxxxxxxxx>
---
drivers/iommu/iommufd/device.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/iommu/iommufd/device.c b/drivers/iommu/iommufd/device.c
index d7060b3b4676..c230ab8dc8f5 100644
--- a/drivers/iommu/iommufd/device.c
+++ b/drivers/iommu/iommufd/device.c
@@ -574,9 +574,6 @@ static int iommufd_hwpt_attach_device(struct iommufd_hw_pagetable *hwpt,
struct iommufd_attach_handle *handle;
int rc;

- if (iommufd_device_is_noiommu(idev))
- return 0;
-
if (!iommufd_hwpt_compatible_device(hwpt, idev))
return -EINVAL;

@@ -584,6 +581,9 @@ static int iommufd_hwpt_attach_device(struct iommufd_hw_pagetable *hwpt,
if (rc)
return rc;

+ if (iommufd_device_is_noiommu(idev))
+ return 0;
+
handle = kzalloc_obj(*handle);
if (!handle)
return -ENOMEM;
@@ -645,9 +645,6 @@ static int iommufd_hwpt_replace_device(struct iommufd_device *idev,
struct iommufd_attach_handle *handle, *old_handle;
int rc;

- if (iommufd_device_is_noiommu(idev))
- return 0;
-
if (!iommufd_hwpt_compatible_device(hwpt, idev))
return -EINVAL;

@@ -655,6 +652,9 @@ static int iommufd_hwpt_replace_device(struct iommufd_device *idev,
if (rc)
return rc;

+ if (iommufd_device_is_noiommu(idev))
+ return 0;
+
old_handle = iommufd_device_get_attach_handle(idev, pasid);

handle = kzalloc_obj(*handle);