Hi Daniel Vetter,
The patch https://patchwork.freedesktop.org/patch/414455/: "dma-buf: Add debug option" from Jan. 15, 2021, leads to the following expection:
Backtrace:
[<ffffffc0081a2258>] atomic_notifier_call_chain+0x9c/0xe8 [<ffffffc0081a2d54>] notify_die+0x114/0x19c [<ffffffc0080348d8>] __die+0xec/0x468 [<ffffffc008034648>] die+0x54/0x1f8 [<ffffffc0080631e8>] die_kernel_fault+0x80/0xbc [<ffffffc0080630fc>] __do_kernel_fault+0x268/0x2d4 [<ffffffc008062c4c>] do_bad_area+0x68/0x148 [<ffffffc00a6dab34>] do_translation_fault+0xbc/0x108 [<ffffffc0080619f8>] do_mem_abort+0x6c/0x1e8 [<ffffffc00a68f5cc>] el1_abort+0x3c/0x64 [<ffffffc00a68f54c>] el1h_64_sync_handler+0x5c/0xa0 [<ffffffc008011ae4>] el1h_64_sync+0x78/0x80 [<ffffffc008063b9c>] dcache_inval_poc+0x40/0x58 [<ffffffc009236104>] iommu_dma_sync_sg_for_cpu+0x144/0x280 [<ffffffc0082b4870>] dma_sync_sg_for_cpu+0xbc/0x110 [<ffffffc002c7538c>] system_heap_dma_buf_begin_cpu_access+0x144/0x1e0 [system_heap] [<ffffffc0094154e4>] dma_buf_begin_cpu_access+0xa4/0x10c [<ffffffc004888df4>] isp71_allocate_working_buffer+0x3b0/0xe8c [mtk_hcp] [<ffffffc004884a20>] mtk_hcp_allocate_working_buffer+0xc0/0x108 [mtk_hcp]
Because of CONFIG_DMABUF_DEBUG will default enable when DMA_API_DEBUG enable, and when not support dma coherent, since the main function of user calling dma_buf_begin_cpu_access and dma_buf_end_cpu_access is to do cache sync during dma_buf_map_attachment and dma_buf_unmap_attachment, which get PA error from sgtable by sg_phys(sg), this leads to the expection.
1.dma_buf_map_attachement() -.> mangle_sg_table(sg) // "sg->page_link ^= ~0xffUL" to rotate PA in this patch.
2.dma_buf_begin_cpu_access() -.> system_heap_dma_buf_begin_cpu_access() in system_heap.c // do cache sync if mapped attachment before -.> iommu_dma_sync_sg_for_cpu() in dma-iommu.c -.> arch_sync_dma_for_device(sg_phys(sg), sg->length, dir) // get PA error since PA mix up
3.dma_buf_end_cpu_access() and dma_buf_begin_cpu_access are similar.
4.dma_buf_unmap_attachement() -.> mangle_sg_table(sg) // "sg->page_link ^= ~0xffUL" to rotate PA
drivers/dma-buf/Kconfig: config DMABUF_DEBUG bool "DMA-BUF debug checks" default y if DMA_API_DEBUG
drivers/dma-buf/dma-buf.c: static void mangle_sg_table(struct sg_table *sg_table) { #ifdef CONFIG_DMABUF_DEBUG int i; struct scatterlist *sg;
/* To catch abuse of the underlying struct page by importers mix * up the bits, but take care to preserve the low SG_ bits to * not corrupt the sgt. The mixing is undone in __unmap_dma_buf * before passing the sgt back to the exporter. */ for_each_sgtable_sg(sg_table, sg, i) sg->page_link ^= ~0xffUL; #endif }
drivers/iommu/dma-iommu.c: static void iommu_dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sgl, int nelems, enum dma_data_direction dir) { struct scatterlist *sg; int i;
if (dev_is_dma_coherent(dev) && !dev_is_untrusted(dev)) return;
for_each_sg(sgl, sg, nelems, i) { if (!dev_is_dma_coherent(dev)) arch_sync_dma_for_cpu(sg_phys(sg), sg->length, dir);
if (is_swiotlb_buffer(sg_phys(sg))) swiotlb_tbl_sync_single(dev, sg_phys(sg), sg->length, dir, SYNC_FOR_CPU); } }
Thanks, Yunfei.
Hi Yunfei,
well it looks like system_heap_dma_buf_begin_cpu_access() is exactly doing what this patch tries to prevent.
In other words the dma_heap implementation is doing something which it shouldn't be doing. The patch from Daniel is just surfacing this.
Regards, Christian.
Am 31.08.22 um 12:35 schrieb yf.wang@mediatek.com:
Hi Daniel Vetter,
The patch https://patchwork.freedesktop.org/patch/414455/: "dma-buf: Add debug option" from Jan. 15, 2021, leads to the following expection:
Backtrace:
[<ffffffc0081a2258>] atomic_notifier_call_chain+0x9c/0xe8 [<ffffffc0081a2d54>] notify_die+0x114/0x19c [<ffffffc0080348d8>] __die+0xec/0x468 [<ffffffc008034648>] die+0x54/0x1f8 [<ffffffc0080631e8>] die_kernel_fault+0x80/0xbc [<ffffffc0080630fc>] __do_kernel_fault+0x268/0x2d4 [<ffffffc008062c4c>] do_bad_area+0x68/0x148 [<ffffffc00a6dab34>] do_translation_fault+0xbc/0x108 [<ffffffc0080619f8>] do_mem_abort+0x6c/0x1e8 [<ffffffc00a68f5cc>] el1_abort+0x3c/0x64 [<ffffffc00a68f54c>] el1h_64_sync_handler+0x5c/0xa0 [<ffffffc008011ae4>] el1h_64_sync+0x78/0x80 [<ffffffc008063b9c>] dcache_inval_poc+0x40/0x58 [<ffffffc009236104>] iommu_dma_sync_sg_for_cpu+0x144/0x280 [<ffffffc0082b4870>] dma_sync_sg_for_cpu+0xbc/0x110 [<ffffffc002c7538c>] system_heap_dma_buf_begin_cpu_access+0x144/0x1e0 [system_heap] [<ffffffc0094154e4>] dma_buf_begin_cpu_access+0xa4/0x10c [<ffffffc004888df4>] isp71_allocate_working_buffer+0x3b0/0xe8c [mtk_hcp] [<ffffffc004884a20>] mtk_hcp_allocate_working_buffer+0xc0/0x108 [mtk_hcp]
Because of CONFIG_DMABUF_DEBUG will default enable when DMA_API_DEBUG enable, and when not support dma coherent, since the main function of user calling dma_buf_begin_cpu_access and dma_buf_end_cpu_access is to do cache sync during dma_buf_map_attachment and dma_buf_unmap_attachment, which get PA error from sgtable by sg_phys(sg), this leads to the expection.
1.dma_buf_map_attachement() -.> mangle_sg_table(sg) // "sg->page_link ^= ~0xffUL" to rotate PA in this patch.
2.dma_buf_begin_cpu_access() -.> system_heap_dma_buf_begin_cpu_access() in system_heap.c // do cache sync if mapped attachment before -.> iommu_dma_sync_sg_for_cpu() in dma-iommu.c -.> arch_sync_dma_for_device(sg_phys(sg), sg->length, dir) // get PA error since PA mix up
3.dma_buf_end_cpu_access() and dma_buf_begin_cpu_access are similar.
4.dma_buf_unmap_attachement() -.> mangle_sg_table(sg) // "sg->page_link ^= ~0xffUL" to rotate PA
drivers/dma-buf/Kconfig: config DMABUF_DEBUG bool "DMA-BUF debug checks" default y if DMA_API_DEBUG
drivers/dma-buf/dma-buf.c: static void mangle_sg_table(struct sg_table *sg_table) { #ifdef CONFIG_DMABUF_DEBUG int i; struct scatterlist *sg;
/* To catch abuse of the underlying struct page by importers mix * up the bits, but take care to preserve the low SG_ bits to * not corrupt the sgt. The mixing is undone in __unmap_dma_buf * before passing the sgt back to the exporter. */ for_each_sgtable_sg(sg_table, sg, i) sg->page_link ^= ~0xffUL; #endif }
drivers/iommu/dma-iommu.c: static void iommu_dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sgl, int nelems, enum dma_data_direction dir) { struct scatterlist *sg; int i;
if (dev_is_dma_coherent(dev) && !dev_is_untrusted(dev)) return;
for_each_sg(sgl, sg, nelems, i) { if (!dev_is_dma_coherent(dev)) arch_sync_dma_for_cpu(sg_phys(sg), sg->length, dir);
if (is_swiotlb_buffer(sg_phys(sg))) swiotlb_tbl_sync_single(dev, sg_phys(sg), sg->length, dir, SYNC_FOR_CPU);
} }
Thanks, Yunfei.
linaro-mm-sig@lists.linaro.org