From c2eb77ff717c3aa403f5807425a7f2b2cb67b6b3 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Wed, 2 Mar 2016 12:51:19 +0200 Subject: [PATCH] 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 Signed-off-by: Tomi Valkeinen --- drivers/gpu/drm/omapdrm/omap_gem.c | 36 ++++++++++++++++-------------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/drivers/gpu/drm/omapdrm/omap_gem.c b/drivers/gpu/drm/omapdrm/omap_gem.c index 9ac30560e9b1..cc36a8dc9bd4 100644 --- a/drivers/gpu/drm/omapdrm/omap_gem.c +++ b/drivers/gpu/drm/omapdrm/omap_gem.c @@ -1398,9 +1398,17 @@ struct drm_gem_object *omap_gem_new(struct drm_device *dev, size = PAGE_ALIGN(gsize.bytes); } - spin_lock(&priv->list_lock); - list_add(&omap_obj->mm_list, &priv->obj_list); - spin_unlock(&priv->list_lock); + /* Initialize the GEM object. */ + if (!(flags & OMAP_BO_MEM_SHMEM)) { + 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. */ 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, GFP_KERNEL); if (!omap_obj->vaddr) - goto fail; + goto err_release; } - /* Initialize the GEM object. */ - if (!(flags & OMAP_BO_MEM_SHMEM)) { - drm_gem_private_object_init(dev, obj, size); - } 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); - } + spin_lock(&priv->list_lock); + list_add(&omap_obj->mm_list, &priv->obj_list); + spin_unlock(&priv->list_lock); return obj; -fail: - omap_gem_free_object(obj); +err_release: + drm_gem_object_release(obj); +err_free: + kfree(omap_obj); return NULL; }