Skip to content

iommu/arm-smmu: allow per-impl capability override and prot masking - #1943

Open
Bibek Kumar Patro (bibekpatro) wants to merge 1 commit into
qualcomm-linux:tech/all/workaroundfrom
bibekpatro:tech/all/workaround
Open

Bibek Kumar Patro (bibekpatro) wants to merge 1 commit into
qualcomm-linux:tech/all/workaroundfrom
bibekpatro:tech/all/workaround

Conversation

@bibekpatro

Copy link
Copy Markdown

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.

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>

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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?

@lumag Dmitry Baryshkov (lumag) left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.
*/

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why isn't 'dma-coherent' enough in the IOMMU device?

return -ENODEV;

/*
* Some Qualcomm platforms lack a coherent pagetable-walk interface.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again, it's a commit message.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants