From e8be46e733f32dca9347a0c046562568becab12c Mon Sep 17 00:00:00 2001 From: Mark Yao Date: Wed, 19 Apr 2017 16:00:44 +0800 Subject: [PATCH] video/rockchip: rga2: fix rga crash with high memory phys_to_virt not support highmem. [ 38.247986] Unable to handle kernel paging request at virtual address 20857000 [ 38.306701] pgd = ed418000 [ 38.309505] [20857000] *pgd=00000000 [ 38.313118] Internal error: Oops: 2805 [#1] PREEMPT SMP ARM [ 38.318682] Modules linked in: [ 38.321746] CPU: 2 PID: 1410 Comm: DisplayThread Not tainted 4.4.55 #156 [ 38.328435] Hardware name: Rockchip (Device Tree) [ 38.333131] task: dd2ad480 ti: dcc08000 task.ti: dcc08000 [ 38.338527] PC is at v7_dma_flush_range+0x1c/0x34 [ 38.343225] LR is at rga_dma_flush_range+0x30/0x68 [ 39.215229] [] (v7_dma_flush_range) from [] (rga_dma_flush_range+0x30/0x68) [ 39.223918] [] (rga_dma_flush_range) from [] (rga2_MapUserMemory+0x220/0x2b0) [ 39.232777] [] (rga2_MapUserMemory) from [] (rga2_set_mmu_info+0x1bc/0x928) [ 39.241461] [] (rga2_set_mmu_info) from [] (rga2_blit+0x2f4/0x448) [ 39.249366] [] (rga2_blit) from [] (rga2_blit_sync+0x64/0x1b0) [ 39.256923] [] (rga2_blit_sync) from [] (rga_ioctl+0x4d0/0x6d8) [ 39.264570] [] (rga_ioctl) from [] (do_vfs_ioctl+0x564/0x6a0) [ 39.272042] [] (do_vfs_ioctl) from [] (SyS_ioctl+0x4c/0x74) [ 39.279342] [] (SyS_ioctl) from [] (ret_fast_syscall+0x0/0x3c) Change-Id: I81fe2d108932a96414a2822c1329c4335753d1d9 Signed-off-by: Mark Yao --- drivers/video/rockchip/rga2/rga2_mmu_info.c | 27 +++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/drivers/video/rockchip/rga2/rga2_mmu_info.c b/drivers/video/rockchip/rga2/rga2_mmu_info.c index 2cd40a5d040c..1d41fa48b908 100644 --- a/drivers/video/rockchip/rga2/rga2_mmu_info.c +++ b/drivers/video/rockchip/rga2/rga2_mmu_info.c @@ -269,6 +269,7 @@ static int rga2_MapUserMemory(struct page **pages, uint32_t *pageTable, uint32_t status; unsigned long Address; unsigned long pfn; + struct page __maybe_unused *page; void *virt; spinlock_t * ptl; pte_t * pte; @@ -338,8 +339,30 @@ static int rga2_MapUserMemory(struct page **pages, uint32_t *pageTable, << PAGE_SHIFT)) & ~PAGE_MASK)); pte_unmap_unlock(pte, ptl); pageTable[i] = (uint32_t)Address; - virt = phys_to_virt(pageTable[i]); - rga_dma_flush_range(virt, virt + 4 * 1024); + +#ifdef CONFIG_ARM + page = pfn_to_page(pfn); + if (PageHighMem(page)) { + if (cache_is_vipt_nonaliasing()) { + virt = kmap_atomic(page); + dmac_flush_range(virt, virt + PAGE_SIZE); + kunmap_atomic(virt); + } else { + virt = kmap_high_get(page); + if (virt) { + dmac_flush_range(virt, + virt + PAGE_SIZE); + kunmap_high(page); + } + } + outer_flush_range(pageTable[i], + pageTable[i] + PAGE_SIZE); + } else +#endif + { + virt = phys_to_virt(pageTable[i]); + rga_dma_flush_range(virt, virt + 4 * 1024); + } } up_read(¤t->mm->mmap_sem); return status; -- 2.34.1