vmap_pfn design to only allow none page based pfn map.

This patch try simple copy pfn vmap code to fix it.

Fix vunmap_udmabuf fix match with vmap_udmabuf, use vunmap.

Signed-off-by: Huan Yang <l...@vivo.com>
---
 drivers/dma-buf/udmabuf.c | 49 +++++++++++++++++++++++++++++++++++----
 1 file changed, 45 insertions(+), 4 deletions(-)

diff --git a/drivers/dma-buf/udmabuf.c b/drivers/dma-buf/udmabuf.c
index cc7398cc17d6..2dfe639230dc 100644
--- a/drivers/dma-buf/udmabuf.c
+++ b/drivers/dma-buf/udmabuf.c
@@ -106,6 +106,49 @@ static int mmap_udmabuf(struct dma_buf *buf, struct 
vm_area_struct *vma)
        return 0;
 }
 
+struct udmabuf_pfn_data {
+       unsigned long *pfns;
+       pgprot_t prot;
+       unsigned int idx;
+};
+
+static int udmabuf_vmap_pfn_apply(pte_t *pte, unsigned long addr, void 
*private)
+{
+       struct udmabuf_pfn_data *data = private;
+       pte_t ptent;
+
+       ptent = pte_mkspecial(pfn_pte(data->pfns[data->idx], data->prot));
+       set_pte_at(&init_mm, addr, pte, ptent);
+
+       data->idx++;
+       return 0;
+}
+
+static void *udmabuf_vmap_pfn(unsigned long *pfns, unsigned int count,
+                             pgprot_t prot)
+{
+       struct udmabuf_pfn_data data = { .pfns = pfns,
+                                        .prot = pgprot_nx(prot) };
+       struct vm_struct *area;
+
+       area = get_vm_area_caller(count * PAGE_SIZE, 0,
+                                 __builtin_return_address(0));
+       if (!area)
+               return NULL;
+
+       if (apply_to_page_range(&init_mm, (unsigned long)area->addr,
+                               count * PAGE_SIZE, udmabuf_vmap_pfn_apply,
+                               &data)) {
+               free_vm_area(area);
+               return NULL;
+       }
+
+       flush_cache_vmap((unsigned long)area->addr,
+                        (unsigned long)area->addr + count * PAGE_SIZE);
+
+       return area->addr;
+}
+
 static int vmap_udmabuf(struct dma_buf *buf, struct iosys_map *map)
 {
        struct udmabuf *ubuf = buf->priv;
@@ -130,7 +173,7 @@ static int vmap_udmabuf(struct dma_buf *buf, struct 
iosys_map *map)
                pfns[pg] = pfn;
        }
 
-       vaddr = vmap_pfn(pfns, ubuf->pagecount, PAGE_KERNEL);
+       vaddr = udmabuf_vmap_pfn(pfns, ubuf->pagecount, PAGE_KERNEL);
        kvfree(pfns);
        if (!vaddr)
                return -EINVAL;
@@ -141,11 +184,9 @@ static int vmap_udmabuf(struct dma_buf *buf, struct 
iosys_map *map)
 
 static void vunmap_udmabuf(struct dma_buf *buf, struct iosys_map *map)
 {
-       struct udmabuf *ubuf = buf->priv;
-
        dma_resv_assert_held(buf->resv);
 
-       vm_unmap_ram(map->vaddr, ubuf->pagecount);
+       vunmap(map->vaddr);
 }
 
 static struct sg_table *get_sg_table(struct device *dev, struct dma_buf *buf,
-- 
2.48.1


Reply via email to