aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/intel_display.c
diff options
context:
space:
mode:
authorDaniel Vetter <daniel.vetter@ffwll.ch>2014-02-10 12:00:39 -0500
committerDaniel Vetter <daniel.vetter@ffwll.ch>2014-02-12 12:53:02 -0500
commita8bb6818270c32126dba0fd2ddb139d885c5687d (patch)
tree56f0b21a168e442a3000cb517a93b84dba7ceacf /drivers/gpu/drm/i915/intel_display.c
parentef2d633e9bcfdb73e536ca81b835dd015fe24ceb (diff)
drm/i915: Fix error path leak in fbdev fb allocation
In Jesse's patch to switch the fbdev framebuffer from an embedded struct to a pointer the kfree in case of an error was missed. Fix this up by using our own internal fb allocation helper directly instead of reinventing that wheel. We need a to_intel_framebuffer cast unfortunately since all the other callers of _create still look better whith using a drm_framebuffer as return pointer. v2: Add an unlocked __intel_framebuffer_create function since our dev->struct_mutex locking is too much a mess. With ppgtt we even need it to take a look at the global gtt offset of pinned objects, since the vma list might chance from underneath us. At least with the current global gtt lookup functions. Reported by Mika. Cc: Mika Kuoppala <mika.kuoppala@linux.intel.com> Cc: Jesse Barnes <jbarnes@virtuousgeek.org> Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/gpu/drm/i915/intel_display.c')
-rw-r--r--drivers/gpu/drm/i915/intel_display.c35
1 files changed, 26 insertions, 9 deletions
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 6600931f213c..6ac4c23acc77 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -7690,10 +7690,15 @@ static struct drm_display_mode load_detect_mode = {
7690 704, 832, 0, 480, 489, 491, 520, 0, DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC), 7690 704, 832, 0, 480, 489, 491, 520, 0, DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
7691}; 7691};
7692 7692
7693static struct drm_framebuffer * 7693static int intel_framebuffer_init(struct drm_device *dev,
7694intel_framebuffer_create(struct drm_device *dev, 7694 struct intel_framebuffer *ifb,
7695 struct drm_mode_fb_cmd2 *mode_cmd, 7695 struct drm_mode_fb_cmd2 *mode_cmd,
7696 struct drm_i915_gem_object *obj) 7696 struct drm_i915_gem_object *obj);
7697
7698struct drm_framebuffer *
7699__intel_framebuffer_create(struct drm_device *dev,
7700 struct drm_mode_fb_cmd2 *mode_cmd,
7701 struct drm_i915_gem_object *obj)
7697{ 7702{
7698 struct intel_framebuffer *intel_fb; 7703 struct intel_framebuffer *intel_fb;
7699 int ret; 7704 int ret;
@@ -7704,12 +7709,7 @@ intel_framebuffer_create(struct drm_device *dev,
7704 return ERR_PTR(-ENOMEM); 7709 return ERR_PTR(-ENOMEM);
7705 } 7710 }
7706 7711
7707 ret = i915_mutex_lock_interruptible(dev);
7708 if (ret)
7709 goto err;
7710
7711 ret = intel_framebuffer_init(dev, intel_fb, mode_cmd, obj); 7712 ret = intel_framebuffer_init(dev, intel_fb, mode_cmd, obj);
7712 mutex_unlock(&dev->struct_mutex);
7713 if (ret) 7713 if (ret)
7714 goto err; 7714 goto err;
7715 7715
@@ -7721,6 +7721,23 @@ err:
7721 return ERR_PTR(ret); 7721 return ERR_PTR(ret);
7722} 7722}
7723 7723
7724struct drm_framebuffer *
7725intel_framebuffer_create(struct drm_device *dev,
7726 struct drm_mode_fb_cmd2 *mode_cmd,
7727 struct drm_i915_gem_object *obj)
7728{
7729 struct drm_framebuffer *fb;
7730 int ret;
7731
7732 ret = i915_mutex_lock_interruptible(dev);
7733 if (ret)
7734 return ERR_PTR(ret);
7735 fb = __intel_framebuffer_create(dev, mode_cmd, obj);
7736 mutex_unlock(&dev->struct_mutex);
7737
7738 return fb;
7739}
7740
7724static u32 7741static u32
7725intel_framebuffer_pitch_for_width(int width, int bpp) 7742intel_framebuffer_pitch_for_width(int width, int bpp)
7726{ 7743{