Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider: - [Critical] drm/msm: bogus physical addresses in __do_map() when dma_iommu is active --
commit 2ee69d02162f3f85f96721bc094502a3dd37d6fa Author: Rob Clark <[email protected]> drm/msm: Convert map helper to use dma-address This commit switches __do_map() in msm_iommu.c from iterating over scatterlist entries with sg_phys(sg) and sg->length to iterating with for_each_sgtable_dma_sg(), sg_dma_address(sg), and sg_dma_len(sg) to avoid issues when CONFIG_DMABUF_DEBUG strips page pointers from scatterlists. > diff --git a/drivers/gpu/drm/msm/msm_iommu.c b/drivers/gpu/drm/msm/msm_iommu.c > index 479e5450a4dcd..c2950d32c5075 100644 > --- a/drivers/gpu/drm/msm/msm_iommu.c > +++ b/drivers/gpu/drm/msm/msm_iommu.c > @@ -153,9 +153,9 @@ __do_map(unsigned long pgsize_bitmap, u64 iova, struct > sg_table *sgt, size_t off > u64 addr = iova; > unsigned int i; > > - for_each_sgtable_sg (sgt, sg, i) { > - size_t size = sg->length; > - phys_addr_t phys = sg_phys(sg); > + for_each_sgtable_dma_sg (sgt, sg, i) { > + size_t size = sg_dma_len(sg); > + phys_addr_t phys = sg_dma_address(sg); [Severity: Critical] As reported by Dmitry Baryshkov on v3 [1], can passing sg_dma_address(sg) and sg_dma_len(sg) as physical addresses to ops->map() in __do_map() program bogus physical addresses into the SMMU page tables when use_dma_iommu() is true on the DRM DMA device? In get_pages() in drivers/gpu/drm/msm/msm_gem.c, scatterlists are mapped against drm_dev_dma_dev(obj->dev): ret = dma_map_sgtable(drm_dev_dma_dev(obj->dev), msm_obj->sgt, DMA_BIDIRECTIONAL, map_attrs); On platforms where the iommus property is placed directly on obj->dev->dev (such as MDP/DPU display controller nodes checked in msm_kms_init_vm(), or when separate_gpu_kms is used) and the IOMMU driver does not return IOMMU_DOMAIN_IDENTITY from .def_domain_type, the IOMMU core allocates an IOMMU_DOMAIN_DMA default domain during bus probe and iommu_setup_dma_ops() sets use_dma_iommu(dev) to true: dma_iommu = iommu_is_dma_domain(domain); dev_assign_dma_iommu(dev, dma_iommu); This happens, for example, with qcom_iommu_ops in drivers/iommu/arm/arm-smmu/qcom_iommu.c (used on MSM8916 / db410c) which does not implement .def_domain_type, and with qcom_smmu_client_of_match in drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c which does not match qcom,mdp5 display-controller nodes. When msm_iommu_new() later attaches its own unmanaged domain via iommu_attach_device(iommu->domain, dev), group->default_domain remains the DMA domain and use_dma_iommu(dev) stays true. As a result, dma_go_direct() returns false and dma_map_sgtable() calls iommu_dma_map_sg(), which allocates a virtual IOVA from the inactive default_domain, coalesces segments into sg_dma_len(sg), and stores that IOVA in sg_dma_address(sg). When __do_map() then passes phys = sg_dma_address(sg) and size = sg_dma_len(sg) to ops->map() (via msm_iommu_pagetable_map() or msm_iommu_map()), wouldn't it program virtual IOVAs from the unused default domain into the active GPU and display page tables as if they were CPU physical addresses? [1] https://lore.kernel.org/r/wxfx4nhwdx6dud4ahy3rfz3btfto4t2zor2pjbotlqpglvwolx@jhnm65bzecnq -- Sashiko AI review ยท https://sashiko.dev/#/patchset/[email protected]?part=5
