diff options
author | Daniel Vetter <daniel.vetter@ffwll.ch> | 2018-11-05 05:12:11 -0500 |
---|---|---|
committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2018-11-06 12:23:31 -0500 |
commit | 968029057192e46dd78e807b81c2aba2d7648c38 (patch) | |
tree | 4684107a3ebcb451fdbaf40c94d658d2f09bbc0b /drivers/gpu/drm | |
parent | 078b7de41249b989a574339078696663e095cf37 (diff) |
drm/lease: look at ->universal_planes only once
It's lockless, and userspace might chance it underneath us. That's not
really a problem, all userspace gets is a slightly dysfunctional
lease with the current code. But this might change, and gcc might
decide to reload a few too many times, and then boom. So better safe
than sorry.
v2: Remove the now unused lessor_priv argument from validate_lease()
(Keith).
v3: Actually add everything ... silly me.
Cc: Keith Packard <keithp@keithp.com>
Cc: Dave Airlie <airlied@gmail.com>
Acked-by: Keith Packard <keithp@keithp.com>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20181105101211.22737-1-daniel.vetter@ffwll.ch
Diffstat (limited to 'drivers/gpu/drm')
-rw-r--r-- | drivers/gpu/drm/drm_lease.c | 14 |
1 files changed, 8 insertions, 6 deletions
diff --git a/drivers/gpu/drm/drm_lease.c b/drivers/gpu/drm/drm_lease.c index 4cfd8fe25536..3b367e07c87e 100644 --- a/drivers/gpu/drm/drm_lease.c +++ b/drivers/gpu/drm/drm_lease.c | |||
@@ -353,9 +353,9 @@ void drm_lease_revoke(struct drm_master *top) | |||
353 | } | 353 | } |
354 | 354 | ||
355 | static int validate_lease(struct drm_device *dev, | 355 | static int validate_lease(struct drm_device *dev, |
356 | struct drm_file *lessor_priv, | ||
357 | int object_count, | 356 | int object_count, |
358 | struct drm_mode_object **objects) | 357 | struct drm_mode_object **objects, |
358 | bool universal_planes) | ||
359 | { | 359 | { |
360 | int o; | 360 | int o; |
361 | int has_crtc = -1; | 361 | int has_crtc = -1; |
@@ -372,14 +372,14 @@ static int validate_lease(struct drm_device *dev, | |||
372 | if (objects[o]->type == DRM_MODE_OBJECT_CONNECTOR && has_connector == -1) | 372 | if (objects[o]->type == DRM_MODE_OBJECT_CONNECTOR && has_connector == -1) |
373 | has_connector = o; | 373 | has_connector = o; |
374 | 374 | ||
375 | if (lessor_priv->universal_planes) { | 375 | if (universal_planes) { |
376 | if (objects[o]->type == DRM_MODE_OBJECT_PLANE && has_plane == -1) | 376 | if (objects[o]->type == DRM_MODE_OBJECT_PLANE && has_plane == -1) |
377 | has_plane = o; | 377 | has_plane = o; |
378 | } | 378 | } |
379 | } | 379 | } |
380 | if (has_crtc == -1 || has_connector == -1) | 380 | if (has_crtc == -1 || has_connector == -1) |
381 | return -EINVAL; | 381 | return -EINVAL; |
382 | if (lessor_priv->universal_planes && has_plane == -1) | 382 | if (universal_planes && has_plane == -1) |
383 | return -EINVAL; | 383 | return -EINVAL; |
384 | return 0; | 384 | return 0; |
385 | } | 385 | } |
@@ -393,6 +393,8 @@ static int fill_object_idr(struct drm_device *dev, | |||
393 | struct drm_mode_object **objects; | 393 | struct drm_mode_object **objects; |
394 | u32 o; | 394 | u32 o; |
395 | int ret; | 395 | int ret; |
396 | bool universal_planes = READ_ONCE(lessor_priv->universal_planes); | ||
397 | |||
396 | objects = kcalloc(object_count, sizeof(struct drm_mode_object *), | 398 | objects = kcalloc(object_count, sizeof(struct drm_mode_object *), |
397 | GFP_KERNEL); | 399 | GFP_KERNEL); |
398 | if (!objects) | 400 | if (!objects) |
@@ -421,7 +423,7 @@ static int fill_object_idr(struct drm_device *dev, | |||
421 | } | 423 | } |
422 | } | 424 | } |
423 | 425 | ||
424 | ret = validate_lease(dev, lessor_priv, object_count, objects); | 426 | ret = validate_lease(dev, object_count, objects, universal_planes); |
425 | if (ret) { | 427 | if (ret) { |
426 | DRM_DEBUG_LEASE("lease validation failed\n"); | 428 | DRM_DEBUG_LEASE("lease validation failed\n"); |
427 | goto out_free_objects; | 429 | goto out_free_objects; |
@@ -448,7 +450,7 @@ static int fill_object_idr(struct drm_device *dev, | |||
448 | object_id, ret); | 450 | object_id, ret); |
449 | goto out_free_objects; | 451 | goto out_free_objects; |
450 | } | 452 | } |
451 | if (obj->type == DRM_MODE_OBJECT_CRTC && !lessor_priv->universal_planes) { | 453 | if (obj->type == DRM_MODE_OBJECT_CRTC && !universal_planes) { |
452 | struct drm_crtc *crtc = obj_to_crtc(obj); | 454 | struct drm_crtc *crtc = obj_to_crtc(obj); |
453 | ret = idr_alloc(leases, &drm_lease_idr_object, crtc->primary->base.id, crtc->primary->base.id + 1, GFP_KERNEL); | 455 | ret = idr_alloc(leases, &drm_lease_idr_object, crtc->primary->base.id, crtc->primary->base.id + 1, GFP_KERNEL); |
454 | if (ret < 0) { | 456 | if (ret < 0) { |