From ea487835e8876abf7ad909636e308c801a2bcda6 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Mon, 28 Sep 2015 21:42:40 +0200 Subject: [PATCH] drm: Enforce unlocked ioctl operation for kms driver ioctls MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With the prep patches for i915 all kms drivers either have DRM_UNLOCKED on all their ioctls. Or the ioctl always directly returns with an invariant return value when in modeset mode. But that's only the case for i915 and radeon. The drm core ioctls are unfortunately too much a mess still to dare this. Follow-up patches will remove DRM_UNLOCKED from all kms drivers to prove that this is indeed the case. Also update the documentation. v2: Really only do this for driver ioctls, spotted by David Herrmann. And drop spurious whitespace change. Cc: David Herrmann Signed-off-by: Daniel Vetter Reviewed-by: David Herrmann Reviewed-by: Christian König Signed-off-by: Daniel Vetter --- Documentation/DocBook/drm.tmpl | 4 +++- drivers/gpu/drm/drm_ioctl.c | 10 ++++++++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/Documentation/DocBook/drm.tmpl b/Documentation/DocBook/drm.tmpl index 8d0cbf10cbba..2bc6c80065ce 100644 --- a/Documentation/DocBook/drm.tmpl +++ b/Documentation/DocBook/drm.tmpl @@ -3684,7 +3684,9 @@ int num_ioctls; DRM_UNLOCKED - The ioctl handler will be called without locking - the DRM global mutex + the DRM global mutex. This is the enforced default for kms drivers + (i.e. using the DRIVER_MODESET flag) and hence shouldn't be used + any more for new drivers. diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c index 530c501422fd..8ce2a0c59116 100644 --- a/drivers/gpu/drm/drm_ioctl.c +++ b/drivers/gpu/drm/drm_ioctl.c @@ -691,13 +691,16 @@ long drm_ioctl(struct file *filp, char stack_kdata[128]; char *kdata = NULL; unsigned int usize, asize, drv_size; + bool is_driver_ioctl; dev = file_priv->minor->dev; if (drm_device_is_unplugged(dev)) return -ENODEV; - if (nr >= DRM_COMMAND_BASE && nr < DRM_COMMAND_END) { + is_driver_ioctl = nr >= DRM_COMMAND_BASE && nr < DRM_COMMAND_END; + + if (is_driver_ioctl) { /* driver ioctl */ if (nr - DRM_COMMAND_BASE >= dev->driver->num_ioctls) goto err_i1; @@ -756,7 +759,10 @@ long drm_ioctl(struct file *filp, memset(kdata, 0, usize); } - if (ioctl->flags & DRM_UNLOCKED) + /* Enforce sane locking for kms driver ioctls. Core ioctls are + * too messy still. */ + if ((drm_core_check_feature(dev, DRIVER_MODESET) && is_driver_ioctl) || + (ioctl->flags & DRM_UNLOCKED)) retcode = func(dev, kdata, file_priv); else { mutex_lock(&drm_global_mutex);