Loading drivers/staging/android/ion/heaps/ion_carveout_heap.c +129 −27 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ struct ion_carveout_heap { struct msm_ion_heap heap; struct rw_semaphore mem_sem; struct gen_pool *pool; phys_addr_t base; }; Loading @@ -34,11 +35,19 @@ static phys_addr_t ion_carveout_allocate(struct ion_heap *heap, unsigned long size) { struct ion_carveout_heap *carveout_heap = to_carveout_heap(heap); unsigned long offset = gen_pool_alloc(carveout_heap->pool, size); if (!offset) return ION_CARVEOUT_ALLOCATE_FAIL; unsigned long offset = ION_CARVEOUT_ALLOCATE_FAIL; down_read(&carveout_heap->mem_sem); if (carveout_heap->pool) { offset = gen_pool_alloc(carveout_heap->pool, size); if (!offset) { offset = ION_CARVEOUT_ALLOCATE_FAIL; goto unlock; } } unlock: up_read(&carveout_heap->mem_sem); return offset; } Loading @@ -50,7 +59,10 @@ static void ion_carveout_free(struct ion_heap *heap, phys_addr_t addr, if (addr == ION_CARVEOUT_ALLOCATE_FAIL) return; down_read(&carveout_heap->mem_sem); if (carveout_heap->pool) gen_pool_free(carveout_heap->pool, addr, size); up_read(&carveout_heap->mem_sem); } static int ion_carveout_heap_allocate(struct ion_heap *heap, Loading Loading @@ -164,43 +176,130 @@ static int ion_carveout_pages_zero(struct page *page, size_t size, return ion_heap_sglist_zero(&sg, 1, pgprot); } static struct ion_heap * __ion_carveout_heap_create(struct ion_platform_heap *heap_data, static int ion_carveout_init_heap_memory(struct ion_carveout_heap *co_heap, phys_addr_t base, ssize_t size, bool sync) { struct ion_carveout_heap *carveout_heap; struct page *page = pfn_to_page(PFN_DOWN(base)); struct device *dev = co_heap->heap.dev; int ret; struct page *page; size_t size; struct device *dev = (struct device *)heap_data->priv; page = pfn_to_page(PFN_DOWN(heap_data->base)); size = heap_data->size; if (sync) if (sync) { if (!pfn_valid(PFN_DOWN(base))) return -EINVAL; ion_pages_sync_for_device(dev, page, size, DMA_BIDIRECTIONAL); } ret = ion_carveout_pages_zero(page, size, pgprot_writecombine(PAGE_KERNEL)); if (ret) return ERR_PTR(ret); return ret; co_heap->pool = gen_pool_create(PAGE_SHIFT, -1); if (!co_heap->pool) return -ENOMEM; co_heap->base = base; gen_pool_add(co_heap->pool, co_heap->base, size, -1); return ret; } static int ion_carveout_heap_add_memory(struct ion_heap *ion_heap, struct sg_table *sgt) { struct ion_carveout_heap *carveout_heap; int ret; if (!ion_heap || !sgt || sgt->nents != 1) return -EINVAL; carveout_heap = to_carveout_heap(ion_heap); down_write(&carveout_heap->mem_sem); if (carveout_heap->pool) { ret = -EBUSY; goto unlock; } ret = ion_carveout_init_heap_memory(carveout_heap, page_to_phys(sg_page(sgt->sgl)), sgt->sgl->length, true); unlock: up_write(&carveout_heap->mem_sem); return ret; } static int ion_carveout_heap_remove_memory(struct ion_heap *ion_heap, struct sg_table *sgt) { struct ion_carveout_heap *carveout_heap; phys_addr_t base; int ret = 0; if (!ion_heap || !sgt || sgt->nents != 1) return -EINVAL; carveout_heap = to_carveout_heap(ion_heap); down_write(&carveout_heap->mem_sem); if (!carveout_heap->pool) { ret = -EINVAL; goto unlock; } base = page_to_phys(sg_page(sgt->sgl)); if (carveout_heap->base != base) { ret = -EINVAL; goto unlock; } if (gen_pool_size(carveout_heap->pool) != gen_pool_avail(carveout_heap->pool)) { ret = -EBUSY; goto unlock; } gen_pool_destroy(carveout_heap->pool); carveout_heap->pool = NULL; unlock: up_write(&carveout_heap->mem_sem); return ret; } static struct msm_ion_heap_ops msm_carveout_heap_ops = { .add_memory = ion_carveout_heap_add_memory, .remove_memory = ion_carveout_heap_remove_memory, }; static struct ion_heap * __ion_carveout_heap_create(struct ion_platform_heap *heap_data, bool sync) { struct ion_carveout_heap *carveout_heap; int ret; struct device *dev = (struct device *)heap_data->priv; bool dynamic_heap = of_property_read_bool(dev->of_node, "qcom,dynamic-heap"); carveout_heap = kzalloc(sizeof(*carveout_heap), GFP_KERNEL); if (!carveout_heap) return ERR_PTR(-ENOMEM); carveout_heap->pool = gen_pool_create(PAGE_SHIFT, -1); if (!carveout_heap->pool) { carveout_heap->heap.dev = dev; if (!dynamic_heap) { ret = ion_carveout_init_heap_memory(carveout_heap, heap_data->base, heap_data->size, sync); if (ret) { kfree(carveout_heap); return ERR_PTR(-ENOMEM); return ERR_PTR(ret); } carveout_heap->base = heap_data->base; carveout_heap->heap.dev = dev; gen_pool_add(carveout_heap->pool, carveout_heap->base, heap_data->size, -1); } init_rwsem(&carveout_heap->mem_sem); carveout_heap->heap.ion_heap.ops = &carveout_heap_ops; carveout_heap->heap.ion_heap.buf_ops = msm_ion_dma_buf_ops; carveout_heap->heap.msm_heap_ops = &msm_carveout_heap_ops; carveout_heap->heap.ion_heap.type = ION_HEAP_TYPE_CARVEOUT; carveout_heap->heap.ion_heap.flags = ION_HEAP_FLAG_DEFER_FREE; Loading @@ -216,7 +315,10 @@ static void ion_carveout_heap_destroy(struct ion_heap *heap) { struct ion_carveout_heap *carveout_heap = to_carveout_heap(heap); down_write(&carveout_heap->mem_sem); if (carveout_heap->pool) gen_pool_destroy(carveout_heap->pool); up_write(&carveout_heap->mem_sem); kfree(carveout_heap); carveout_heap = NULL; } Loading drivers/staging/android/ion/heaps/msm_ion.c +5 −1 Original line number Diff line number Diff line Loading @@ -78,7 +78,11 @@ static struct ion_heap_desc ion_heap_meta[] = { { .id = ION_SECURE_CARVEOUT_HEAP_ID, .name = ION_SECURE_CARVEOUT_HEAP_NAME, } }, { .id = ION_TUI_CARVEOUT_HEAP_ID, .name = ION_TUI_CARVEOUT_HEAP_NAME, }, }; #define MAKE_HEAP_TYPE_MAPPING(h) { .name = #h, \ Loading drivers/staging/android/ion/heaps/msm_ion_priv.h +1 −0 Original line number Diff line number Diff line Loading @@ -38,6 +38,7 @@ #define ION_SECURE_HEAP_NAME "secure_heap" #define ION_SECURE_DISPLAY_HEAP_NAME "secure_display" #define ION_AUDIO_HEAP_NAME "audio" #define ION_TUI_CARVEOUT_HEAP_NAME "tui_carveout" /** * Debug feature. Make ION allocations DMA Loading include/uapi/linux/msm_ion_ids.h +2 −1 Original line number Diff line number Diff line /* SPDX-License-Identifier: GPL-2.0-only WITH Linux-syscall-note */ /* * Copyright (c) 2019, The Linux Foundation. All rights reserved. * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved. */ #ifndef _MSM_ION_IDS_H #define _MSM_ION_IDS_H Loading @@ -17,6 +17,7 @@ */ #define ION_SYSTEM_HEAP_ID ION_BIT(0) #define ION_TUI_CARVEOUT_HEAP_ID ION_BIT(2) #define ION_QSECOM_TA_HEAP_ID ION_BIT(8) #define ION_CAMERA_HEAP_ID ION_BIT(9) #define ION_ADSP_HEAP_ID ION_BIT(11) Loading Loading
drivers/staging/android/ion/heaps/ion_carveout_heap.c +129 −27 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ struct ion_carveout_heap { struct msm_ion_heap heap; struct rw_semaphore mem_sem; struct gen_pool *pool; phys_addr_t base; }; Loading @@ -34,11 +35,19 @@ static phys_addr_t ion_carveout_allocate(struct ion_heap *heap, unsigned long size) { struct ion_carveout_heap *carveout_heap = to_carveout_heap(heap); unsigned long offset = gen_pool_alloc(carveout_heap->pool, size); if (!offset) return ION_CARVEOUT_ALLOCATE_FAIL; unsigned long offset = ION_CARVEOUT_ALLOCATE_FAIL; down_read(&carveout_heap->mem_sem); if (carveout_heap->pool) { offset = gen_pool_alloc(carveout_heap->pool, size); if (!offset) { offset = ION_CARVEOUT_ALLOCATE_FAIL; goto unlock; } } unlock: up_read(&carveout_heap->mem_sem); return offset; } Loading @@ -50,7 +59,10 @@ static void ion_carveout_free(struct ion_heap *heap, phys_addr_t addr, if (addr == ION_CARVEOUT_ALLOCATE_FAIL) return; down_read(&carveout_heap->mem_sem); if (carveout_heap->pool) gen_pool_free(carveout_heap->pool, addr, size); up_read(&carveout_heap->mem_sem); } static int ion_carveout_heap_allocate(struct ion_heap *heap, Loading Loading @@ -164,43 +176,130 @@ static int ion_carveout_pages_zero(struct page *page, size_t size, return ion_heap_sglist_zero(&sg, 1, pgprot); } static struct ion_heap * __ion_carveout_heap_create(struct ion_platform_heap *heap_data, static int ion_carveout_init_heap_memory(struct ion_carveout_heap *co_heap, phys_addr_t base, ssize_t size, bool sync) { struct ion_carveout_heap *carveout_heap; struct page *page = pfn_to_page(PFN_DOWN(base)); struct device *dev = co_heap->heap.dev; int ret; struct page *page; size_t size; struct device *dev = (struct device *)heap_data->priv; page = pfn_to_page(PFN_DOWN(heap_data->base)); size = heap_data->size; if (sync) if (sync) { if (!pfn_valid(PFN_DOWN(base))) return -EINVAL; ion_pages_sync_for_device(dev, page, size, DMA_BIDIRECTIONAL); } ret = ion_carveout_pages_zero(page, size, pgprot_writecombine(PAGE_KERNEL)); if (ret) return ERR_PTR(ret); return ret; co_heap->pool = gen_pool_create(PAGE_SHIFT, -1); if (!co_heap->pool) return -ENOMEM; co_heap->base = base; gen_pool_add(co_heap->pool, co_heap->base, size, -1); return ret; } static int ion_carveout_heap_add_memory(struct ion_heap *ion_heap, struct sg_table *sgt) { struct ion_carveout_heap *carveout_heap; int ret; if (!ion_heap || !sgt || sgt->nents != 1) return -EINVAL; carveout_heap = to_carveout_heap(ion_heap); down_write(&carveout_heap->mem_sem); if (carveout_heap->pool) { ret = -EBUSY; goto unlock; } ret = ion_carveout_init_heap_memory(carveout_heap, page_to_phys(sg_page(sgt->sgl)), sgt->sgl->length, true); unlock: up_write(&carveout_heap->mem_sem); return ret; } static int ion_carveout_heap_remove_memory(struct ion_heap *ion_heap, struct sg_table *sgt) { struct ion_carveout_heap *carveout_heap; phys_addr_t base; int ret = 0; if (!ion_heap || !sgt || sgt->nents != 1) return -EINVAL; carveout_heap = to_carveout_heap(ion_heap); down_write(&carveout_heap->mem_sem); if (!carveout_heap->pool) { ret = -EINVAL; goto unlock; } base = page_to_phys(sg_page(sgt->sgl)); if (carveout_heap->base != base) { ret = -EINVAL; goto unlock; } if (gen_pool_size(carveout_heap->pool) != gen_pool_avail(carveout_heap->pool)) { ret = -EBUSY; goto unlock; } gen_pool_destroy(carveout_heap->pool); carveout_heap->pool = NULL; unlock: up_write(&carveout_heap->mem_sem); return ret; } static struct msm_ion_heap_ops msm_carveout_heap_ops = { .add_memory = ion_carveout_heap_add_memory, .remove_memory = ion_carveout_heap_remove_memory, }; static struct ion_heap * __ion_carveout_heap_create(struct ion_platform_heap *heap_data, bool sync) { struct ion_carveout_heap *carveout_heap; int ret; struct device *dev = (struct device *)heap_data->priv; bool dynamic_heap = of_property_read_bool(dev->of_node, "qcom,dynamic-heap"); carveout_heap = kzalloc(sizeof(*carveout_heap), GFP_KERNEL); if (!carveout_heap) return ERR_PTR(-ENOMEM); carveout_heap->pool = gen_pool_create(PAGE_SHIFT, -1); if (!carveout_heap->pool) { carveout_heap->heap.dev = dev; if (!dynamic_heap) { ret = ion_carveout_init_heap_memory(carveout_heap, heap_data->base, heap_data->size, sync); if (ret) { kfree(carveout_heap); return ERR_PTR(-ENOMEM); return ERR_PTR(ret); } carveout_heap->base = heap_data->base; carveout_heap->heap.dev = dev; gen_pool_add(carveout_heap->pool, carveout_heap->base, heap_data->size, -1); } init_rwsem(&carveout_heap->mem_sem); carveout_heap->heap.ion_heap.ops = &carveout_heap_ops; carveout_heap->heap.ion_heap.buf_ops = msm_ion_dma_buf_ops; carveout_heap->heap.msm_heap_ops = &msm_carveout_heap_ops; carveout_heap->heap.ion_heap.type = ION_HEAP_TYPE_CARVEOUT; carveout_heap->heap.ion_heap.flags = ION_HEAP_FLAG_DEFER_FREE; Loading @@ -216,7 +315,10 @@ static void ion_carveout_heap_destroy(struct ion_heap *heap) { struct ion_carveout_heap *carveout_heap = to_carveout_heap(heap); down_write(&carveout_heap->mem_sem); if (carveout_heap->pool) gen_pool_destroy(carveout_heap->pool); up_write(&carveout_heap->mem_sem); kfree(carveout_heap); carveout_heap = NULL; } Loading
drivers/staging/android/ion/heaps/msm_ion.c +5 −1 Original line number Diff line number Diff line Loading @@ -78,7 +78,11 @@ static struct ion_heap_desc ion_heap_meta[] = { { .id = ION_SECURE_CARVEOUT_HEAP_ID, .name = ION_SECURE_CARVEOUT_HEAP_NAME, } }, { .id = ION_TUI_CARVEOUT_HEAP_ID, .name = ION_TUI_CARVEOUT_HEAP_NAME, }, }; #define MAKE_HEAP_TYPE_MAPPING(h) { .name = #h, \ Loading
drivers/staging/android/ion/heaps/msm_ion_priv.h +1 −0 Original line number Diff line number Diff line Loading @@ -38,6 +38,7 @@ #define ION_SECURE_HEAP_NAME "secure_heap" #define ION_SECURE_DISPLAY_HEAP_NAME "secure_display" #define ION_AUDIO_HEAP_NAME "audio" #define ION_TUI_CARVEOUT_HEAP_NAME "tui_carveout" /** * Debug feature. Make ION allocations DMA Loading
include/uapi/linux/msm_ion_ids.h +2 −1 Original line number Diff line number Diff line /* SPDX-License-Identifier: GPL-2.0-only WITH Linux-syscall-note */ /* * Copyright (c) 2019, The Linux Foundation. All rights reserved. * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved. */ #ifndef _MSM_ION_IDS_H #define _MSM_ION_IDS_H Loading @@ -17,6 +17,7 @@ */ #define ION_SYSTEM_HEAP_ID ION_BIT(0) #define ION_TUI_CARVEOUT_HEAP_ID ION_BIT(2) #define ION_QSECOM_TA_HEAP_ID ION_BIT(8) #define ION_CAMERA_HEAP_ID ION_BIT(9) #define ION_ADSP_HEAP_ID ION_BIT(11) Loading