Merge "msm: kgsl: Don't allow re-importing memory owned by KGSL"
This commit is contained in:
commit
abe544901b
@ -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;
|
||||
@ -2358,18 +2354,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;
|
||||
|
||||
@ -2420,7 +2414,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 New Issue
Block a user