summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/ast/ast_drv.h2
-rw-r--r--drivers/gpu/drm/drm_crtc.c6
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_kms.c32
3 files changed, 32 insertions, 8 deletions
diff --git a/drivers/gpu/drm/ast/ast_drv.h b/drivers/gpu/drm/ast/ast_drv.h
index 5ccf984f063..528429252f0 100644
--- a/drivers/gpu/drm/ast/ast_drv.h
+++ b/drivers/gpu/drm/ast/ast_drv.h
@@ -98,6 +98,8 @@ struct ast_private {
struct drm_gem_object *cursor_cache;
uint64_t cursor_cache_gpu_addr;
+ /* Acces to this cache is protected by the crtc->mutex of the only crtc
+ * we have. */
struct ttm_bo_kmap_obj cache_kmap;
int next_cursor;
};
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index b7c6168fae7..58fa69e5ff4 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -2036,7 +2036,6 @@ int drm_mode_cursor_ioctl(struct drm_device *dev,
if (!req->flags || (~DRM_MODE_CURSOR_FLAGS & req->flags))
return -EINVAL;
- drm_modeset_lock_all(dev);
obj = drm_mode_object_find(dev, req->crtc_id, DRM_MODE_OBJECT_CRTC);
if (!obj) {
DRM_DEBUG_KMS("Unknown CRTC ID %d\n", req->crtc_id);
@@ -2051,20 +2050,23 @@ int drm_mode_cursor_ioctl(struct drm_device *dev,
goto out;
}
/* Turns off the cursor if handle is 0 */
+ mutex_lock(&crtc->mutex);
ret = crtc->funcs->cursor_set(crtc, file_priv, req->handle,
req->width, req->height);
+ mutex_unlock(&crtc->mutex);
}
if (req->flags & DRM_MODE_CURSOR_MOVE) {
if (crtc->funcs->cursor_move) {
+ drm_modeset_lock_all(dev);
ret = crtc->funcs->cursor_move(crtc, req->x, req->y);
+ drm_modeset_unlock_all(dev);
} else {
ret = -EFAULT;
goto out;
}
}
out:
- drm_modeset_unlock_all(dev);
return ret;
}
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
index 9c0876b908a..8d82e631c30 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
@@ -180,16 +180,29 @@ int vmw_du_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv,
struct vmw_dma_buffer *dmabuf = NULL;
int ret;
+ /*
+ * FIXME: Unclear whether there's any global state touched by the
+ * cursor_set function, especially vmw_cursor_update_position looks
+ * suspicious. For now take the easy route and reacquire all locks. We
+ * can do this since the caller in the drm core doesn't check anything
+ * which is protected by any looks.
+ */
+ mutex_unlock(&crtc->mutex);
+ drm_modeset_lock_all(dev_priv->dev);
+
/* A lot of the code assumes this */
- if (handle && (width != 64 || height != 64))
- return -EINVAL;
+ if (handle && (width != 64 || height != 64)) {
+ ret = -EINVAL;
+ goto out;
+ }
if (handle) {
ret = vmw_user_lookup_handle(dev_priv, tfile,
handle, &surface, &dmabuf);
if (ret) {
DRM_ERROR("failed to find surface or dmabuf: %i\n", ret);
- return -EINVAL;
+ ret = -EINVAL;
+ goto out;
}
}
@@ -197,7 +210,8 @@ int vmw_du_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv,
if (surface && !surface->snooper.image) {
DRM_ERROR("surface not suitable for cursor\n");
vmw_surface_unreference(&surface);
- return -EINVAL;
+ ret = -EINVAL;
+ goto out;
}
/* takedown old cursor */
@@ -225,14 +239,20 @@ int vmw_du_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv,
du->hotspot_x, du->hotspot_y);
} else {
vmw_cursor_update_position(dev_priv, false, 0, 0);
- return 0;
+ ret = 0;
+ goto out;
}
vmw_cursor_update_position(dev_priv, true,
du->cursor_x + du->hotspot_x,
du->cursor_y + du->hotspot_y);
- return 0;
+ ret = 0;
+out:
+ drm_modeset_unlock_all(dev_priv->dev);
+ mutex_lock(&crtc->mutex);
+
+ return ret;
}
int vmw_du_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)