Skip to content

Commit

Permalink
drm/i915/fbdev: Check for the framebuffer before use
Browse files Browse the repository at this point in the history
If the fbdev probing fails, and in our error path we fail to clear the
dev_priv->fbdev, then we can try and use a dangling fbdev pointer, and
in particular a NULL fb. This could also happen in pathological cases
where we try to operate on the fbdev prior to it being probed.

Reported-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
Cc: Mika Kuoppala <mika.kuoppala@intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/1468431285-28264-2-git-send-email-chris@chris-wilson.co.uk
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Reviewed-by: Mika Kuoppala <mika.kuoppala@intel.com>
(cherry picked from commit 6bc2654)
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
  • Loading branch information
Chris Wilson authored and Jani Nikula committed Aug 4, 2016
1 parent a7b4667 commit c45eb4f
Showing 1 changed file with 11 additions and 14 deletions.
25 changes: 11 additions & 14 deletions drivers/gpu/drm/i915/intel_fbdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -782,7 +782,7 @@ void intel_fbdev_set_suspend(struct drm_device *dev, int state, bool synchronous
struct intel_fbdev *ifbdev = dev_priv->fbdev;
struct fb_info *info;

if (!ifbdev)
if (!ifbdev || !ifbdev->fb)
return;

info = ifbdev->helper.fbdev;
Expand Down Expand Up @@ -827,31 +827,28 @@ void intel_fbdev_set_suspend(struct drm_device *dev, int state, bool synchronous

void intel_fbdev_output_poll_changed(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = to_i915(dev);
if (dev_priv->fbdev)
drm_fb_helper_hotplug_event(&dev_priv->fbdev->helper);
struct intel_fbdev *ifbdev = to_i915(dev)->fbdev;

if (ifbdev && ifbdev->fb)
drm_fb_helper_hotplug_event(&ifbdev->helper);
}

void intel_fbdev_restore_mode(struct drm_device *dev)
{
int ret;
struct drm_i915_private *dev_priv = to_i915(dev);
struct intel_fbdev *ifbdev = dev_priv->fbdev;
struct drm_fb_helper *fb_helper;
struct intel_fbdev *ifbdev = to_i915(dev)->fbdev;

if (!ifbdev)
return;

intel_fbdev_sync(ifbdev);
if (!ifbdev->fb)
return;

fb_helper = &ifbdev->helper;

ret = drm_fb_helper_restore_fbdev_mode_unlocked(fb_helper);
if (ret) {
if (drm_fb_helper_restore_fbdev_mode_unlocked(&ifbdev->helper)) {
DRM_DEBUG("failed to restore crtc mode\n");
} else {
mutex_lock(&fb_helper->dev->struct_mutex);
mutex_lock(&dev->struct_mutex);
intel_fb_obj_invalidate(ifbdev->fb->obj, ORIGIN_GTT);
mutex_unlock(&fb_helper->dev->struct_mutex);
mutex_unlock(&dev->struct_mutex);
}
}

0 comments on commit c45eb4f

Please sign in to comment.