mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-25 14:13:01 -04:00
msm: kgsl: Don't allow re-importing memory owned by KGSL
Don't allow IOCTL_KGSL_MAP_USER_MEM to import user memory that was already allocated and mapped by KGSL in the first place. Remapping memory never makes sense and it messes up reference counting in the pools. Change-Id: Ic0dedbade96ac6b30dcbbb794bf57a597f1bb351 Signed-off-by: Jordan Crouse <jcrouse@codeaurora.org>
This commit is contained in:
parent
8f4bf966d4
commit
c1e3429092
1 changed files with 25 additions and 31 deletions
|
|
@ -2296,14 +2296,6 @@ long kgsl_ioctl_cmdstream_freememontimestamp_ctxtid(
|
|||
return ret;
|
||||
}
|
||||
|
||||
static inline int _check_region(unsigned long start, unsigned long size,
|
||||
uint64_t len)
|
||||
{
|
||||
uint64_t end = ((uint64_t) start) + size;
|
||||
|
||||
return (end > len);
|
||||
}
|
||||
|
||||
static int check_vma_flags(struct vm_area_struct *vma,
|
||||
unsigned int flags)
|
||||
{
|
||||
|
|
@ -2318,23 +2310,27 @@ static int check_vma_flags(struct vm_area_struct *vma,
|
|||
return -EFAULT;
|
||||
}
|
||||
|
||||
static int check_vma(struct vm_area_struct *vma, struct file *vmfile,
|
||||
struct kgsl_memdesc *memdesc)
|
||||
static int check_vma(unsigned long hostptr, u64 size)
|
||||
{
|
||||
if (vma == NULL || vma->vm_file != vmfile)
|
||||
return -EINVAL;
|
||||
struct vm_area_struct *vma;
|
||||
unsigned long cur = hostptr;
|
||||
|
||||
/* userspace may not know the size, in which case use the whole vma */
|
||||
if (memdesc->size == 0)
|
||||
memdesc->size = vma->vm_end - vma->vm_start;
|
||||
/* range checking */
|
||||
if (vma->vm_start != memdesc->useraddr ||
|
||||
(memdesc->useraddr + memdesc->size) != vma->vm_end)
|
||||
return -EINVAL;
|
||||
return check_vma_flags(vma, memdesc->flags);
|
||||
while (cur < (hostptr + size)) {
|
||||
vma = find_vma(current->mm, cur);
|
||||
if (!vma)
|
||||
return false;
|
||||
|
||||
/* Don't remap memory that we already own */
|
||||
if (vma->vm_file && vma->vm_file->f_op == &kgsl_fops)
|
||||
return false;
|
||||
|
||||
cur = vma->vm_end;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static int memdesc_sg_virt(struct kgsl_memdesc *memdesc, struct file *vmfile)
|
||||
static int memdesc_sg_virt(struct kgsl_memdesc *memdesc)
|
||||
{
|
||||
int ret = 0;
|
||||
long npages = 0, i;
|
||||
|
|
@ -2357,18 +2353,16 @@ static int memdesc_sg_virt(struct kgsl_memdesc *memdesc, struct file *vmfile)
|
|||
}
|
||||
|
||||
down_read(¤t->mm->mmap_sem);
|
||||
/* If we have vmfile, make sure we map the correct vma and map it all */
|
||||
if (vmfile != NULL)
|
||||
ret = check_vma(find_vma(current->mm, memdesc->useraddr),
|
||||
vmfile, memdesc);
|
||||
|
||||
if (ret == 0) {
|
||||
npages = get_user_pages(memdesc->useraddr,
|
||||
sglen, write, pages, NULL);
|
||||
ret = (npages < 0) ? (int)npages : 0;
|
||||
if (!check_vma(memdesc->useraddr, memdesc->size)) {
|
||||
up_read(¤t->mm->mmap_sem);
|
||||
ret = -EFAULT;
|
||||
goto out;
|
||||
}
|
||||
|
||||
npages = get_user_pages(memdesc->useraddr, sglen, write, pages, NULL);
|
||||
up_read(¤t->mm->mmap_sem);
|
||||
|
||||
ret = (npages < 0) ? (int)npages : 0;
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
|
|
@ -2419,7 +2413,7 @@ static int kgsl_setup_anon_useraddr(struct kgsl_pagetable *pagetable,
|
|||
entry->memdesc.gpuaddr = (uint64_t) entry->memdesc.useraddr;
|
||||
}
|
||||
|
||||
return memdesc_sg_virt(&entry->memdesc, NULL);
|
||||
return memdesc_sg_virt(&entry->memdesc);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_DMA_SHARED_BUFFER
|
||||
|
|
|
|||
Loading…
Reference in a new issue