--- file_not_specified_in_diff +++ file_not_specified_in_diff @@ -, +, @@ --- drivers/gpu/drm/i915/intel_fbdev.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) --- 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_h goto out; } - /* Flush everything out, we'll be doing GTT only from now on */ - ret = intel_pin_and_fence_fb_obj(NULL, fb, NULL, NULL, 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_ 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, NULL, NULL); + if (ret) + goto out_unlock; + info = drm_fb_helper_alloc_fbi(helper); if (IS_ERR(info)) { ret = PTR_ERR(info); @@ -286,6 +287,7 @@ out_destroy_fbi: out_unpin: i915_gem_object_ggtt_unpin(obj); drm_gem_object_unreference(&obj->base); +out_unlock: mutex_unlock(&dev->struct_mutex); return ret; } @@ -523,6 +525,10 @@ static const struct drm_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);