OSDN Git Service

Merge tag 'drm-misc-next-2019-12-16' of git://anongit.freedesktop.org/drm/drm-misc...
[uclinux-h8/linux.git] / drivers / gpu / drm / drm_gem.c
index 56f42e0..a9e4a61 100644 (file)
@@ -1105,18 +1105,30 @@ int drm_gem_mmap_obj(struct drm_gem_object *obj, unsigned long obj_size,
        if (obj_size < vma->vm_end - vma->vm_start)
                return -EINVAL;
 
+       /* Take a ref for this mapping of the object, so that the fault
+        * handler can dereference the mmap offset's pointer to the object.
+        * This reference is cleaned up by the corresponding vm_close
+        * (which should happen whether the vma was created by this call, or
+        * by a vm_open due to mremap or partial unmap or whatever).
+        */
+       drm_gem_object_get(obj);
+
        if (obj->funcs && obj->funcs->mmap) {
                ret = obj->funcs->mmap(obj, vma);
-               if (ret)
+               if (ret) {
+                       drm_gem_object_put_unlocked(obj);
                        return ret;
+               }
                WARN_ON(!(vma->vm_flags & VM_DONTEXPAND));
        } else {
                if (obj->funcs && obj->funcs->vm_ops)
                        vma->vm_ops = obj->funcs->vm_ops;
                else if (dev->driver->gem_vm_ops)
                        vma->vm_ops = dev->driver->gem_vm_ops;
-               else
+               else {
+                       drm_gem_object_put_unlocked(obj);
                        return -EINVAL;
+               }
 
                vma->vm_flags |= VM_IO | VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP;
                vma->vm_page_prot = pgprot_writecombine(vm_get_page_prot(vma->vm_flags));
@@ -1125,14 +1137,6 @@ int drm_gem_mmap_obj(struct drm_gem_object *obj, unsigned long obj_size,
 
        vma->vm_private_data = obj;
 
-       /* Take a ref for this mapping of the object, so that the fault
-        * handler can dereference the mmap offset's pointer to the object.
-        * This reference is cleaned up by the corresponding vm_close
-        * (which should happen whether the vma was created by this call, or
-        * by a vm_open due to mremap or partial unmap or whatever).
-        */
-       drm_gem_object_get(obj);
-
        return 0;
 }
 EXPORT_SYMBOL(drm_gem_mmap_obj);