Message ID | 20210325130332.778208-5-thierry.reding@gmail.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | arm64: tegra: Prevent early SMMU faults | expand |
On 2021-03-25 13:03, Thierry Reding wrote: > From: Thierry Reding <treding@nvidia.com> > > Implement a ->probe_finalize() callback that can be used by vendor > implementations to perform extra programming necessary after devices > have been attached to the SMMU. > > Signed-off-by: Thierry Reding <treding@nvidia.com> > --- > drivers/iommu/arm/arm-smmu/arm-smmu.c | 17 +++++++++++++++++ > drivers/iommu/arm/arm-smmu/arm-smmu.h | 1 + > 2 files changed, 18 insertions(+) > > diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c b/drivers/iommu/arm/arm-smmu/arm-smmu.c > index d8c6bfde6a61..4589e76543a8 100644 > --- a/drivers/iommu/arm/arm-smmu/arm-smmu.c > +++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c > @@ -1447,6 +1447,22 @@ static void arm_smmu_release_device(struct device *dev) > iommu_fwspec_free(dev); > } > > +static void arm_smmu_probe_finalize(struct device *dev) > +{ > + struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev); > + struct arm_smmu_master_cfg *cfg; > + struct arm_smmu_device *smmu; > + > + if (!fwspec || fwspec->ops != &arm_smmu_ops) > + return; I think we can trust the IOMMU core not to call things in the wrong order, and if the fwspec has changed since it was validated in .probe_device then the world is probably on fire anyway. Robin. > + > + cfg = dev_iommu_priv_get(dev); > + smmu = cfg->smmu; > + > + if (smmu->impl->probe_finalize) > + smmu->impl->probe_finalize(smmu, dev); > +} > + > static struct iommu_group *arm_smmu_device_group(struct device *dev) > { > struct arm_smmu_master_cfg *cfg = dev_iommu_priv_get(dev); > @@ -1630,6 +1646,7 @@ static struct iommu_ops arm_smmu_ops = { > .iova_to_phys = arm_smmu_iova_to_phys, > .probe_device = arm_smmu_probe_device, > .release_device = arm_smmu_release_device, > + .probe_finalize = arm_smmu_probe_finalize, > .device_group = arm_smmu_device_group, > .domain_get_attr = arm_smmu_domain_get_attr, > .domain_set_attr = arm_smmu_domain_set_attr, > diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.h b/drivers/iommu/arm/arm-smmu/arm-smmu.h > index d2a2d1bc58ba..6779db30cebb 100644 > --- a/drivers/iommu/arm/arm-smmu/arm-smmu.h > +++ b/drivers/iommu/arm/arm-smmu/arm-smmu.h > @@ -439,6 +439,7 @@ struct arm_smmu_impl { > struct device *dev, int start); > void (*write_s2cr)(struct arm_smmu_device *smmu, int idx); > void (*write_sctlr)(struct arm_smmu_device *smmu, int idx, u32 reg); > + void (*probe_finalize)(struct arm_smmu_device *smmu, struct device *dev); > }; > > #define INVALID_SMENDX -1 >
diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c b/drivers/iommu/arm/arm-smmu/arm-smmu.c index d8c6bfde6a61..4589e76543a8 100644 --- a/drivers/iommu/arm/arm-smmu/arm-smmu.c +++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c @@ -1447,6 +1447,22 @@ static void arm_smmu_release_device(struct device *dev) iommu_fwspec_free(dev); } +static void arm_smmu_probe_finalize(struct device *dev) +{ + struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev); + struct arm_smmu_master_cfg *cfg; + struct arm_smmu_device *smmu; + + if (!fwspec || fwspec->ops != &arm_smmu_ops) + return; + + cfg = dev_iommu_priv_get(dev); + smmu = cfg->smmu; + + if (smmu->impl->probe_finalize) + smmu->impl->probe_finalize(smmu, dev); +} + static struct iommu_group *arm_smmu_device_group(struct device *dev) { struct arm_smmu_master_cfg *cfg = dev_iommu_priv_get(dev); @@ -1630,6 +1646,7 @@ static struct iommu_ops arm_smmu_ops = { .iova_to_phys = arm_smmu_iova_to_phys, .probe_device = arm_smmu_probe_device, .release_device = arm_smmu_release_device, + .probe_finalize = arm_smmu_probe_finalize, .device_group = arm_smmu_device_group, .domain_get_attr = arm_smmu_domain_get_attr, .domain_set_attr = arm_smmu_domain_set_attr, diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.h b/drivers/iommu/arm/arm-smmu/arm-smmu.h index d2a2d1bc58ba..6779db30cebb 100644 --- a/drivers/iommu/arm/arm-smmu/arm-smmu.h +++ b/drivers/iommu/arm/arm-smmu/arm-smmu.h @@ -439,6 +439,7 @@ struct arm_smmu_impl { struct device *dev, int start); void (*write_s2cr)(struct arm_smmu_device *smmu, int idx); void (*write_sctlr)(struct arm_smmu_device *smmu, int idx, u32 reg); + void (*probe_finalize)(struct arm_smmu_device *smmu, struct device *dev); }; #define INVALID_SMENDX -1