From: Cho KyongHo Date: Fri, 9 Feb 2018 06:11:15 +0000 (+0900) Subject: android: ion: fix missing buffer initialization X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=836d940157fbfa49da4a500f517d3f0617bd9e1b;p=GitHub%2FLineageOS%2Fandroid_kernel_motorola_exynos9610.git android: ion: fix missing buffer initialization 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 --- diff --git a/drivers/staging/android/ion/ion_carveout_heap.c b/drivers/staging/android/ion/ion_carveout_heap.c index dcee60b2d813..52718cdec6ad 100644 --- a/drivers/staging/android/ion/ion_carveout_heap.c +++ b/drivers/staging/android/ion/ion_carveout_heap.c @@ -22,6 +22,9 @@ #include #include #include + +#include + #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); diff --git a/drivers/staging/android/ion/ion_cma_heap.c b/drivers/staging/android/ion/ion_cma_heap.c index fa3e4b7e0c9f..27d6d2ff972a 100644 --- a/drivers/staging/android/ion/ion_cma_heap.c +++ b/drivers/staging/android/ion/ion_cma_heap.c @@ -23,6 +23,8 @@ #include #include +#include + #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: diff --git a/drivers/staging/android/ion/ion_page_pool.c b/drivers/staging/android/ion/ion_page_pool.c index 817849df9de3..184fc29417f7 100644 --- a/drivers/staging/android/ion/ion_page_pool.c +++ b/drivers/staging/android/ion/ion_page_pool.c @@ -23,6 +23,8 @@ #include #include +#include + #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; }