diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 114a7a1a8740096217b62d5fc108210c3cc8f44d..31c3732b7a690aa7d813f4ecad46a071a7ef684f 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -1016,8 +1016,8 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc,
 
 	if (bo->size < width * height * 4) {
 		DRM_ERROR("buffer is to small\n");
-		drm_gem_object_unreference(bo);
-		return -ENOMEM;
+		ret = -ENOMEM;
+		goto fail;
 	}
 
 	/* we only need to pin inside GTT if cursor is non-phy */
@@ -1025,16 +1025,14 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc,
 		ret = i915_gem_object_pin(bo, PAGE_SIZE);
 		if (ret) {
 			DRM_ERROR("failed to pin cursor bo\n");
-			drm_gem_object_unreference(bo);
-			return ret;
+			goto fail;
 		}
 		addr = obj_priv->gtt_offset;
 	} else {
 		ret = i915_gem_attach_phys_object(dev, bo, (pipe == 0) ? I915_GEM_PHYS_CURSOR_0 : I915_GEM_PHYS_CURSOR_1);
 		if (ret) {
 			DRM_ERROR("failed to attach phys object\n");
-			drm_gem_object_unreference(bo);
-			return ret;
+			goto fail;
 		}
 		addr = obj_priv->phys_obj->handle->busaddr;
 	}
@@ -1054,13 +1052,20 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc,
 				i915_gem_detach_phys_object(dev, intel_crtc->cursor_bo);
 		} else
 			i915_gem_object_unpin(intel_crtc->cursor_bo);
+		mutex_lock(&dev->struct_mutex);
 		drm_gem_object_unreference(intel_crtc->cursor_bo);
+		mutex_unlock(&dev->struct_mutex);
 	}
 
 	intel_crtc->cursor_addr = addr;
 	intel_crtc->cursor_bo = bo;
 
 	return 0;
+fail:
+	mutex_lock(&dev->struct_mutex);
+	drm_gem_object_unreference(bo);
+	mutex_unlock(&dev->struct_mutex);
+	return ret;
 }
 
 static int intel_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)