Commit b308a7c5 authored by Rebecca Schultz Zavin's avatar Rebecca Schultz Zavin Committed by Greg Kroah-Hartman

gpu: ion: Fix bug in ion_system_heap map_user

When the requested mmap length was not an integer number of
chunks or the buffer, or if an offset was provided, a bug
would cause extra or incorrect pages of the buffer to be mapped.
Signed-off-by: default avatarRebecca Schultz Zavin <rebecca@android.com>
[jstultz: modified patch to apply to staging directory]
Signed-off-by: default avatarJohn Stultz <john.stultz@linaro.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 8fae8312
...@@ -292,18 +292,27 @@ int ion_system_heap_map_user(struct ion_heap *heap, struct ion_buffer *buffer, ...@@ -292,18 +292,27 @@ int ion_system_heap_map_user(struct ion_heap *heap, struct ion_buffer *buffer,
{ {
struct sg_table *table = buffer->priv_virt; struct sg_table *table = buffer->priv_virt;
unsigned long addr = vma->vm_start; unsigned long addr = vma->vm_start;
unsigned long offset = vma->vm_pgoff; unsigned long offset = vma->vm_pgoff * PAGE_SIZE;
struct scatterlist *sg; struct scatterlist *sg;
int i; int i;
for_each_sg(table->sgl, sg, table->nents, i) { for_each_sg(table->sgl, sg, table->nents, i) {
if (offset) { struct page *page = sg_page(sg);
offset--; unsigned long remainder = vma->vm_end - addr;
unsigned long len = sg_dma_len(sg);
if (offset >= sg_dma_len(sg)) {
offset -= sg_dma_len(sg);
continue; continue;
} else if (offset) {
page += offset / PAGE_SIZE;
len = sg_dma_len(sg) - offset;
offset = 0;
} }
remap_pfn_range(vma, addr, page_to_pfn(sg_page(sg)), len = min(len, remainder);
sg_dma_len(sg), vma->vm_page_prot); remap_pfn_range(vma, addr, page_to_pfn(page), len,
addr += sg_dma_len(sg); vma->vm_page_prot);
addr += len;
if (addr >= vma->vm_end) if (addr >= vma->vm_end)
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment