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

Reply via email to