Skip to content

Commit 6bc2654

Browse files
committed
drm/i915/fbdev: Check for the framebuffer before use
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>
1 parent 0b8c0e9 commit 6bc2654

File tree

1 file changed

+11
-14
lines changed

1 file changed

+11
-14
lines changed

drivers/gpu/drm/i915/intel_fbdev.c

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -782,7 +782,7 @@ void intel_fbdev_set_suspend(struct drm_device *dev, int state, bool synchronous
782782
struct intel_fbdev *ifbdev = dev_priv->fbdev;
783783
struct fb_info *info;
784784

785-
if (!ifbdev)
785+
if (!ifbdev || !ifbdev->fb)
786786
return;
787787

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

828828
void intel_fbdev_output_poll_changed(struct drm_device *dev)
829829
{
830-
struct drm_i915_private *dev_priv = to_i915(dev);
831-
if (dev_priv->fbdev)
832-
drm_fb_helper_hotplug_event(&dev_priv->fbdev->helper);
830+
struct intel_fbdev *ifbdev = to_i915(dev)->fbdev;
831+
832+
if (ifbdev && ifbdev->fb)
833+
drm_fb_helper_hotplug_event(&ifbdev->helper);
833834
}
834835

835836
void intel_fbdev_restore_mode(struct drm_device *dev)
836837
{
837-
int ret;
838-
struct drm_i915_private *dev_priv = to_i915(dev);
839-
struct intel_fbdev *ifbdev = dev_priv->fbdev;
840-
struct drm_fb_helper *fb_helper;
838+
struct intel_fbdev *ifbdev = to_i915(dev)->fbdev;
841839

842840
if (!ifbdev)
843841
return;
844842

845843
intel_fbdev_sync(ifbdev);
844+
if (!ifbdev->fb)
845+
return;
846846

847-
fb_helper = &ifbdev->helper;
848-
849-
ret = drm_fb_helper_restore_fbdev_mode_unlocked(fb_helper);
850-
if (ret) {
847+
if (drm_fb_helper_restore_fbdev_mode_unlocked(&ifbdev->helper)) {
851848
DRM_DEBUG("failed to restore crtc mode\n");
852849
} else {
853-
mutex_lock(&fb_helper->dev->struct_mutex);
850+
mutex_lock(&dev->struct_mutex);
854851
intel_fb_obj_invalidate(ifbdev->fb->obj, ORIGIN_GTT);
855-
mutex_unlock(&fb_helper->dev->struct_mutex);
852+
mutex_unlock(&dev->struct_mutex);
856853
}
857854
}

0 commit comments

Comments
 (0)