aboutsummaryrefslogtreecommitdiffstats
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 5ccf984f063a..528429252f0f 100644
--- a/drivers/gpu/drm/ast/ast_drv.h
+++ b/drivers/gpu/drm/ast/ast_drv.h
@@ -98,6 +98,8 @@ struct ast_private {
98 98
99 struct drm_gem_object *cursor_cache; 99 struct drm_gem_object *cursor_cache;
100 uint64_t cursor_cache_gpu_addr; 100 uint64_t cursor_cache_gpu_addr;
101 /* Acces to this cache is protected by the crtc->mutex of the only crtc
102 * we have. */
101 struct ttm_bo_kmap_obj cache_kmap; 103 struct ttm_bo_kmap_obj cache_kmap;
102 int next_cursor; 104 int next_cursor;
103}; 105};
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index b7c6168fae7e..58fa69e5ff4c 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,
2036 if (!req->flags || (~DRM_MODE_CURSOR_FLAGS & req->flags)) 2036 if (!req->flags || (~DRM_MODE_CURSOR_FLAGS & req->flags))
2037 return -EINVAL; 2037 return -EINVAL;
2038 2038
2039 drm_modeset_lock_all(dev);
2040 obj = drm_mode_object_find(dev, req->crtc_id, DRM_MODE_OBJECT_CRTC); 2039 obj = drm_mode_object_find(dev, req->crtc_id, DRM_MODE_OBJECT_CRTC);
2041 if (!obj) { 2040 if (!obj) {
2042 DRM_DEBUG_KMS("Unknown CRTC ID %d\n", req->crtc_id); 2041 DRM_DEBUG_KMS("Unknown CRTC ID %d\n", req->crtc_id);
@@ -2051,20 +2050,23 @@ int drm_mode_cursor_ioctl(struct drm_device *dev,
2051 goto out; 2050 goto out;
2052 } 2051 }
2053 /* Turns off the cursor if handle is 0 */ 2052 /* Turns off the cursor if handle is 0 */
2053 mutex_lock(&crtc->mutex);
2054 ret = crtc->funcs->cursor_set(crtc, file_priv, req->handle, 2054 ret = crtc->funcs->cursor_set(crtc, file_priv, req->handle,
2055 req->width, req->height); 2055 req->width, req->height);
2056 mutex_unlock(&crtc->mutex);
2056 } 2057 }
2057 2058
2058 if (req->flags & DRM_MODE_CURSOR_MOVE) { 2059 if (req->flags & DRM_MODE_CURSOR_MOVE) {
2059 if (crtc->funcs->cursor_move) { 2060 if (crtc->funcs->cursor_move) {
2061 drm_modeset_lock_all(dev);
2060 ret = crtc->funcs->cursor_move(crtc, req->x, req->y); 2062 ret = crtc->funcs->cursor_move(crtc, req->x, req->y);
2063 drm_modeset_unlock_all(dev);
2061 } else { 2064 } else {
2062 ret = -EFAULT; 2065 ret = -EFAULT;
2063 goto out; 2066 goto out;
2064 } 2067 }
2065 } 2068 }
2066out: 2069out:
2067 drm_modeset_unlock_all(dev);
2068 return ret; 2070 return ret;
2069} 2071}
2070 2072
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
index 9c0876b908ae..8d82e631c305 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,
180 struct vmw_dma_buffer *dmabuf = NULL; 180 struct vmw_dma_buffer *dmabuf = NULL;
181 int ret; 181 int ret;
182 182
183 /*
184 * FIXME: Unclear whether there's any global state touched by the
185 * cursor_set function, especially vmw_cursor_update_position looks
186 * suspicious. For now take the easy route and reacquire all locks. We
187 * can do this since the caller in the drm core doesn't check anything
188 * which is protected by any looks.
189 */
190 mutex_unlock(&crtc->mutex);
191 drm_modeset_lock_all(dev_priv->dev);
192
183 /* A lot of the code assumes this */ 193 /* A lot of the code assumes this */
184 if (handle && (width != 64 || height != 64)) 194 if (handle && (width != 64 || height != 64)) {
185 return -EINVAL; 195 ret = -EINVAL;
196 goto out;
197 }
186 198
187 if (handle) { 199 if (handle) {
188 ret = vmw_user_lookup_handle(dev_priv, tfile, 200 ret = vmw_user_lookup_handle(dev_priv, tfile,
189 handle, &surface, &dmabuf); 201 handle, &surface, &dmabuf);
190 if (ret) { 202 if (ret) {
191 DRM_ERROR("failed to find surface or dmabuf: %i\n", ret); 203 DRM_ERROR("failed to find surface or dmabuf: %i\n", ret);
192 return -EINVAL; 204 ret = -EINVAL;
205 goto out;
193 } 206 }
194 } 207 }
195 208
@@ -197,7 +210,8 @@ int vmw_du_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv,
197 if (surface && !surface->snooper.image) { 210 if (surface && !surface->snooper.image) {
198 DRM_ERROR("surface not suitable for cursor\n"); 211 DRM_ERROR("surface not suitable for cursor\n");
199 vmw_surface_unreference(&surface); 212 vmw_surface_unreference(&surface);
200 return -EINVAL; 213 ret = -EINVAL;
214 goto out;
201 } 215 }
202 216
203 /* takedown old cursor */ 217 /* takedown old cursor */
@@ -225,14 +239,20 @@ int vmw_du_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv,
225 du->hotspot_x, du->hotspot_y); 239 du->hotspot_x, du->hotspot_y);
226 } else { 240 } else {
227 vmw_cursor_update_position(dev_priv, false, 0, 0); 241 vmw_cursor_update_position(dev_priv, false, 0, 0);
228 return 0; 242 ret = 0;
243 goto out;
229 } 244 }
230 245
231 vmw_cursor_update_position(dev_priv, true, 246 vmw_cursor_update_position(dev_priv, true,
232 du->cursor_x + du->hotspot_x, 247 du->cursor_x + du->hotspot_x,
233 du->cursor_y + du->hotspot_y); 248 du->cursor_y + du->hotspot_y);
234 249
235 return 0; 250 ret = 0;
251out:
252 drm_modeset_unlock_all(dev_priv->dev);
253 mutex_lock(&crtc->mutex);
254
255 return ret;
236} 256}
237 257
238int vmw_du_crtc_cursor_move(struct drm_crtc *crtc, int x, int y) 258int vmw_du_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)