From 3c65f6f3c33aadbb465b431ef5fbffa415cbcc1d Mon Sep 17 00:00:00 2001 From: Jianqun Xu Date: Thu, 2 Mar 2023 10:26:48 +0800 Subject: [PATCH] video: rockchip: mpp: fix dma buf sync start dma address Locate the start dma address with the dma address from the first sg and the offset, since the sg_dma_address for the other sg will return a invalid mapping address (-1). Unable to handle kernel paging request at virtual address ffffff8000000000 Mem abort info: ESR = 0x96000146 EC = 0x25: DABT (current EL), IL = 32 bits SET = 0, FnV = 0 EA = 0, S1PTW = 0 Data abort info: ISV = 0, ISS = 0x00000146 CM = 1, WnR = 1 swapper pgtable: 4k pages, 39-bit VAs, pgdp=0000000001caa000 [ffffff8000000000] pgd=000000007fffb003, p4d=000000007fffb003, pud=000000007fffb003, pmd=0000000000000000 Internal error: Oops: 96000146 [#1] PREEMPT SMP Modules linked in: rk_vcodec [last unloaded: rk_vcodec] CPU: 0 PID: 2173 Comm: mpp_mjpege_217 Not tainted 5.10.110 #389 Hardware name: Rockchip PX30 mini evb ddr3 board (DT) pstate: 80400005 (Nzcv daif +PAN -UAO -TCO BTYPE=--) pc : __clean_dcache_area_poc+0x20/0x38 lr : arch_sync_dma_for_device+0x20/0x2c sp : ffffffc0136fbb90 x29: ffffffc0136fbb90 x28: 000000000000026f x27: 0000000000000000 x26: ffffff805fa22c00 x25: 0000000000000000 x24: ffffff8045543800 x23: 0000000000100000 x22: 0000000000000000 x21: 0000000041100000 x20: 000000000000026f x19: 0000000000000001 x18: ffffffc012139060 x17: 0000000000000000 x16: 00000000000000c0 x15: 0000000000000004 x14: 0000000000003fff x13: ffffffc011c8c7f0 x12: 0000000000000000 x11: 0000000000000000 x10: 0000000000000001 x9 : 0000000100000000 x8 : 0000000000000000 x7 : 7320302074657366 x6 : ffffffc011e764a0 x5 : ffffffffffffffff x4 : 0000000000000000 x3 : 000000000000003f x2 : 0000000000000040 x1 : ffffff800000026f x0 : ffffff8000000000 Call trace: __clean_dcache_area_poc+0x20/0x38 iommu_dma_sync_single_for_device+0x40/0x54 dma_sync_single_for_device+0x2c/0xe8 mpp_dma_buf_sync+0x138/0x184 [rk_vcodec] vepu_alloc_task+0x2a0/0x390 [rk_vcodec] mpp_process_task_default+0x5c/0x218 [rk_vcodec] mpp_dev_ioctl+0x39c/0x5e0 [rk_vcodec] __arm64_compat_sys_ioctl+0x104/0x158 el0_svc_common+0xac/0x1ac do_el0_svc_compat+0x1c/0x28 el0_svc_compat+0x10/0x1c el0_sync_compat_handler+0x60/0x8c el0_sync_compat+0x164/0x180 Fixes: 3fb2e28edd06 ("video: rockchip: mpp: change the way to refresh the dma cache") Signed-off-by: Yandong Lin Signed-off-by: Jianqun Xu Change-Id: I7d9fc844df602e38ee8fa0e303a0e251a58b072a --- drivers/video/rockchip/mpp/mpp_iommu.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/drivers/video/rockchip/mpp/mpp_iommu.c b/drivers/video/rockchip/mpp/mpp_iommu.c index 612813bf615d..0b9c8483801d 100644 --- a/drivers/video/rockchip/mpp/mpp_iommu.c +++ b/drivers/video/rockchip/mpp/mpp_iommu.c @@ -382,21 +382,21 @@ mpp_dma_session_create(struct device *dev, u32 max_buffers) void mpp_dma_buf_sync(struct mpp_dma_buffer *buffer, u32 offset, u32 length, enum dma_data_direction dir, bool for_cpu) { - struct scatterlist *sg; - unsigned int len = 0; - dma_addr_t sg_dma_addr; - int i; - struct sg_table *sgt = buffer->sgt; struct device *dev = buffer->dma->dev; + struct sg_table *sgt = buffer->sgt; + struct scatterlist *sg = sgt->sgl; + dma_addr_t sg_dma_addr = sg_dma_address(sg); + unsigned int len = 0; + int i; for_each_sgtable_sg(sgt, sg, i) { unsigned int sg_offset, sg_left, size = 0; - sg_dma_addr = sg_dma_address(sg); - len += sg->length; - if (len <= offset) + if (len <= offset) { + sg_dma_addr += sg->length; continue; + } sg_left = len - offset; sg_offset = sg->length - sg_left; @@ -412,6 +412,7 @@ void mpp_dma_buf_sync(struct mpp_dma_buffer *buffer, u32 offset, u32 length, offset += size; length -= size; + sg_dma_addr += sg->length; if (length == 0) break;