drm: Turn off Legacy Context Functions
authorPeter Antoine <peter.antoine@intel.com>
Tue, 23 Jun 2015 07:18:49 +0000 (08:18 +0100)
committerDaniel Vetter <daniel.vetter@ffwll.ch>
Thu, 2 Jul 2015 15:00:47 +0000 (17:00 +0200)
The context functions are not used by the i915 driver and should not
be used by modeset drivers. These driver functions contain several bugs
and security holes. This change makes these functions optional can be
turned on by a setting, they are turned off by default for modeset
driver with the exception of the nouvea driver that may require them with
an old version of libdrm.

The previous attempt was

commit 7c510133d93dd6f15ca040733ba7b2891ed61fd1
Author: Daniel Vetter <daniel.vetter@ffwll.ch>
Date:   Thu Aug 8 15:41:21 2013 +0200

    drm: mark context support as a legacy subsystem

but this had to be reverted

commit c21eb21cb50d58e7cbdcb8b9e7ff68b85cfa5095
Author: Dave Airlie <airlied@redhat.com>
Date:   Fri Sep 20 08:32:59 2013 +1000

    Revert "drm: mark context support as a legacy subsystem"

v2: remove returns from void function, and formatting (Daniel Vetter)

v3:
- s/Nova/nouveau/ in the commit message, and add references to the
  previous attempts
- drop the part touching the drm hw lock, that should be a separate
  patch.

Signed-off-by: Peter Antoine <peter.antoine@intel.com> (v2)
Cc: Peter Antoine <peter.antoine@intel.com> (v2)
Reviewed-by: Peter Antoine <peter.antoine@intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
drivers/gpu/drm/drm_context.c
drivers/gpu/drm/drm_drv.c
drivers/gpu/drm/nouveau/nouveau_drm.c
include/drm/drmP.h

