lists.openwall.net | lists / announce owl-users owl-dev john-users john-dev passwdqc-users yescrypt popa3d-users / oss-security kernel-hardening musl sabotage tlsify passwords / crypt-dev xvendor / Bugtraq Full-Disclosure linux-kernel linux-netdev linux-ext4 linux-hardening linux-cve-announce PHC | |
Open Source and information security mailing list archives
| ||
|
Date: Fri, 13 Dec 2013 19:26:27 -0800 From: John Stultz <john.stultz@...aro.org> To: LKML <linux-kernel@...r.kernel.org> Cc: Greg KH <gregkh@...uxfoundation.org>, Android Kernel Team <kernel-team@...roid.com>, Sumit Semwal <sumit.semwal@...aro.org>, Jesse Barker <jesse.barker@....com>, Colin Cross <ccross@...roid.com>, John Stultz <john.stultz@...aro.org> Subject: [PATCH 107/115] ion: use alloc_pages in system contig heap From: Colin Cross <ccross@...roid.com> There is no reason to use kzalloc, just call alloc_pages directly. Change the GFP from GFP_KERNEL to include __GFP_HIGH, to allow it to return contiguous pages from highmem. virt_to_* functions aren't valid on highmem pages, so store the struct page * in an sg_table in buffer->priv_virt like most other heaps, and replace virt_to_* with page_to_*. Signed-off-by: Colin Cross <ccross@...roid.com> Signed-off-by: John Stultz <john.stultz@...aro.org> --- drivers/staging/android/ion/ion_system_heap.c | 71 ++++++++++++++++++--------- 1 file changed, 48 insertions(+), 23 deletions(-) diff --git a/drivers/staging/android/ion/ion_system_heap.c b/drivers/staging/android/ion/ion_system_heap.c index 53afa33..841511d 100644 --- a/drivers/staging/android/ion/ion_system_heap.c +++ b/drivers/staging/android/ion/ion_system_heap.c @@ -360,29 +360,69 @@ static int ion_system_contig_heap_allocate(struct ion_heap *heap, unsigned long flags) { int order = get_order(len); + struct page *page; + struct sg_table *table; + unsigned long i; + int ret; if (align > (PAGE_SIZE << order)) return -EINVAL; - if (ion_buffer_fault_user_mappings(buffer)) - return -EINVAL; - - buffer->priv_virt = kzalloc(len, GFP_KERNEL); - if (!buffer->priv_virt) + page = alloc_pages(low_order_gfp_flags, order); + if (!page) return -ENOMEM; + + split_page(page, order); + + len = PAGE_ALIGN(len); + for (i = len >> PAGE_SHIFT; i < (1 << order); i++) + __free_page(page + i); + + table = kzalloc(sizeof(struct sg_table), GFP_KERNEL); + if (!table) { + ret = -ENOMEM; + goto out; + } + + ret = sg_alloc_table(table, 1, GFP_KERNEL); + if (ret) + goto out; + + sg_set_page(table->sgl, page, len, 0); + + buffer->priv_virt = table; + + ion_pages_sync_for_device(NULL, page, len, DMA_BIDIRECTIONAL); + return 0; + +out: + for (i = 0; i < len >> PAGE_SHIFT; i++) + __free_page(page + i); + kfree(table); + return ret; } void ion_system_contig_heap_free(struct ion_buffer *buffer) { - kfree(buffer->priv_virt); + struct sg_table *table = buffer->priv_virt; + struct page *page = sg_page(table->sgl); + unsigned long pages = PAGE_ALIGN(buffer->size) >> PAGE_SHIFT; + unsigned long i; + + for (i = 0; i < pages; i++) + __free_page(page + i); + sg_free_table(table); + kfree(table); } static int ion_system_contig_heap_phys(struct ion_heap *heap, struct ion_buffer *buffer, ion_phys_addr_t *addr, size_t *len) { - *addr = virt_to_phys(buffer->priv_virt); + struct sg_table *table = buffer->priv_virt; + struct page *page = sg_page(table->sgl); + *addr = page_to_phys(page); *len = buffer->size; return 0; } @@ -390,27 +430,12 @@ static int ion_system_contig_heap_phys(struct ion_heap *heap, struct sg_table *ion_system_contig_heap_map_dma(struct ion_heap *heap, struct ion_buffer *buffer) { - struct sg_table *table; - int ret; - - table = kzalloc(sizeof(struct sg_table), GFP_KERNEL); - if (!table) - return ERR_PTR(-ENOMEM); - ret = sg_alloc_table(table, 1, GFP_KERNEL); - if (ret) { - kfree(table); - return ERR_PTR(ret); - } - sg_set_page(table->sgl, virt_to_page(buffer->priv_virt), buffer->size, - 0); - return table; + return buffer->priv_virt; } void ion_system_contig_heap_unmap_dma(struct ion_heap *heap, struct ion_buffer *buffer) { - sg_free_table(buffer->sg_table); - kfree(buffer->sg_table); } static struct ion_heap_ops kmalloc_ops = { -- 1.8.3.2 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@...r.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Powered by blists - more mailing lists