Re: [RFC 06/20] iommu: Add iommu_device_init[exit]_user_dma interfaces

From: Jason Gunthorpe
Date: Wed Sep 22 2021 - 08:39:37 EST


On Wed, Sep 22, 2021 at 01:47:05AM +0000, Tian, Kevin wrote:

> > IIRC in VFIO the container is the IOAS and when the group goes to
> > create the device fd it should simply do the
> > iommu_device_init_user_dma() followed immediately by a call to bind
> > the container IOAS as your #3.
>
> a slight correction.
>
> to meet vfio semantics we could do init_user_dma() at group attach
> time and then call binding to container IOAS when the device fd
> is created. This is because vfio requires the group in a security context
> before the device is opened.

Is it? Until a device FD is opened the group fd is kind of idle, right?

> > Ie the basic flow would see the driver core doing some:
>
> Just double confirm. Is there concern on having the driver core to
> call iommu functions?

It is always an interesting question, but I'd say iommu is
foundantional to Linux and if it needs driver core help it shouldn't
be any different from PM, pinctl, or other subsystems that have
inserted themselves into the driver core.

Something kind of like the below.

If I recall, once it is done like this then the entire iommu notifier
infrastructure can be ripped out which is a lot of code.


diff --git a/drivers/base/dd.c b/drivers/base/dd.c
index 68ea1f949daa90..e39612c99c6123 100644
--- a/drivers/base/dd.c
+++ b/drivers/base/dd.c
@@ -566,6 +566,10 @@ static int really_probe(struct device *dev, struct device_driver *drv)
goto done;
}

+ ret = iommu_set_kernel_ownership(dev);
+ if (ret)
+ return ret;
+
re_probe:
dev->driver = drv;

@@ -673,6 +677,7 @@ static int really_probe(struct device *dev, struct device_driver *drv)
dev->pm_domain->dismiss(dev);
pm_runtime_reinit(dev);
dev_pm_set_driver_flags(dev, 0);
+ iommu_release_kernel_ownership(dev);
done:
return ret;
}
@@ -1214,6 +1219,7 @@ static void __device_release_driver(struct device *dev, struct device *parent)
dev->pm_domain->dismiss(dev);
pm_runtime_reinit(dev);
dev_pm_set_driver_flags(dev, 0);
+ iommu_release_kernel_ownership(dev);

klist_remove(&dev->p->knode_driver);
device_pm_check_callbacks(dev);