index 9b23525c0ed043f0220760010c2584e86ed163f6..32958dabd7b0fe10b5e53e1f7134d973285294bf 100644 (file)
@@ -53,6 +53,10 @@ struct drm_ctx_list {
  */
 void drm_legacy_ctxbitmap_free(struct drm_device * dev, int ctx_handle)
 {
+       if (!drm_core_check_feature(dev, DRIVER_KMS_LEGACY_CONTEXT) &&
+           drm_core_check_feature(dev, DRIVER_MODESET))
+               return;
+
        mutex_lock(&dev->struct_mutex);
        idr_remove(&dev->ctx_idr, ctx_handle);
        mutex_unlock(&dev->struct_mutex);
@@ -87,6 +91,10 @@ static int drm_legacy_ctxbitmap_next(struct drm_device * dev)
  */
 int drm_legacy_ctxbitmap_init(struct drm_device * dev)
 {
+       if (!drm_core_check_feature(dev, DRIVER_KMS_LEGACY_CONTEXT) &&
+           drm_core_check_feature(dev, DRIVER_MODESET))
+               return -EINVAL;
+
        idr_init(&dev->ctx_idr);
        return 0;
 }
@@ -101,6 +109,10 @@ int drm_legacy_ctxbitmap_init(struct drm_device * dev)
  */
 void drm_legacy_ctxbitmap_cleanup(struct drm_device * dev)
 {
+       if (!drm_core_check_feature(dev, DRIVER_KMS_LEGACY_CONTEXT) &&
+           drm_core_check_feature(dev, DRIVER_MODESET))
+               return;
+
        mutex_lock(&dev->struct_mutex);
        idr_destroy(&dev->ctx_idr);
        mutex_unlock(&dev->struct_mutex);
@@ -119,6 +131,10 @@ void drm_legacy_ctxbitmap_flush(struct drm_device *dev, struct drm_file *file)
 {
        struct drm_ctx_list *pos, *tmp;
 
+       if (!drm_core_check_feature(dev, DRIVER_KMS_LEGACY_CONTEXT) &&
+           drm_core_check_feature(dev, DRIVER_MODESET))
+               return;
+
        mutex_lock(&dev->ctxlist_mutex);
 
        list_for_each_entry_safe(pos, tmp, &dev->ctxlist, head) {
@@ -161,6 +177,10 @@ int drm_legacy_getsareactx(struct drm_device *dev, void *data,
        struct drm_local_map *map;
        struct drm_map_list *_entry;
 
+       if (!drm_core_check_feature(dev, DRIVER_KMS_LEGACY_CONTEXT) &&
+           drm_core_check_feature(dev, DRIVER_MODESET))
+               return -EINVAL;
+
        mutex_lock(&dev->struct_mutex);
 
        map = idr_find(&dev->ctx_idr, request->ctx_id);
@@ -205,6 +225,10 @@ int drm_legacy_setsareactx(struct drm_device *dev, void *data,
        struct drm_local_map *map = NULL;
        struct drm_map_list *r_list = NULL;
 
+       if (!drm_core_check_feature(dev, DRIVER_KMS_LEGACY_CONTEXT) &&
+           drm_core_check_feature(dev, DRIVER_MODESET))
+               return -EINVAL;
+
        mutex_lock(&dev->struct_mutex);
        list_for_each_entry(r_list, &dev->maplist, head) {
                if (r_list->map
@@ -305,6 +329,10 @@ int drm_legacy_resctx(struct drm_device *dev, void *data,
        struct drm_ctx ctx;
        int i;
 
+       if (!drm_core_check_feature(dev, DRIVER_KMS_LEGACY_CONTEXT) &&
+           drm_core_check_feature(dev, DRIVER_MODESET))
+               return -EINVAL;
+
        if (res->count >= DRM_RESERVED_CONTEXTS) {
                memset(&ctx, 0, sizeof(ctx));
                for (i = 0; i < DRM_RESERVED_CONTEXTS; i++) {
@@ -335,6 +363,10 @@ int drm_legacy_addctx(struct drm_device *dev, void *data,
        struct drm_ctx_list *ctx_entry;
        struct drm_ctx *ctx = data;
 
+       if (!drm_core_check_feature(dev, DRIVER_KMS_LEGACY_CONTEXT) &&
+           drm_core_check_feature(dev, DRIVER_MODESET))
+               return -EINVAL;
+
        ctx->handle = drm_legacy_ctxbitmap_next(dev);
        if (ctx->handle == DRM_KERNEL_CONTEXT) {
                /* Skip kernel's context and get a new one. */
@@ -378,6 +410,10 @@ int drm_legacy_getctx(struct drm_device *dev, void *data,
 {
        struct drm_ctx *ctx = data;
 
+       if (!drm_core_check_feature(dev, DRIVER_KMS_LEGACY_CONTEXT) &&
+           drm_core_check_feature(dev, DRIVER_MODESET))
+               return -EINVAL;
+
        /* This is 0, because we don't handle any context flags */
        ctx->flags = 0;
 
@@ -400,6 +436,10 @@ int drm_legacy_switchctx(struct drm_device *dev, void *data,
 {
        struct drm_ctx *ctx = data;
 
+       if (!drm_core_check_feature(dev, DRIVER_KMS_LEGACY_CONTEXT) &&
+           drm_core_check_feature(dev, DRIVER_MODESET))
+               return -EINVAL;
+
        DRM_DEBUG("%d\n", ctx->handle);
        return drm_context_switch(dev, dev->last_context, ctx->handle);
 }
@@ -420,6 +460,10 @@ int drm_legacy_newctx(struct drm_device *dev, void *data,
 {
        struct drm_ctx *ctx = data;
 
+       if (!drm_core_check_feature(dev, DRIVER_KMS_LEGACY_CONTEXT) &&
+           drm_core_check_feature(dev, DRIVER_MODESET))
+               return -EINVAL;
+
        DRM_DEBUG("%d\n", ctx->handle);
        drm_context_switch_complete(dev, file_priv, ctx->handle);
 
@@ -442,6 +486,10 @@ int drm_legacy_rmctx(struct drm_device *dev, void *data,
 {
        struct drm_ctx *ctx = data;
 
+       if (!drm_core_check_feature(dev, DRIVER_KMS_LEGACY_CONTEXT) &&
+           drm_core_check_feature(dev, DRIVER_MODESET))
+               return -EINVAL;
+
        DRM_DEBUG("%d\n", ctx->handle);
        if (ctx->handle != DRM_KERNEL_CONTEXT) {
                if (dev->driver->context_dtor)
index b7bf4ce8c012bfb68442307b2b6f9f5658d0df48..838657503113cce1dd88adabaa7b9b14c9cc2a84 100644 (file)
@@ -582,11 +582,14 @@ struct drm_device *drm_dev_alloc(struct drm_driver *driver,
        if (drm_ht_create(&dev->map_hash, 12))
                goto err_minors;
 
-       ret = drm_legacy_ctxbitmap_init(dev);
-       if (ret) {
-               DRM_ERROR("Cannot allocate memory for context bitmap.\n");
-               goto err_ht;
-       }
+       if (drm_core_check_feature(dev, DRIVER_KMS_LEGACY_CONTEXT) ||
+               !drm_core_check_feature(dev, DRIVER_MODESET))
+               ret = drm_legacy_ctxbitmap_init(dev);
+               if (ret) {
+                       DRM_ERROR(
+                               "Cannot allocate memory for context bitmap.\n");
+                       goto err_ht;
+               }
 
        if (drm_core_check_feature(dev, DRIVER_GEM)) {
                ret = drm_gem_init(dev);
index 89049335b7383a12749e3d0e2f55f00be81598d4..9624b3827c349ae503c65fd5ee138988cf37f1ab 100644 (file)
@@ -941,7 +941,8 @@ static struct drm_driver
 driver_stub = {
        .driver_features =
                DRIVER_USE_AGP |
-               DRIVER_GEM | DRIVER_MODESET | DRIVER_PRIME | DRIVER_RENDER,
+               DRIVER_GEM | DRIVER_MODESET | DRIVER_PRIME | DRIVER_RENDER |
+               DRIVER_KMS_LEGACY_CONTEXT,
 
        .load = nouveau_drm_load,
        .unload = nouveau_drm_unload,
index 48db6a56975f5ebc874d19054828b70a5f4aaa15..3dc7c16c18f26179db3b81c327ec58d1a5a1d188 100644 (file)
@@ -137,17 +137,18 @@ void drm_err(const char *format, ...);
 /*@{*/
 
 /* driver capabilities and requirements mask */
-#define DRIVER_USE_AGP     0x1
-#define DRIVER_PCI_DMA     0x8
-#define DRIVER_SG          0x10
-#define DRIVER_HAVE_DMA    0x20
-#define DRIVER_HAVE_IRQ    0x40
-#define DRIVER_IRQ_SHARED  0x80
-#define DRIVER_GEM         0x1000
-#define DRIVER_MODESET     0x2000
-#define DRIVER_PRIME       0x4000
-#define DRIVER_RENDER      0x8000
-#define DRIVER_ATOMIC      0x10000
+#define DRIVER_USE_AGP                 0x1
+#define DRIVER_PCI_DMA                 0x8
+#define DRIVER_SG                      0x10
+#define DRIVER_HAVE_DMA                        0x20
+#define DRIVER_HAVE_IRQ                        0x40
+#define DRIVER_IRQ_SHARED              0x80
+#define DRIVER_GEM                     0x1000
+#define DRIVER_MODESET                 0x2000
+#define DRIVER_PRIME                   0x4000
+#define DRIVER_RENDER                  0x8000
+#define DRIVER_ATOMIC                  0x10000
+#define DRIVER_KMS_LEGACY_CONTEXT      0x20000
 
 /***********************************************************************/
 /** \name Macros to make printk easier */