diff options
author | Keith Packard <keithp@keithp.com> | 2017-04-10 07:35:34 +0300 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2017-10-25 09:31:30 +0300 |
commit | 7de440db20d4531e4b740bf17b56afc426c54377 (patch) | |
tree | f260b946f2d43023266e721903b99f523c2a944d /drivers/gpu/drm/drm_vblank.c | |
parent | 2ed077e467eedb033032bc4b6e349365517662d6 (diff) | |
download | linux-7de440db20d4531e4b740bf17b56afc426c54377.tar.xz |
drm: Check mode object lease status in all master ioctl paths [v4]
Attempts to modify un-leased objects are rejected with an error.
Information returned about unleased objects is modified to make them
appear unusable and/or disconnected.
Changes for v2 as suggested by Daniel Vetter <daniel.vetter@ffwll.ch>:
* With the change in the __drm_mode_object_find API to pass the
file_priv along, we can now centralize most of the lease-based
access checks in that function.
* A few places skip that API and require in-line checks.
Changes for v3 provided by Dave Airlie <airlied@redhat.com>
* remove support for leasing encoders.
* add support for leasing planes.
Changes for v4
* Only call drm_lease_held if DRIVER_MODESET.
Signed-off-by: Keith Packard <keithp@keithp.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/drm_vblank.c')
-rw-r--r-- | drivers/gpu/drm/drm_vblank.c | 22 |
1 files changed, 20 insertions, 2 deletions
diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c index 13722c373a6a..57cc6e37c810 100644 --- a/drivers/gpu/drm/drm_vblank.c +++ b/drivers/gpu/drm/drm_vblank.c @@ -1447,10 +1447,12 @@ static void drm_wait_vblank_reply(struct drm_device *dev, unsigned int pipe, int drm_wait_vblank_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv) { + struct drm_crtc *crtc; struct drm_vblank_crtc *vblank; union drm_wait_vblank *vblwait = data; int ret; u64 req_seq, seq; + unsigned int pipe_index; unsigned int flags, pipe, high_pipe; if (!dev->irq_enabled) @@ -1472,9 +1474,25 @@ int drm_wait_vblank_ioctl(struct drm_device *dev, void *data, flags = vblwait->request.type & _DRM_VBLANK_FLAGS_MASK; high_pipe = (vblwait->request.type & _DRM_VBLANK_HIGH_CRTC_MASK); if (high_pipe) - pipe = high_pipe >> _DRM_VBLANK_HIGH_CRTC_SHIFT; + pipe_index = high_pipe >> _DRM_VBLANK_HIGH_CRTC_SHIFT; else - pipe = flags & _DRM_VBLANK_SECONDARY ? 1 : 0; + pipe_index = flags & _DRM_VBLANK_SECONDARY ? 1 : 0; + + /* Convert lease-relative crtc index into global crtc index */ + if (drm_core_check_feature(dev, DRIVER_MODESET)) { + pipe = 0; + drm_for_each_crtc(crtc, dev) { + if (drm_lease_held(file_priv, crtc->base.id)) { + if (pipe_index == 0) + break; + pipe_index--; + } + pipe++; + } + } else { + pipe = pipe_index; + } + if (pipe >= dev->num_crtcs) return -EINVAL; |