diff --git a/drivers/gpu/drm/i915/intel_fbdev.c b/drivers/gpu/drm/i915/intel_fbdev.c index 7ccde58f8c98..bea75cafc623 100644 --- a/drivers/gpu/drm/i915/intel_fbdev.c +++ b/drivers/gpu/drm/i915/intel_fbdev.c @@ -163,13 +163,6 @@ static int intelfb_alloc(struct drm_fb_helper *helper, goto out; } - /* Flush everything out, we'll be doing GTT only from now on */ - ret = intel_pin_and_fence_fb_obj(NULL, fb, NULL); - if (ret) { - DRM_ERROR("failed to pin obj: %d\n", ret); - goto out; - } - mutex_unlock(&dev->struct_mutex); ifbdev->fb = to_intel_framebuffer(fb); @@ -225,6 +218,14 @@ static int intelfb_create(struct drm_fb_helper *helper, mutex_lock(&dev->struct_mutex); + /* Pin the GGTT vma for our access via info->screen_base. + * This also validates that any existing fb inherited from the + * BIOS is suitable for own access. + */ + ret = intel_pin_and_fence_fb_obj(NULL, &ifbdev->fb->base, NULL); + if (ret) + goto out_unlock; + info = drm_fb_helper_alloc_fbi(helper); if (IS_ERR(info)) { DRM_ERROR("Failed to allocate fb_info\n"); @@ -287,6 +288,7 @@ out_destroy_fbi: drm_fb_helper_release_fbi(helper); out_unpin: i915_gem_object_ggtt_unpin(obj); +out_unlock: mutex_unlock(&dev->struct_mutex); return ret; } @@ -524,6 +526,10 @@ static const struct drm_fb_helper_funcs intel_fb_helper_funcs = { static void intel_fbdev_destroy(struct drm_device *dev, struct intel_fbdev *ifbdev) { + /* We rely on the object-free to release the VMA pinning for + * the info->screen_base mmaping. Leaking the VMA is simpler than + * trying to rectify all the possible error paths leading here. + */ drm_fb_helper_unregister_fbi(&ifbdev->helper); drm_fb_helper_release_fbi(&ifbdev->helper);