gpu: ion: ion_chunk_heap: Zero chunk heap memory at creation time
authorRebecca Schultz Zavin <rebecca@android.com>
Mon, 1 Apr 2013 23:40:02 +0000 (16:40 -0700)
committerArve Hjønnevåg <arve@android.com>
Mon, 1 Jul 2013 21:16:24 +0000 (14:16 -0700)
Allocations from the ion heap need to be zeroed to protect userspace
from seeing memory belonging to other processes.  First allocations
from this heap were not zero'd allowing users to see memory from other
processes on a warm reset.

Change-Id: I524a7b79cb76c390c870fcf8b30d213185fc85a0
Signed-off-by: Rebecca Schultz Zavin <rebecca@android.com>
drivers/gpu/ion/ion_chunk_heap.c

index 7f482b625475d132bbcda714f10b745d48a8e2e5..cc824f3a81d0e654d6c96629eb81cc53ff18f1ba 100644 (file)
@@ -140,6 +140,10 @@ static struct ion_heap_ops chunk_heap_ops = {
 struct ion_heap *ion_chunk_heap_create(struct ion_platform_heap *heap_data)
 {
        struct ion_chunk_heap *chunk_heap;
+       struct vm_struct *vm_struct;
+       pgprot_t pgprot = pgprot_writecombine(PAGE_KERNEL);
+       int i, ret;
+
 
        chunk_heap = kzalloc(sizeof(struct ion_chunk_heap), GFP_KERNEL);
        if (!chunk_heap)
@@ -149,12 +153,30 @@ struct ion_heap *ion_chunk_heap_create(struct ion_platform_heap *heap_data)
        chunk_heap->pool = gen_pool_create(get_order(chunk_heap->chunk_size) +
                                           PAGE_SHIFT, -1);
        if (!chunk_heap->pool) {
-               kfree(chunk_heap);
-               return ERR_PTR(-ENOMEM);
+               ret = -ENOMEM;
+               goto error_gen_pool_create;
        }
        chunk_heap->base = heap_data->base;
        chunk_heap->size = heap_data->size;
        chunk_heap->allocated = 0;
+
+       vm_struct = get_vm_area(PAGE_SIZE, VM_ALLOC);
+       if (!vm_struct) {
+               ret = -ENOMEM;
+               goto error;
+       }
+       for (i = 0; i < chunk_heap->size; i += PAGE_SIZE) {
+               struct page *page = phys_to_page(chunk_heap->base + i);
+               struct page **pages = &page;
+
+               ret = map_vm_area(vm_struct, pgprot, &pages);
+               if (ret)
+                       goto error_map_vm_area;
+               memset(vm_struct->addr, 0, PAGE_SIZE);
+               unmap_kernel_range((unsigned long)vm_struct->addr, PAGE_SIZE);
+       }
+       free_vm_area(vm_struct);
+
        __dma_page_cpu_to_dev(phys_to_page(heap_data->base), 0, heap_data->size,
                              DMA_BIDIRECTIONAL);
        gen_pool_add(chunk_heap->pool, chunk_heap->base, heap_data->size, -1);
@@ -165,6 +187,14 @@ struct ion_heap *ion_chunk_heap_create(struct ion_platform_heap *heap_data)
                heap_data->size, heap_data->align);
 
        return &chunk_heap->heap;
+
+error_map_vm_area:
+       free_vm_area(vm_struct);
+error:
+       gen_pool_destroy(chunk_heap->pool);
+error_gen_pool_create:
+       kfree(chunk_heap);
+       return ERR_PTR(ret);
 }
 
 void ion_chunk_heap_destroy(struct ion_heap *heap)