@@ -169,6 +169,7 @@ static void vfio_device_group_get_kvm_safe(struct vfio_device *device)
static int vfio_device_group_open(struct vfio_device_file *df)
{
struct vfio_device *device = df->device;
+ u32 ioas_id;
int ret;
mutex_lock(&device->group->group_lock);
@@ -177,6 +178,13 @@ static int vfio_device_group_open(struct vfio_device_file *df)
goto out_unlock;
}
+ if (device->group->iommufd) {
+ ret = iommufd_vfio_compat_ioas_id(device->group->iommufd,
+ &ioas_id);
+ if (ret)
+ goto out_unlock;
+ }
+
mutex_lock(&device->dev_set->lock);
/*
@@ -188,9 +196,12 @@ static int vfio_device_group_open(struct vfio_device_file *df)
if (device->open_count == 0)
vfio_device_group_get_kvm_safe(device);
- df->iommufd = device->group->iommufd;
-
- ret = vfio_device_open(df);
+ if (device->group->iommufd) {
+ df->iommufd = device->group->iommufd;
+ ret = vfio_device_open(df, NULL, &ioas_id);
+ } else {
+ ret = vfio_device_open(df, NULL, NULL);
+ }
if (ret)
df->iommufd = NULL;
@@ -10,9 +10,9 @@
MODULE_IMPORT_NS(IOMMUFD);
MODULE_IMPORT_NS(IOMMUFD_VFIO);
-int vfio_iommufd_bind(struct vfio_device *vdev, struct iommufd_ctx *ictx)
+int vfio_iommufd_bind(struct vfio_device *vdev, struct iommufd_ctx *ictx,
+ u32 *dev_id, u32 *pt_id)
{
- u32 ioas_id;
u32 device_id;
int ret;
@@ -29,17 +29,14 @@ int vfio_iommufd_bind(struct vfio_device *vdev, struct iommufd_ctx *ictx)
if (ret)
return ret;
- ret = iommufd_vfio_compat_ioas_id(ictx, &ioas_id);
- if (ret)
- goto err_unbind;
- ret = vdev->ops->attach_ioas(vdev, &ioas_id);
- if (ret)
- goto err_unbind;
+ if (pt_id) {
+ ret = vdev->ops->attach_ioas(vdev, pt_id);
+ if (ret)
+ goto err_unbind;
+ }
- /*
- * The legacy path has no way to return the device id or the selected
- * pt_id
- */
+ if (dev_id)
+ *dev_id = device_id;
return 0;
err_unbind:
@@ -26,7 +26,8 @@ struct vfio_device_file {
void vfio_device_put_registration(struct vfio_device *device);
bool vfio_device_try_get_registration(struct vfio_device *device);
-int vfio_device_open(struct vfio_device_file *df);
+int vfio_device_open(struct vfio_device_file *df,
+ u32 *dev_id, u32 *pt_id);
void vfio_device_close(struct vfio_device_file *df);
struct vfio_device_file *
vfio_allocate_device_file(struct vfio_device *device);
@@ -224,11 +225,13 @@ static inline void vfio_container_cleanup(void)
#endif
#if IS_ENABLED(CONFIG_IOMMUFD)
-int vfio_iommufd_bind(struct vfio_device *device, struct iommufd_ctx *ictx);
+int vfio_iommufd_bind(struct vfio_device *device, struct iommufd_ctx *ictx,
+ u32 *dev_id, u32 *pt_id);
void vfio_iommufd_unbind(struct vfio_device *device);
#else
static inline int vfio_iommufd_bind(struct vfio_device *device,
- struct iommufd_ctx *ictx)
+ struct iommufd_ctx *ictx,
+ u32 *dev_id, u32 *pt_id)
{
return -EOPNOTSUPP;
}
@@ -411,7 +411,8 @@ vfio_allocate_device_file(struct vfio_device *device)
return df;
}
-static int vfio_device_first_open(struct vfio_device_file *df)
+static int vfio_device_first_open(struct vfio_device_file *df,
+ u32 *dev_id, u32 *pt_id)
{
struct vfio_device *device = df->device;
struct iommufd_ctx *iommufd = df->iommufd;
@@ -423,7 +424,7 @@ static int vfio_device_first_open(struct vfio_device_file *df)
return -ENODEV;
if (iommufd)
- ret = vfio_iommufd_bind(device, iommufd);
+ ret = vfio_iommufd_bind(device, iommufd, dev_id, pt_id);
else
ret = vfio_device_group_use_iommu(device);
if (ret)
@@ -462,7 +463,8 @@ static void vfio_device_last_close(struct vfio_device_file *df)
module_put(device->dev->driver->owner);
}
-int vfio_device_open(struct vfio_device_file *df)
+int vfio_device_open(struct vfio_device_file *df,
+ u32 *dev_id, u32 *pt_id)
{
struct vfio_device *device = df->device;
int ret = 0;
@@ -471,7 +473,7 @@ int vfio_device_open(struct vfio_device_file *df)
device->open_count++;
if (device->open_count == 1) {
- ret = vfio_device_first_open(df);
+ ret = vfio_device_first_open(df, dev_id, pt_id);
if (ret)
device->open_count--;
}