msm: kgsl: prevent multiple or partial mmaps of a buffer
These cases have never been a normal operation pattern of the
userspace driver. Sharing buffers through multiple mappings
is better left to dma-buf or ion.
Change-Id: I7e7658137937c96b9505d0f912dcb262d652e0c3
Signed-off-by: Jeremy Gebben <jgebben@codeaurora.org>
diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c
index be454a6..65eed58 100644
--- a/drivers/gpu/msm/kgsl.c
+++ b/drivers/gpu/msm/kgsl.c
@@ -2099,6 +2099,8 @@
kgsl_gpumem_vm_close(struct vm_area_struct *vma)
{
struct kgsl_mem_entry *entry = vma->vm_private_data;
+
+ entry->memdesc.useraddr = 0;
kgsl_mem_entry_put(entry);
}
@@ -2110,6 +2112,7 @@
static int kgsl_mmap(struct file *file, struct vm_area_struct *vma)
{
+ unsigned int ret;
unsigned long vma_offset = vma->vm_pgoff << PAGE_SHIFT;
struct kgsl_device_private *dev_priv = file->private_data;
struct kgsl_process_private *private = dev_priv->process_priv;
@@ -2136,8 +2139,20 @@
if (!entry->memdesc.ops ||
!entry->memdesc.ops->vmflags ||
- !entry->memdesc.ops->vmfault)
- return -EINVAL;
+ !entry->memdesc.ops->vmfault) {
+ ret = -EINVAL;
+ goto err_put;
+ }
+
+ if (entry->memdesc.useraddr != 0) {
+ ret = -EBUSY;
+ goto err_put;
+ }
+
+ if (entry->memdesc.size != (vma->vm_end - vma->vm_start)) {
+ ret = -ERANGE;
+ goto err_put;
+ }
vma->vm_flags |= entry->memdesc.ops->vmflags(&entry->memdesc);
@@ -2146,7 +2161,12 @@
vma->vm_ops = &kgsl_gpumem_vm_ops;
vma->vm_file = file;
+ entry->memdesc.useraddr = vma->vm_start;
+
return 0;
+err_put:
+ kgsl_mem_entry_put(entry);
+ return ret;
}
static irqreturn_t kgsl_irq_handler(int irq, void *data)