On Sun, Nov 28, 2021 at 10:50:38AM +0800, Lu Baolu wrote: > Multiple platform devices may be placed in the same IOMMU group because > they cannot be isolated from each other. These devices must either be > entirely under kernel control or userspace control, never a mixture. This > checks and sets DMA ownership during driver binding, and release the > ownership during driver unbinding. > > Driver may set a new flag (suppress_auto_claim_dma_owner) to disable auto > claiming DMA_OWNER_DMA_API ownership in the binding process. For instance, > the userspace framework drivers (vfio etc.) which need to manually claim > DMA_OWNER_PRIVATE_DOMAIN_USER when assigning a device to userspace. Why would any vfio driver be a platform driver? That should never be the case as they obviously are not platform drivers, they are virtual ones. > > Signed-off-by: Lu Baolu <baolu.lu@xxxxxxxxxxxxxxx> > --- > include/linux/platform_device.h | 1 + > drivers/base/platform.c | 30 +++++++++++++++++++++++++++++- > 2 files changed, 30 insertions(+), 1 deletion(-) > > diff --git a/include/linux/platform_device.h b/include/linux/platform_device.h > index 7c96f169d274..779bcf2a851c 100644 > --- a/include/linux/platform_device.h > +++ b/include/linux/platform_device.h > @@ -210,6 +210,7 @@ struct platform_driver { > struct device_driver driver; > const struct platform_device_id *id_table; > bool prevent_deferred_probe; > + bool suppress_auto_claim_dma_owner; What platform driver needs this change? > }; > > #define to_platform_driver(drv) (container_of((drv), struct platform_driver, \ > diff --git a/drivers/base/platform.c b/drivers/base/platform.c > index 598acf93a360..df4b385c8a52 100644 > --- a/drivers/base/platform.c > +++ b/drivers/base/platform.c > @@ -30,6 +30,7 @@ > #include <linux/property.h> > #include <linux/kmemleak.h> > #include <linux/types.h> > +#include <linux/iommu.h> > > #include "base.h" > #include "power/power.h" > @@ -1465,6 +1466,32 @@ int platform_dma_configure(struct device *dev) > return ret; > } > > +static int _platform_dma_configure(struct device *dev) > +{ > + struct platform_driver *drv = to_platform_driver(dev->driver); > + int ret; > + > + if (!drv->suppress_auto_claim_dma_owner) { > + ret = iommu_device_set_dma_owner(dev, DMA_OWNER_DMA_API, NULL); > + if (ret) > + return ret; > + } > + > + ret = platform_dma_configure(dev); > + if (ret && !drv->suppress_auto_claim_dma_owner) > + iommu_device_release_dma_owner(dev, DMA_OWNER_DMA_API); > + > + return ret; > +} > + > +static void _platform_dma_unconfigure(struct device *dev) > +{ > + struct platform_driver *drv = to_platform_driver(dev->driver); > + > + if (!drv->suppress_auto_claim_dma_owner) > + iommu_device_release_dma_owner(dev, DMA_OWNER_DMA_API); > +} > + > static const struct dev_pm_ops platform_dev_pm_ops = { > SET_RUNTIME_PM_OPS(pm_generic_runtime_suspend, pm_generic_runtime_resume, NULL) > USE_PLATFORM_PM_SLEEP_OPS > @@ -1478,7 +1505,8 @@ struct bus_type platform_bus_type = { > .probe = platform_probe, > .remove = platform_remove, > .shutdown = platform_shutdown, > - .dma_configure = platform_dma_configure, > + .dma_configure = _platform_dma_configure, What happened to the original platform_dma_configure() function? And single "_" prefixes are odd, please just spell out what the difference is in the function name, "_" gives us no hint at all. thnaks, greg k-h