diff options
-rw-r--r-- | drivers/gpu/drm/ast/ast_drv.h | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/drm_crtc.c | 6 | ||||
-rw-r--r-- | drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | 32 |
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 | } |
2066 | out: | 2069 | out: |
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; |
251 | out: | ||
252 | drm_modeset_unlock_all(dev_priv->dev); | ||
253 | mutex_lock(&crtc->mutex); | ||
254 | |||
255 | return ret; | ||
236 | } | 256 | } |
237 | 257 | ||
238 | int vmw_du_crtc_cursor_move(struct drm_crtc *crtc, int x, int y) | 258 | int vmw_du_crtc_cursor_move(struct drm_crtc *crtc, int x, int y) |