drm: Return -ENOTSUPP when called for KMS cap with a non-KMS driver
authorMichel Dänzer <michel.daenzer@amd.com>
Thu, 1 Dec 2016 07:37:31 +0000 (16:37 +0900)
committerDaniel Vetter <daniel.vetter@ffwll.ch>
Tue, 6 Dec 2016 12:27:35 +0000 (13:27 +0100)
This is an attempt to make the previous fix a bit more robust going
forward.

v2:
* Only allow DRM_CAP_TIMESTAMP_MONOTONIC with UMS drivers (Daniel
  Vetter, Alex Deucher)
* Different logic to keep DRM_CAP_TIMESTAMP_MONOTONIC separate from
  the other caps (Daniel Vetter)

Signed-off-by: Michel Dänzer <michel.daenzer@amd.com>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Link: http://patchwork.freedesktop.org/patch/msgid/20161201073731.5716-1-michel@daenzer.net
drivers/gpu/drm/drm_ioctl.c

index 71c3473476c7498721a8524c2b8fbde18bf22d7b..706d5aaee7c3bc8aacc7acda23f99e52c5bfebaa 100644 (file)
@@ -229,6 +229,17 @@ static int drm_getcap(struct drm_device *dev, void *data, struct drm_file *file_
        struct drm_crtc *crtc;
 
        req->value = 0;
+
+       /* Only one cap makes sense with a UMS driver: */
+       if (req->capability == DRM_CAP_TIMESTAMP_MONOTONIC) {
+               req->value = drm_timestamp_monotonic;
+               return 0;
+       }
+
+       /* Other caps only work with KMS drivers */
+       if (!drm_core_check_feature(dev, DRIVER_MODESET))
+               return -ENOTSUPP;
+
        switch (req->capability) {
        case DRM_CAP_DUMB_BUFFER:
                if (dev->driver->dumb_create)
@@ -247,19 +258,14 @@ static int drm_getcap(struct drm_device *dev, void *data, struct drm_file *file_
                req->value |= dev->driver->prime_fd_to_handle ? DRM_PRIME_CAP_IMPORT : 0;
                req->value |= dev->driver->prime_handle_to_fd ? DRM_PRIME_CAP_EXPORT : 0;
                break;
-       case DRM_CAP_TIMESTAMP_MONOTONIC:
-               req->value = drm_timestamp_monotonic;
-               break;
        case DRM_CAP_ASYNC_PAGE_FLIP:
                req->value = dev->mode_config.async_page_flip;
                break;
        case DRM_CAP_PAGE_FLIP_TARGET:
-               if (drm_core_check_feature(dev, DRIVER_MODESET)) {
-                       req->value = 1;
-                       drm_for_each_crtc(crtc, dev) {
-                               if (!crtc->funcs->page_flip_target)
-                                       req->value = 0;
-                       }
+               req->value = 1;
+               drm_for_each_crtc(crtc, dev) {
+                       if (!crtc->funcs->page_flip_target)
+                               req->value = 0;
                }
                break;
        case DRM_CAP_CURSOR_WIDTH: