@@ -2748,9 +2748,11 @@ static int arm_smmu_enable_nesting(struct iommu_domain *domain)
return ret;
}
-static int arm_smmu_of_xlate(struct device *dev, struct of_phandle_args *args)
+static int arm_smmu_of_xlate_fwspec(struct iommu_fwspec *fwspec,
+ struct device *dev,
+ struct of_phandle_args *args)
{
- return iommu_fwspec_add_ids(dev, args->args, 1);
+ return iommu_fwspec_append_ids(fwspec, args->args, 1);
}
static void arm_smmu_get_resv_regions(struct device *dev,
@@ -2858,7 +2860,7 @@ static struct iommu_ops arm_smmu_ops = {
.probe_device = arm_smmu_probe_device,
.release_device = arm_smmu_release_device,
.device_group = arm_smmu_device_group,
- .of_xlate = arm_smmu_of_xlate,
+ .of_xlate_fwspec = arm_smmu_of_xlate_fwspec,
.get_resv_regions = arm_smmu_get_resv_regions,
.remove_dev_pasid = arm_smmu_remove_dev_pasid,
.dev_enable_feat = arm_smmu_dev_enable_feature,
@@ -1510,7 +1510,9 @@ static int arm_smmu_set_pgtable_quirks(struct iommu_domain *domain,
return ret;
}
-static int arm_smmu_of_xlate(struct device *dev, struct of_phandle_args *args)
+static int arm_smmu_of_xlate_fwspec(struct iommu_fwspec *fwspec,
+ struct device *dev,
+ struct of_phandle_args *args)
{
u32 mask, fwid = 0;
@@ -1522,7 +1524,7 @@ static int arm_smmu_of_xlate(struct device *dev, struct of_phandle_args *args)
else if (!of_property_read_u32(args->np, "stream-match-mask", &mask))
fwid |= FIELD_PREP(ARM_SMMU_SMR_MASK, mask);
- return iommu_fwspec_add_ids(dev, &fwid, 1);
+ return iommu_fwspec_append_ids(fwspec, &fwid, 1);
}
static void arm_smmu_get_resv_regions(struct device *dev,
@@ -1562,7 +1564,7 @@ static struct iommu_ops arm_smmu_ops = {
.release_device = arm_smmu_release_device,
.probe_finalize = arm_smmu_probe_finalize,
.device_group = arm_smmu_device_group,
- .of_xlate = arm_smmu_of_xlate,
+ .of_xlate_fwspec = arm_smmu_of_xlate_fwspec,
.get_resv_regions = arm_smmu_get_resv_regions,
.def_domain_type = arm_smmu_def_domain_type,
.pgsize_bitmap = -1UL, /* Restricted during device attach */
@@ -3000,6 +3000,9 @@ int iommu_fwspec_of_xlate(struct iommu_fwspec *fwspec, struct device *dev,
if (ret)
return ret;
+ if (fwspec->ops->of_xlate_fwspec)
+ return fwspec->ops->of_xlate_fwspec(fwspec, dev, iommu_spec);
+
if (!fwspec->ops->of_xlate)
return -ENODEV;
@@ -1027,9 +1027,11 @@ static struct iommu_group *viommu_device_group(struct device *dev)
return generic_device_group(dev);
}
-static int viommu_of_xlate(struct device *dev, struct of_phandle_args *args)
+static int viommu_of_xlate_fwspec(struct iommu_fwspec *fwspec,
+ struct device *dev,
+ struct of_phandle_args *args)
{
- return iommu_fwspec_add_ids(dev, args->args, 1);
+ return iommu_fwspec_append_ids(fwspec, args->args, 1);
}
static bool viommu_capable(struct device *dev, enum iommu_cap cap)
@@ -1050,7 +1052,7 @@ static struct iommu_ops viommu_ops = {
.release_device = viommu_release_device,
.device_group = viommu_device_group,
.get_resv_regions = viommu_get_resv_regions,
- .of_xlate = viommu_of_xlate,
+ .of_xlate_fwspec = viommu_of_xlate_fwspec,
.owner = THIS_MODULE,
.default_domain_ops = &(const struct iommu_domain_ops) {
.attach_dev = viommu_attach_dev,
@@ -41,6 +41,7 @@ struct notifier_block;
struct iommu_sva;
struct iommu_fault_event;
struct iommu_dma_cookie;
+struct iommu_fwspec;
/* iommu fault flags */
#define IOMMU_FAULT_READ 0x0
@@ -287,6 +288,8 @@ struct iommu_ops {
/* Request/Free a list of reserved regions for a device */
void (*get_resv_regions)(struct device *dev, struct list_head *list);
+ int (*of_xlate_fwspec)(struct iommu_fwspec *fwspec, struct device *dev,
+ struct of_phandle_args *args);
int (*of_xlate)(struct device *dev, struct of_phandle_args *args);
bool (*is_attach_deferred)(struct device *dev);
The new callback takes in the fwspec instead of retrieving it from the dev->iommu. Provide iommu_fwspec_append_ids() to work directly on the fwspec. Convert SMMU, SMMUv3, and virtio to use iommu_fwspec_append_ids() and the new entry point. This avoids having to touch dev->iommu at all, and doesn't require the iommu_probe_device_lock. Signed-off-by: Jason Gunthorpe <jgg@nvidia.com> --- drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 8 +++++--- drivers/iommu/arm/arm-smmu/arm-smmu.c | 8 +++++--- drivers/iommu/iommu.c | 3 +++ drivers/iommu/virtio-iommu.c | 8 +++++--- include/linux/iommu.h | 3 +++ 5 files changed, 21 insertions(+), 9 deletions(-)