iommu/arm-smmu: allow per-impl capability override and prot masking - #1943
Open
Bibek Kumar Patro (bibekpatro) wants to merge 1 commit into
Open
Bibek Kumar Patro (bibekpatro) wants to merge 1 commit into
Bibek Kumar Patro (bibekpatro) wants to merge 1 commit into
Conversation
Some Qualcomm platforms using qcom,smmu-500 (arm,mmu-500) do not connect the SMMU pagetable-walk interface to a coherent interconnect. On those platforms ARM_SMMU_FEAT_COHERENT_WALK is not set (no dma-coherent in the SMMU DT node), and arm_smmu_capable() returns false for IOMMU_CAP_CACHE_COHERENCY. VFIO and iommufd both gate device binding on this capability, blocking userspace DMA drivers even when the caller manages cache coherency in software. Other platforms using the same compatible string (e.g. qcom,sa8775p-smmu-500) do have a coherent interconnect and carry dma-coherent in their DT node; arm_smmu_capable() already returns true for those without any override. A related problem exists on the mapping side: iommufd unconditionally sets IOMMU_CACHE in iommu_prot, which causes arm_lpae_prot_to_pte() to select Normal WB-RA-WA / Inner-Shareable attributes. On a non-coherent interconnect those attributes request snoops that the hardware cannot honour, risking silent data corruption. Add two hooks to struct arm_smmu_impl to let per-platform code address both problems, guarded by ARM_SMMU_FEAT_COHERENT_WALK so that coherent instances sharing the same impl are not affected: @CAPABLE: when set, arm_smmu_capable() delegates to this hook. The hook can inspect smmu->features to decide whether to override or delegate back to arm_smmu_capable(). qcom_smmu_500_capable() returns true for IOMMU_CAP_CACHE_COHERENCY only when COHERENT_WALK is absent. @prot_mask: bitmask of IOMMU_* flags cleared from iommu_prot in arm_smmu_map_pages(), but only when ARM_SMMU_FEAT_COHERENT_WALK is not set. Coherent instances keep IOMMU_CACHE so io-pgtable selects the correct WB+IS PTEs. Non-coherent instances set IOMMU_CACHE here to prevent WB+IS attributes on an interconnect that cannot honour them. Export arm_smmu_capable() so impl modules can use it as a fallback. Wire both hooks into qcom_smmu_500_impl with prot_mask = IOMMU_CACHE. The COHERENT_WALK guard in both the hook and arm_smmu_map_pages() ensures coherent platforms (sa8775p, sm8450, sm8250, etc.) are unaffected. Assisted-by: Claude:Claude-Haiku-4.5 Signed-off-by: Bibek Kumar Patro <bibek.patro@oss.qualcomm.com> Signed-off-by: Prakash Gupta <prakash.gupta@oss.qualcomm.com>
Bibek Kumar Patro (bibekpatro)
force-pushed
the
tech/all/workaround
branch
from
September 30, 2026 06:27
4a7cfd3 to
82d671d
Compare
qcomlnxci
requested review from
a team,
Dmitry Baryshkov (lumag),
Mukesh Ojha (mukeshojha-linux) and
yijiyang
and removed request for
a team
September 30, 2026 06:28
Prakash Gupta (quic-guptap)
left a comment
There was a problem hiding this comment.
Please keep original author and s-o-b order. I think the change is revised from https://github.com/qualcomm-
linux/kernel/commit/09e07a0d654f7a5da30e257d2e6be4f3dd64ebb6
could you please specify changes done on top of base?
Dmitry Baryshkov (lumag)
requested changes
Sep 30, 2026
Dmitry Baryshkov (lumag)
left a comment
Contributor
There was a problem hiding this comment.
Please don't use language like "Some Qualcomm platforms". It's very imprecise. Also I don't see this being Qualcomm-specific at all.
| * IOMMU_CAP_CACHE_COHERENCY so that VFIO/iommufd binding succeeds, while | ||
| * relying on arm_smmu_map_pages() to strip IOMMU_CACHE from iommu_prot | ||
| * (via prot_mask) so that io-pgtable does not select WB+IS attributes on | ||
| * a non-coherent interconnect. |
Contributor
There was a problem hiding this comment.
This looks like a commit message rather than a sensible code comment.
| * logic in arm_smmu_capable() already returns true. Only | ||
| * advertise the capability on non-coherent instances so | ||
| * that callers managing coherency in software can bind. | ||
| */ |
Contributor
There was a problem hiding this comment.
Why isn't 'dma-coherent' enough in the IOMMU device?
| return -ENODEV; | ||
|
|
||
| /* | ||
| * Some Qualcomm platforms lack a coherent pagetable-walk interface. |
Contributor
There was a problem hiding this comment.
Again, it's a commit message.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Some Qualcomm platforms using qcom,smmu-500 (arm,mmu-500) do not connect the SMMU pagetable-walk interface to a coherent interconnect. On those platforms ARM_SMMU_FEAT_COHERENT_WALK is not set (no dma-coherent in the SMMU DT node), and arm_smmu_capable() returns false for IOMMU_CAP_CACHE_COHERENCY. VFIO and iommufd both gate device binding on this capability, blocking userspace DMA drivers even when the caller manages cache coherency in software.
Other platforms using the same compatible string (e.g. qcom,sa8775p-smmu-500) do have a coherent interconnect and carry dma-coherent in their DT node; arm_smmu_capable() already returns true for those without any override.
A related problem exists on the mapping side: iommufd unconditionally sets IOMMU_CACHE in iommu_prot, which causes arm_lpae_prot_to_pte() to select Normal WB-RA-WA / Inner-Shareable attributes. On a non-coherent interconnect those attributes request snoops that the hardware cannot honour, risking silent data corruption.
Add two hooks to struct arm_smmu_impl to let per-platform code address both problems, guarded by ARM_SMMU_FEAT_COHERENT_WALK so that coherent instances sharing the same impl are not affected:
CAPABLE: when set, arm_smmu_capable() delegates to this hook. The
hook can inspect smmu->features to decide whether to override or
delegate back to arm_smmu_capable(). qcom_smmu_500_capable() returns
true for IOMMU_CAP_CACHE_COHERENCY only when COHERENT_WALK is absent.
@prot_mask: bitmask of IOMMU_* flags cleared from iommu_prot in
arm_smmu_map_pages(), but only when ARM_SMMU_FEAT_COHERENT_WALK is
not set. Coherent instances keep IOMMU_CACHE so io-pgtable selects
the correct WB+IS PTEs. Non-coherent instances set IOMMU_CACHE here
to prevent WB+IS attributes on an interconnect that cannot honour them.
Export arm_smmu_capable() so impl modules can use it as a fallback.
Wire both hooks into qcom_smmu_500_impl with prot_mask = IOMMU_CACHE. The COHERENT_WALK guard in both the hook and arm_smmu_map_pages() ensures coherent platforms (sa8775p, sm8450, sm8250, etc.) are unaffected.