Messages in this thread | | | Date | Sun, 31 Jul 2022 19:55:15 +0800 | Subject | Re: [PATCH v10 02/12] iommu: Add max_pasids field in struct dev_iommu | From | Yi Liu <> |
| |
On 2022/7/5 13:07, Lu Baolu wrote: > Use this field to save the number of PASIDs that a device is able to > consume. It is a generic attribute of a device and lifting it into the > per-device dev_iommu struct could help to avoid the boilerplate code > in various IOMMU drivers. > > Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com> > Reviewed-by: Kevin Tian <kevin.tian@intel.com> > Tested-by: Zhangfei Gao <zhangfei.gao@linaro.org> > Tested-by: Tony Zhu <tony.zhu@intel.com> > --- > include/linux/iommu.h | 2 ++ > drivers/iommu/iommu.c | 20 ++++++++++++++++++++ > 2 files changed, 22 insertions(+)
Reviewed-by: Yi Liu <yi.l.liu@intel.com>
> diff --git a/include/linux/iommu.h b/include/linux/iommu.h > index 03fbb1b71536..418a1914a041 100644 > --- a/include/linux/iommu.h > +++ b/include/linux/iommu.h > @@ -364,6 +364,7 @@ struct iommu_fault_param { > * @fwspec: IOMMU fwspec data > * @iommu_dev: IOMMU device this device is linked to > * @priv: IOMMU Driver private data > + * @max_pasids: number of PASIDs this device can consume > * > * TODO: migrate other per device data pointers under iommu_dev_data, e.g. > * struct iommu_group *iommu_group; > @@ -375,6 +376,7 @@ struct dev_iommu { > struct iommu_fwspec *fwspec; > struct iommu_device *iommu_dev; > void *priv; > + u32 max_pasids; > }; > > int iommu_device_register(struct iommu_device *iommu, > diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c > index cdc86c39954e..0cb0750f61e8 100644 > --- a/drivers/iommu/iommu.c > +++ b/drivers/iommu/iommu.c > @@ -20,6 +20,7 @@ > #include <linux/idr.h> > #include <linux/err.h> > #include <linux/pci.h> > +#include <linux/pci-ats.h> > #include <linux/bitops.h> > #include <linux/property.h> > #include <linux/fsl/mc.h> > @@ -218,6 +219,24 @@ static void dev_iommu_free(struct device *dev) > kfree(param); > } > > +static u32 dev_iommu_get_max_pasids(struct device *dev) > +{ > + u32 max_pasids = 0, bits = 0; > + int ret; > + > + if (dev_is_pci(dev)) { > + ret = pci_max_pasids(to_pci_dev(dev)); > + if (ret > 0) > + max_pasids = ret; > + } else { > + ret = device_property_read_u32(dev, "pasid-num-bits", &bits); > + if (!ret) > + max_pasids = 1UL << bits; > + } > + > + return min_t(u32, max_pasids, dev->iommu->iommu_dev->max_pasids); > +} > + > static int __iommu_probe_device(struct device *dev, struct list_head *group_list) > { > const struct iommu_ops *ops = dev->bus->iommu_ops; > @@ -243,6 +262,7 @@ static int __iommu_probe_device(struct device *dev, struct list_head *group_list > } > > dev->iommu->iommu_dev = iommu_dev; > + dev->iommu->max_pasids = dev_iommu_get_max_pasids(dev); > > group = iommu_group_get_for_dev(dev); > if (IS_ERR(group)) {
-- Regards, Yi Liu
| |