drm/omap: gem: Fix omap_gem_new() error path

When an error occurs in omap_gem_new() the function calls
omap_gem_free_object() to clean up. However, that function expects to be
called on a fully initialized GEM object and thus crashes.

Replace it by manual cleanup.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
This commit is contained in:
Laurent Pinchart 2016-03-02 12:51:19 +02:00 committed by Tomi Valkeinen
parent 39cd66209d
commit c2eb77ff71
1 changed files with 19 additions and 17 deletions

View File

@ -1398,9 +1398,17 @@ struct drm_gem_object *omap_gem_new(struct drm_device *dev,
size = PAGE_ALIGN(gsize.bytes); size = PAGE_ALIGN(gsize.bytes);
} }
spin_lock(&priv->list_lock); /* Initialize the GEM object. */
list_add(&omap_obj->mm_list, &priv->obj_list); if (!(flags & OMAP_BO_MEM_SHMEM)) {
spin_unlock(&priv->list_lock); drm_gem_private_object_init(dev, obj, size);
} else {
ret = drm_gem_object_init(dev, obj, size);
if (ret)
goto err_free;
mapping = file_inode(obj->filp)->i_mapping;
mapping_set_gfp_mask(mapping, GFP_USER | __GFP_DMA32);
}
/* Allocate memory if needed. */ /* Allocate memory if needed. */
if (flags & OMAP_BO_MEM_DMA_API) { if (flags & OMAP_BO_MEM_DMA_API) {
@ -1408,25 +1416,19 @@ struct drm_gem_object *omap_gem_new(struct drm_device *dev,
&omap_obj->paddr, &omap_obj->paddr,
GFP_KERNEL); GFP_KERNEL);
if (!omap_obj->vaddr) if (!omap_obj->vaddr)
goto fail; goto err_release;
} }
/* Initialize the GEM object. */ spin_lock(&priv->list_lock);
if (!(flags & OMAP_BO_MEM_SHMEM)) { list_add(&omap_obj->mm_list, &priv->obj_list);
drm_gem_private_object_init(dev, obj, size); spin_unlock(&priv->list_lock);
} else {
ret = drm_gem_object_init(dev, obj, size);
if (ret)
goto fail;
mapping = file_inode(obj->filp)->i_mapping;
mapping_set_gfp_mask(mapping, GFP_USER | __GFP_DMA32);
}
return obj; return obj;
fail: err_release:
omap_gem_free_object(obj); drm_gem_object_release(obj);
err_free:
kfree(omap_obj);
return NULL; return NULL;
} }