android: ion: fix missing buffer initialization
authorCho KyongHo <pullip.cho@samsung.com>
Fri, 9 Feb 2018 06:11:15 +0000 (15:11 +0900)
committerSangwook Ju <sw.ju@samsung.com>
Mon, 14 May 2018 10:45:22 +0000 (19:45 +0900)
Every buffer allocated to userspace should be initialized to a
specific pattern to remove data written by previous users of the
memory in the buffer. The initialization should include elimination
of dirty cache lines allocated for a uncached buffer to prevent write
back from dirty cache lines after uncached data write to the buffer.
This write-back corrupts the buffer with the stale data in the cache.

Cache flush on allocation uses __flush_dcache_area() that is not a
kernel API function allowed for the drivers. But we have no chice than
that because dma-mapping API needs a device descriptor configured for
DMA. Instead modifying pseudo device descriptor, ion_device, we have
decided to use ARM64 specific function __funsh_dcache_area() for
convenient maintenance.

Change-Id: I6d6dda56a5ac4f8cf9dc796b3eddb7ba40e337d9
Signed-off-by: Cho KyongHo <pullip.cho@samsung.com>
drivers/staging/android/ion/ion_carveout_heap.c
drivers/staging/android/ion/ion_cma_heap.c
drivers/staging/android/ion/ion_page_pool.c

index dcee60b2d8136f7cc315dfbcd92337b117be6740..52718cdec6adf14722b87f9ce756479e706f78d5 100644 (file)
@@ -22,6 +22,9 @@
 #include <linux/scatterlist.h>
 #include <linux/slab.h>
 #include <linux/vmalloc.h>
+
+#include <asm/cacheflush.h>
+
 #include "ion.h"
 
 #define ION_CARVEOUT_ALLOCATE_FAIL     -1
@@ -98,6 +101,9 @@ static void ion_carveout_heap_free(struct ion_buffer *buffer)
        phys_addr_t paddr = PFN_PHYS(page_to_pfn(page));
 
        ion_heap_buffer_zero(buffer);
+       /* the free pages in carveout pool should be cache cold */
+       if ((buffer->flags & ION_FLAG_CACHED) != 0)
+               __flush_dcache_area(page_to_virt(page), buffer->size);
 
        ion_carveout_free(heap, paddr, buffer->size);
        sg_free_table(table);
@@ -123,10 +129,12 @@ struct ion_heap *ion_carveout_heap_create(struct ion_platform_heap *heap_data)
        page = pfn_to_page(PFN_DOWN(heap_data->base));
        size = heap_data->size;
 
-       ret = ion_heap_pages_zero(page, size, pgprot_writecombine(PAGE_KERNEL));
+       ret = ion_heap_pages_zero(page, size, PAGE_KERNEL);
        if (ret)
                return ERR_PTR(ret);
 
+       __flush_dcache_area(page_to_virt(page), size);
+
        carveout_heap = kzalloc(sizeof(*carveout_heap), GFP_KERNEL);
        if (!carveout_heap)
                return ERR_PTR(-ENOMEM);
index fa3e4b7e0c9ffb40ea8f0c16c2d4966c8376ef5c..27d6d2ff972a170fa23d38dba0b6f82a83434715 100644 (file)
@@ -23,6 +23,8 @@
 #include <linux/scatterlist.h>
 #include <linux/highmem.h>
 
+#include <asm/cacheflush.h>
+
 #include "ion.h"
 
 struct ion_cma_heap {
@@ -80,6 +82,10 @@ static int ion_cma_allocate(struct ion_heap *heap, struct ion_buffer *buffer,
 
        buffer->priv_virt = pages;
        buffer->sg_table = table;
+
+       if (!(flags & ION_FLAG_CACHED))
+               __flush_dcache_area(page_to_virt(pages), len);
+
        return 0;
 
 free_mem:
index 817849df9de33dd0ecc92940098ac92a66fabb1c..184fc29417f73d6567d438c85eef8db1a908d82b 100644 (file)
@@ -23,6 +23,8 @@
 #include <linux/slab.h>
 #include <linux/swap.h>
 
+#include <asm/cacheflush.h>
+
 #include "ion.h"
 
 static void *ion_page_pool_alloc_pages(struct ion_page_pool *pool)
@@ -85,8 +87,12 @@ struct page *ion_page_pool_alloc(struct ion_page_pool *pool)
                page = ion_page_pool_remove(pool, false);
        mutex_unlock(&pool->mutex);
 
-       if (!page)
+       if (!page) {
                page = ion_page_pool_alloc_pages(pool);
+               if (!pool->cached)
+                       __flush_dcache_area(page_to_virt(page),
+                                           1 << (PAGE_SHIFT + pool->order));
+       }
 
        return page;
 }
@@ -161,8 +167,7 @@ struct ion_page_pool *ion_page_pool_create(gfp_t gfp_mask, unsigned int order,
        pool->order = order;
        mutex_init(&pool->mutex);
        plist_node_init(&pool->list, order);
-       if (cached)
-               pool->cached = true;
+       pool->cached = cached;
 
        return pool;
 }