diff options
author | Robin Murphy <robin.murphy@arm.com> | 2022-08-15 17:26:50 +0200 |
---|---|---|
committer | Joerg Roedel <jroedel@suse.de> | 2022-09-07 14:16:39 +0200 |
commit | df198b37e72c18c771d93ffbaf2176c0270505f3 (patch) | |
tree | 543a690a15dcacc5c4ce79b7778b72b208c8fdfb /drivers/iommu/arm | |
parent | iommu: Retire iommu_capable() (diff) | |
download | linux-df198b37e72c18c771d93ffbaf2176c0270505f3.tar.xz linux-df198b37e72c18c771d93ffbaf2176c0270505f3.zip |
iommu/arm-smmu: Report IOMMU_CAP_CACHE_COHERENCY better
Assuming that any SMMU can enforce coherency for any device is clearly
nonsense. Although technically even a single SMMU instance can be wired
up to only be capable of emitting coherent traffic for some of the
devices it translates, it's a fairly realistic approximation that if the
SMMU's pagetable walker is wired up to a coherent interconnect then all
its translation units probably are too, and conversely that lack of
coherent table walks implies a non-coherent system in general. Either
way it's still less inaccurate than what we've been claiming so far.
Signed-off-by: Robin Murphy <robin.murphy@arm.com>
Link: https://lore.kernel.org/r/106c9741415f0b6358c72d53ae9c78c553a2b45c.1660574547.git.robin.murphy@arm.com
Signed-off-by: Joerg Roedel <jroedel@suse.de>
Diffstat (limited to 'drivers/iommu/arm')
-rw-r--r-- | drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 5 | ||||
-rw-r--r-- | drivers/iommu/arm/arm-smmu/arm-smmu.c | 9 |
2 files changed, 8 insertions, 6 deletions
diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c index ab919ec43c4d..fceab59113ba 100644 --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c @@ -1994,9 +1994,12 @@ static const struct iommu_flush_ops arm_smmu_flush_ops = { /* IOMMU API */ static bool arm_smmu_capable(struct device *dev, enum iommu_cap cap) { + struct arm_smmu_master *master = dev_iommu_priv_get(dev); + switch (cap) { case IOMMU_CAP_CACHE_COHERENCY: - return true; + /* Assume that a coherent TCU implies coherent TBUs */ + return master->smmu->features & ARM_SMMU_FEAT_COHERENCY; case IOMMU_CAP_NOEXEC: return true; default: diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c b/drivers/iommu/arm/arm-smmu/arm-smmu.c index ce036a053fb8..8039c8bc8470 100644 --- a/drivers/iommu/arm/arm-smmu/arm-smmu.c +++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c @@ -1332,13 +1332,12 @@ static phys_addr_t arm_smmu_iova_to_phys(struct iommu_domain *domain, static bool arm_smmu_capable(struct device *dev, enum iommu_cap cap) { + struct arm_smmu_master_cfg *cfg = dev_iommu_priv_get(dev); + switch (cap) { case IOMMU_CAP_CACHE_COHERENCY: - /* - * Return true here as the SMMU can always send out coherent - * requests. - */ - return true; + /* Assume that a coherent TCU implies coherent TBUs */ + return cfg->smmu->features & ARM_SMMU_FEAT_COHERENT_WALK; case IOMMU_CAP_NOEXEC: return true; default: |