Now that devices under noiommu mode can bind with IOMMUFD and perform
IOAS operations, lift restrictions on cdev from VFIO side.
No IOMMU cdevs are explicitly named with noiommu prefix. e.g.
/dev/vfio/
|-- 7
|-- devices
| `-- noiommu-vfio0
`-- vfio
Signed-off-by: Jacob Pan <jacob.pan@linux.microsoft.com>
---
v2:
- Fix build dependency on IOMMU_SUPPORT
Signed-off-by: Jacob Pan <jacob.pan@linux.microsoft.com>
---
drivers/vfio/Kconfig | 7 +++++--
drivers/vfio/iommufd.c | 7 -------
drivers/vfio/vfio.h | 8 +-------
drivers/vfio/vfio_main.c | 22 +++++++++++++++++++---
include/linux/vfio.h | 9 +++++++++
5 files changed, 34 insertions(+), 19 deletions(-)
diff --git a/drivers/vfio/Kconfig b/drivers/vfio/Kconfig
index ceae52fd7586..78feca3d0c8b 100644
--- a/drivers/vfio/Kconfig
+++ b/drivers/vfio/Kconfig
@@ -22,8 +22,7 @@ config VFIO_DEVICE_CDEV
The VFIO device cdev is another way for userspace to get device
access. Userspace gets device fd by opening device cdev under
/dev/vfio/devices/vfioX, and then bind the device fd with an iommufd
- to set up secure DMA context for device access. This interface does
- not support noiommu.
+ to set up secure DMA context for device access.
If you don't know what to do here, say N.
@@ -63,6 +62,10 @@ endif
config VFIO_NOIOMMU
bool "VFIO No-IOMMU support"
depends on VFIO_GROUP
+ select GENERIC_PT
+ select IOMMU_PT
+ select IOMMU_PT_AMDV1
+ depends on IOMMU_SUPPORT
help
VFIO is built on the ability to isolate devices using the IOMMU.
Only with an IOMMU can userspace access to DMA capable devices be
diff --git a/drivers/vfio/iommufd.c b/drivers/vfio/iommufd.c
index a38d262c6028..26c9c3068c77 100644
--- a/drivers/vfio/iommufd.c
+++ b/drivers/vfio/iommufd.c
@@ -25,10 +25,6 @@ int vfio_df_iommufd_bind(struct vfio_device_file *df)
lockdep_assert_held(&vdev->dev_set->lock);
- /* Returns 0 to permit device opening under noiommu mode */
- if (vfio_device_is_noiommu(vdev))
- return 0;
-
return vdev->ops->bind_iommufd(vdev, ictx, &df->devid);
}
@@ -58,9 +54,6 @@ void vfio_df_iommufd_unbind(struct vfio_device_file *df)
lockdep_assert_held(&vdev->dev_set->lock);
- if (vfio_device_is_noiommu(vdev))
- return;
-
if (vdev->ops->unbind_iommufd)
vdev->ops->unbind_iommufd(vdev);
}
diff --git a/drivers/vfio/vfio.h b/drivers/vfio/vfio.h
index c5541967ef9b..f6262f2cc7a6 100644
--- a/drivers/vfio/vfio.h
+++ b/drivers/vfio/vfio.h
@@ -381,19 +381,13 @@ void vfio_init_device_cdev(struct vfio_device *device);
static inline int vfio_device_add(struct vfio_device *device)
{
- /* cdev does not support noiommu device */
- if (vfio_device_is_noiommu(device))
- return device_add(&device->device);
vfio_init_device_cdev(device);
return cdev_device_add(&device->cdev, &device->device);
}
static inline void vfio_device_del(struct vfio_device *device)
{
- if (vfio_device_is_noiommu(device))
- device_del(&device->device);
- else
- cdev_device_del(&device->cdev, &device->device);
+ cdev_device_del(&device->cdev, &device->device);
}
int vfio_device_fops_cdev_open(struct inode *inode, struct file *filep);
diff --git a/drivers/vfio/vfio_main.c b/drivers/vfio/vfio_main.c
index 742477546b15..099d9b1ade4c 100644
--- a/drivers/vfio/vfio_main.c
+++ b/drivers/vfio/vfio_main.c
@@ -331,13 +331,15 @@ static int __vfio_register_dev(struct vfio_device *device,
if (!device->dev_set)
vfio_assign_device_set(device, device);
- ret = dev_set_name(&device->device, "vfio%d", device->index);
+ ret = vfio_device_set_group(device, type);
if (ret)
return ret;
- ret = vfio_device_set_group(device, type);
+ /* Just to be safe, expose to user explicitly noiommu cdev node */
+ ret = dev_set_name(&device->device, "%svfio%d",
+ device->noiommu ? "noiommu-" : "", device->index);
if (ret)
- return ret;
+ goto err_out;
/*
* VFIO always sets IOMMU_CACHE because we offer no way for userspace to
@@ -357,6 +359,10 @@ static int __vfio_register_dev(struct vfio_device *device,
/* Refcounting can't start until the driver calls register */
refcount_set(&device->refcount, 1);
+ /* noiommu device w/o container may have NULL group */
+ if (vfio_device_is_noiommu(device) && !vfio_device_has_group(device))
+ return 0;
+
vfio_device_group_register(device);
vfio_device_debugfs_init(device);
@@ -391,6 +397,16 @@ void vfio_unregister_group_dev(struct vfio_device *device)
bool interrupted = false;
long rc;
+ /*
+ * For noiommu devices without a container, thus no dummy group,
+ * simply delete and unregister to balance refcount.
+ */
+ if (device->noiommu && !vfio_device_has_group(device)) {
+ vfio_device_del(device);
+ vfio_device_put_registration(device);
+ return;
+ }
+
/*
* Prevent new device opened by userspace via the
* VFIO_GROUP_GET_DEVICE_FD in the group path.
diff --git a/include/linux/vfio.h b/include/linux/vfio.h
index 844d14839f96..775bd4f6bae9 100644
--- a/include/linux/vfio.h
+++ b/include/linux/vfio.h
@@ -327,6 +327,10 @@ struct iommu_group *vfio_file_iommu_group(struct file *file);
#if IS_ENABLED(CONFIG_VFIO_GROUP)
bool vfio_file_is_group(struct file *file);
bool vfio_file_has_dev(struct file *file, struct vfio_device *device);
+static inline bool vfio_device_has_group(struct vfio_device *device)
+{
+ return device->group;
+}
#else
static inline bool vfio_file_is_group(struct file *file)
{
@@ -337,6 +341,11 @@ static inline bool vfio_file_has_dev(struct file *file, struct vfio_device *devi
{
return false;
}
+
+static inline bool vfio_device_has_group(struct vfio_device *device)
+{
+ return false;
+}
#endif
bool vfio_file_is_valid(struct file *file);
bool vfio_file_enforced_coherent(struct file *file);
--
2.34.1
Hi Jacob,
kernel test robot noticed the following build errors:
[auto build test ERROR on linus/master]
[also build test ERROR on v7.0-rc3 next-20260311]
[cannot apply to awilliam-vfio/next awilliam-vfio/for-linus]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Jacob-Pan/iommufd-Support-a-HWPT-without-an-iommu-driver-for-noiommu/20260313-182818
base: linus/master
patch link: https://lore.kernel.org/r/20260312155637.376854-9-jacob.pan%40linux.microsoft.com
patch subject: [PATCH V2 08/11] vfio: Enable cdev noiommu mode under iommufd
config: m68k-allmodconfig (https://download.01.org/0day-ci/archive/20260314/202603141655.DaMKZr7a-lkp@intel.com/config)
compiler: m68k-linux-gcc (GCC) 15.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260314/202603141655.DaMKZr7a-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202603141655.DaMKZr7a-lkp@intel.com/
All errors (new ones prefixed by >>):
In file included from drivers/iommu/generic_pt/fmt/iommu_template.h:36,
from drivers/iommu/generic_pt/fmt/iommu_mock.c:10:
drivers/iommu/generic_pt/fmt/amdv1.h: In function 'amdv1pt_install_table':
>> drivers/iommu/generic_pt/fmt/amdv1.h:255:16: error: implicit declaration of function 'pt_table_install64'; did you mean 'pt_table_install32'? [-Wimplicit-function-declaration]
255 | return pt_table_install64(pts, entry);
| ^~~~~~~~~~~~~~~~~~
| pt_table_install32
Kconfig warnings: (for reference only)
WARNING: unmet direct dependencies detected for IOMMU_PT_AMDV1
Depends on [n]: GENERIC_PT [=y] && IOMMU_PT [=m] && !GENERIC_ATOMIC64 [=y]
Selected by [m]:
- VFIO_NOIOMMU [=y] && VFIO [=m] && VFIO_GROUP [=y] && IOMMU_SUPPORT [=y]
vim +255 drivers/iommu/generic_pt/fmt/amdv1.h
879ced2bab1ba9 Jason Gunthorpe 2025-11-04 236
879ced2bab1ba9 Jason Gunthorpe 2025-11-04 237 static inline bool amdv1pt_install_table(struct pt_state *pts,
879ced2bab1ba9 Jason Gunthorpe 2025-11-04 238 pt_oaddr_t table_pa,
879ced2bab1ba9 Jason Gunthorpe 2025-11-04 239 const struct pt_write_attrs *attrs)
879ced2bab1ba9 Jason Gunthorpe 2025-11-04 240 {
879ced2bab1ba9 Jason Gunthorpe 2025-11-04 241 u64 entry;
879ced2bab1ba9 Jason Gunthorpe 2025-11-04 242
879ced2bab1ba9 Jason Gunthorpe 2025-11-04 243 /*
879ced2bab1ba9 Jason Gunthorpe 2025-11-04 244 * IR and IW are ANDed from the table levels along with the PTE. We
879ced2bab1ba9 Jason Gunthorpe 2025-11-04 245 * always control permissions from the PTE, so always set IR and IW for
879ced2bab1ba9 Jason Gunthorpe 2025-11-04 246 * tables.
879ced2bab1ba9 Jason Gunthorpe 2025-11-04 247 */
879ced2bab1ba9 Jason Gunthorpe 2025-11-04 248 entry = AMDV1PT_FMT_PR |
879ced2bab1ba9 Jason Gunthorpe 2025-11-04 249 FIELD_PREP(AMDV1PT_FMT_NEXT_LEVEL, pts->level) |
879ced2bab1ba9 Jason Gunthorpe 2025-11-04 250 FIELD_PREP(AMDV1PT_FMT_OA,
879ced2bab1ba9 Jason Gunthorpe 2025-11-04 251 log2_div(table_pa, PT_GRANULE_LG2SZ)) |
879ced2bab1ba9 Jason Gunthorpe 2025-11-04 252 AMDV1PT_FMT_IR | AMDV1PT_FMT_IW;
879ced2bab1ba9 Jason Gunthorpe 2025-11-04 253 if (pts_feature(pts, PT_FEAT_AMDV1_ENCRYPT_TABLES))
879ced2bab1ba9 Jason Gunthorpe 2025-11-04 254 entry = __sme_set(entry);
879ced2bab1ba9 Jason Gunthorpe 2025-11-04 @255 return pt_table_install64(pts, entry);
879ced2bab1ba9 Jason Gunthorpe 2025-11-04 256 }
879ced2bab1ba9 Jason Gunthorpe 2025-11-04 257 #define pt_install_table amdv1pt_install_table
879ced2bab1ba9 Jason Gunthorpe 2025-11-04 258
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
© 2016 - 2026 Red Hat, Inc.