diff options
author | Keith Packard <keithp@keithp.com> | 2017-11-08 12:53:11 +0200 |
---|---|---|
committer | Leonard Crestez <leonard.crestez@nxp.com> | 2018-08-24 12:41:33 +0300 |
commit | d8a8d68e2822bede234c20d295007d82c08dc9b7 (patch) | |
tree | d0387d31a34dff31f408aa7622cbda5ed950c05f /drivers/gpu/drm/drm_irq.c | |
parent | 3aaebf5de39b1b4435656551a047fecbdf8d4411 (diff) |
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>
Signed-off-by: Marius Vlad <marius-cristian.vlad@nxp.com>
Diffstat (limited to 'drivers/gpu/drm/drm_irq.c')
-rw-r--r-- | drivers/gpu/drm/drm_irq.c | 23 |
1 files changed, 21 insertions, 2 deletions
diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index 00c815a7c414..6a200f716e33 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c @@ -1661,9 +1661,11 @@ err_put: int drm_wait_vblank(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; + unsigned int pipe_index; unsigned int flags, seq, pipe, high_pipe; if (!dev->irq_enabled) @@ -1685,9 +1687,26 @@ int drm_wait_vblank(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; |