[PATCH] drm: Turn off Legacy Context Functions

2015-06-10 Thread Peter Antoine
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 Nova driver that may require them with
an old version of libdrm.

Signed-off-by: Peter Antoine 
---
 drivers/gpu/drm/drm_context.c | 48 +++
 drivers/gpu/drm/drm_drv.c | 13 ++
 drivers/gpu/drm/drm_lock.c|  8 ++
 drivers/gpu/drm/nouveau/nouveau_drm.c |  3 ++-
 include/drm/drmP.h| 23 +
 5 files changed, 78 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/drm_context.c b/drivers/gpu/drm/drm_context.c
index 9b23525..f3ea657 100644
--- a/drivers/gpu/drm/drm_context.c
+++ b/drivers/gpu/drm/drm_context.c
@@ -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 -EINVAL;
+
mutex_lock(>struct_mutex);
idr_remove(>ctx_idr, ctx_handle);
mutex_unlock(>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(>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 -EINVAL;
+
mutex_lock(>struct_mutex);
idr_destroy(>ctx_idr);
mutex_unlock(>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 -EINVAL;
+
mutex_lock(>ctxlist_mutex);

list_for_each_entry_safe(pos, tmp, >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(>struct_mutex);

map = idr_find(>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(>struct_mutex);
list_for_each_entry(r_list, >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(, 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

[PATCH 5/5] drm: Make Legacy Context access functions optional.

2015-04-23 Thread Peter Antoine
As these functions are only used by one driver and there are security holes
in these functions. Make the functions optional.

These changes are based on the two patches:
  commit c21eb21cb50d58e7cbdcb8b9e7ff68b85cfa5095
  Author: Dave Airlie 

And the commit that the above patch reverts:
  commit 7c510133d93dd6f15ca040733ba7b2891ed61fd1
  Author: Daniel Vetter 

This should now turn off the context feature.

Issue: VIZ-5485
Signed-off-by: Peter Antoine 
---
 drivers/gpu/drm/drm_context.c | 36 
 drivers/gpu/drm/drm_drv.c | 12 +++-
 2 files changed, 43 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/drm_context.c b/drivers/gpu/drm/drm_context.c
index 1febcd3..09af26c 100644
--- a/drivers/gpu/drm/drm_context.c
+++ b/drivers/gpu/drm/drm_context.c
@@ -53,6 +53,9 @@ 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))
+   return -EINVAL;
+
mutex_lock(>struct_mutex);
idr_remove(>ctx_idr, ctx_handle);
mutex_unlock(>struct_mutex);
@@ -87,6 +90,9 @@ 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))
+   return -EINVAL;
+
idr_init(>ctx_idr);
return 0;
 }
@@ -101,6 +107,9 @@ 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))
+   return -EINVAL;
+
mutex_lock(>struct_mutex);
idr_destroy(>ctx_idr);
mutex_unlock(>struct_mutex);
@@ -119,6 +128,9 @@ 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))
+   return -EINVAL;
+
mutex_lock(>ctxlist_mutex);

list_for_each_entry_safe(pos, tmp, >ctxlist, head) {
@@ -161,6 +173,9 @@ 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))
+   return -EINVAL;
+
mutex_lock(>struct_mutex);

map = idr_find(>ctx_idr, request->ctx_id);
@@ -205,6 +220,9 @@ 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))
+   return -EINVAL;
+
mutex_lock(>struct_mutex);
list_for_each_entry(r_list, >maplist, head) {
if (r_list->map
@@ -311,6 +329,9 @@ 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))
+   return -EINVAL;
+
if (res->count >= DRM_RESERVED_CONTEXTS) {
memset(, 0, sizeof(ctx));
for (i = 0; i < DRM_RESERVED_CONTEXTS; i++) {
@@ -341,6 +362,9 @@ 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))
+   return -EINVAL;
+
ctx->handle = drm_legacy_ctxbitmap_next(dev);
if (_DRM_LOCKING_CONTEXT(ctx->handle) == DRM_KERNEL_CONTEXT) {
/* Skip kernel's context and get a new one. */
@@ -384,6 +408,9 @@ 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))
+   return -EINVAL;
+
/* This is 0, because we don't handle any context flags */
ctx->flags = 0;

@@ -406,6 +433,9 @@ 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))
+   return -EINVAL;
+
DRM_DEBUG("%d\n", ctx->handle);
return drm_context_switch(dev, dev->last_context, ctx->handle);
 }
@@ -426,6 +456,9 @@ 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))
+   return -EINVAL;
+
DRM_DEBUG("%d\n", ctx->handle);
drm_context_switch_complete(dev, file_priv, ctx->handle);

@@ -448,6 +481,9 @@ 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))
+   retu

[PATCH 4/5] drm: Make HW_LOCK access functions optional.

2015-04-23 Thread Peter Antoine
As these functions are only used by one driver and there are security holes
in these functions. Make the functions optional.

Issue: VIZ-5485
Signed-off-by: Peter Antoine 
---
 drivers/gpu/drm/drm_lock.c|  6 ++
 drivers/gpu/drm/i915/i915_dma.c   |  3 +++
 drivers/gpu/drm/nouveau/nouveau_drm.c |  3 ++-
 include/drm/drmP.h| 23 ---
 include/uapi/drm/i915_drm.h   |  1 +
 5 files changed, 24 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/drm_lock.c b/drivers/gpu/drm/drm_lock.c
index 94500930..b61d4c7 100644
--- a/drivers/gpu/drm/drm_lock.c
+++ b/drivers/gpu/drm/drm_lock.c
@@ -61,6 +61,9 @@ int drm_legacy_lock(struct drm_device *dev, void *data,
struct drm_master *master = file_priv->master;
int ret = 0;

+   if (!drm_core_check_feature(dev, DRIVER_KMS_LEGACY_CONTEXT))
+   return -EINVAL;
+
++file_priv->lock_count;

if (_DRM_LOCKING_CONTEXT(lock->context) == DRM_KERNEL_CONTEXT) {
@@ -153,6 +156,9 @@ int drm_legacy_unlock(struct drm_device *dev, void *data, 
struct drm_file *file_
struct drm_lock *lock = data;
struct drm_master *master = file_priv->master;

+   if (!drm_core_check_feature(dev, DRIVER_KMS_LEGACY_CONTEXT))
+   return -EINVAL;
+
if (_DRM_LOCKING_CONTEXT(lock->context) == DRM_KERNEL_CONTEXT) {
DRM_ERROR("Process %d using kernel context %d\n",
  task_pid_nr(current), lock->context);
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
index e44116f..c771ef0 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -163,6 +163,9 @@ static int i915_getparam(struct drm_device *dev, void *data,
if (!value)
return -ENODEV;
break;
+   case I915_PARAM_HAS_LEGACY_CONTEXT:
+   value = drm_core_check_feature(dev, DRIVER_KMS_LEGACY_CONTEXT);
+   break;
default:
DRM_DEBUG("Unknown parameter %d\n", param->param);
return -EINVAL;
diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c 
b/drivers/gpu/drm/nouveau/nouveau_drm.c
index 8763deb..936b423 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_drm.c
@@ -940,7 +940,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,
diff --git a/include/drm/drmP.h b/include/drm/drmP.h
index 62c40777..367e42f 100644
--- a/include/drm/drmP.h
+++ b/include/drm/drmP.h
@@ -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_DMA0x20
-#define DRIVER_HAVE_IRQ0x40
-#define DRIVER_IRQ_SHARED  0x80
-#define DRIVER_GEM 0x1000
-#define DRIVER_MODESET 0x2000
-#define DRIVER_PRIME   0x4000
-#define DRIVER_RENDER  0x8000
-#define DRIVER_ATOMIC  0x1
+#define DRIVER_USE_AGP 0x1
+#define DRIVER_PCI_DMA 0x8
+#define DRIVER_SG  0x10
+#define DRIVER_HAVE_DMA0x20
+#define DRIVER_HAVE_IRQ0x40
+#define DRIVER_IRQ_SHARED  0x80
+#define DRIVER_GEM 0x1000
+#define DRIVER_MODESET 0x2000
+#define DRIVER_PRIME   0x4000
+#define DRIVER_RENDER  0x8000
+#define DRIVER_ATOMIC  0x1
+#define DRIVER_KMS_LEGACY_CONTEXT  0x2

 /***/
 /** \name Macros to make printk easier */
diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h
index 4851d66..0ad611a2 100644
--- a/include/uapi/drm/i915_drm.h
+++ b/include/uapi/drm/i915_drm.h
@@ -350,6 +350,7 @@ typedef struct drm_i915_irq_wait {
 #define I915_PARAM_REVISION  32
 #define I915_PARAM_SUBSLICE_TOTAL   33
 #define I915_PARAM_EU_TOTAL 34
+#define I915_PARAM_HAS_LEGACY_CONTEXT   35

 typedef struct drm_i915_getparam {
int param;
-- 
1.9.1



[PATCH 3/5] drm: Possible lock priority escalation.

2015-04-23 Thread Peter Antoine
If an application that has a driver lock created, wants the lock the
kernel context, it is not allowed to. If the call to drm_lock has a
context of 0, it is rejected. If you set the context to _DRM_LOCK_CONT
then call drm lock, it will pass the context == DRM_KERNEL_CONTEXT checks.
But as the DRM_LOCK_CONT bits are not part of the context id this allows
operations on the DRM_KERNEL_CONTEXT.

Issue: VIZ-5485
Signed-off-by: Peter Antoine 
---
 drivers/gpu/drm/drm_context.c | 6 +++---
 drivers/gpu/drm/drm_lock.c| 4 ++--
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/drm_context.c b/drivers/gpu/drm/drm_context.c
index 96350d1..1febcd3 100644
--- a/drivers/gpu/drm/drm_context.c
+++ b/drivers/gpu/drm/drm_context.c
@@ -123,7 +123,7 @@ void drm_legacy_ctxbitmap_flush(struct drm_device *dev, 
struct drm_file *file)

list_for_each_entry_safe(pos, tmp, >ctxlist, head) {
if (pos->tag == file &&
-   pos->handle != DRM_KERNEL_CONTEXT) {
+   _DRM_LOCKING_CONTEXT(pos->handle) != DRM_KERNEL_CONTEXT) {
if (dev->driver->context_dtor)
dev->driver->context_dtor(dev, pos->handle);

@@ -342,7 +342,7 @@ int drm_legacy_addctx(struct drm_device *dev, void *data,
struct drm_ctx *ctx = data;

ctx->handle = drm_legacy_ctxbitmap_next(dev);
-   if (ctx->handle == DRM_KERNEL_CONTEXT) {
+   if (_DRM_LOCKING_CONTEXT(ctx->handle) == DRM_KERNEL_CONTEXT) {
/* Skip kernel's context and get a new one. */
ctx->handle = drm_legacy_ctxbitmap_next(dev);
}
@@ -449,7 +449,7 @@ int drm_legacy_rmctx(struct drm_device *dev, void *data,
struct drm_ctx *ctx = data;

DRM_DEBUG("%d\n", ctx->handle);
-   if (ctx->handle != DRM_KERNEL_CONTEXT) {
+   if (_DRM_LOCKING_CONTEXT(ctx->handle) != DRM_KERNEL_CONTEXT) {
if (dev->driver->context_dtor)
dev->driver->context_dtor(dev, ctx->handle);
drm_legacy_ctxbitmap_free(dev, ctx->handle);
diff --git a/drivers/gpu/drm/drm_lock.c b/drivers/gpu/drm/drm_lock.c
index 070dd5d..94500930 100644
--- a/drivers/gpu/drm/drm_lock.c
+++ b/drivers/gpu/drm/drm_lock.c
@@ -63,7 +63,7 @@ int drm_legacy_lock(struct drm_device *dev, void *data,

++file_priv->lock_count;

-   if (lock->context == DRM_KERNEL_CONTEXT) {
+   if (_DRM_LOCKING_CONTEXT(lock->context) == DRM_KERNEL_CONTEXT) {
DRM_ERROR("Process %d using kernel context %d\n",
  task_pid_nr(current), lock->context);
return -EINVAL;
@@ -153,7 +153,7 @@ int drm_legacy_unlock(struct drm_device *dev, void *data, 
struct drm_file *file_
struct drm_lock *lock = data;
struct drm_master *master = file_priv->master;

-   if (lock->context == DRM_KERNEL_CONTEXT) {
+   if (_DRM_LOCKING_CONTEXT(lock->context) == DRM_KERNEL_CONTEXT) {
DRM_ERROR("Process %d using kernel context %d\n",
  task_pid_nr(current), lock->context);
return -EINVAL;
-- 
1.9.1



[PATCH 2/5] drm: Fixes unsafe deference in locks.

2015-04-23 Thread Peter Antoine
This patch fixes an unsafe deference in the DRM_IOCTL_NEW_CTX. If the
ioctl is called before the lock is created or after it has been destroyed.
The code will deference a NULL pointer. This ioctl is a root ioctl so
exploitation is limited.

Issue: VIZ-5485
Signed-off-by: Peter Antoine 
---
 drivers/gpu/drm/drm_context.c | 8 +++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/drm_context.c b/drivers/gpu/drm/drm_context.c
index 9b23525..96350d1 100644
--- a/drivers/gpu/drm/drm_context.c
+++ b/drivers/gpu/drm/drm_context.c
@@ -277,7 +277,13 @@ static int drm_context_switch_complete(struct drm_device 
*dev,
 {
dev->last_context = new;/* PRE/POST: This is the _only_ writer. 
*/

-   if (!_DRM_LOCK_IS_HELD(file_priv->master->lock.hw_lock->lock)) {
+   if (file_priv->master->lock.hw_lock == NULL) {
+   DRM_ERROR(
+   "Device has been unregistered. Hard exit. Process %d\n",
+   task_pid_nr(current));
+   send_sig(SIGTERM, current, 0);
+   return -EPERM;
+   } else if (!_DRM_LOCK_IS_HELD(file_priv->master->lock.hw_lock->lock)) {
DRM_ERROR("Lock isn't held after context switch\n");
}

-- 
1.9.1



[PATCH 1/5] drm: Kernel Crash in drm_unlock

2015-04-23 Thread Peter Antoine
This patch fixes a possible kernel crash when drm_unlock (DRM_IOCTL_UNLOCK)
is called by a application that has not had a lock created by it. This
crash can be caused by any application from all users.

Issue: VIZ-5485
Signed-off-by: Peter Antoine 
---
 drivers/gpu/drm/drm_lock.c | 8 
 1 file changed, 8 insertions(+)

diff --git a/drivers/gpu/drm/drm_lock.c b/drivers/gpu/drm/drm_lock.c
index f861361..070dd5d 100644
--- a/drivers/gpu/drm/drm_lock.c
+++ b/drivers/gpu/drm/drm_lock.c
@@ -159,6 +159,14 @@ int drm_legacy_unlock(struct drm_device *dev, void *data, 
struct drm_file *file_
return -EINVAL;
}

+   if (!master->lock.hw_lock) {
+   DRM_ERROR(
+   "Device has been unregistered. Hard exit. Process %d\n",
+   task_pid_nr(current));
+   send_sig(SIGTERM, current, 0);
+   return -EPERM;
+   }
+
if (drm_legacy_lock_free(>lock, lock->context)) {
/* FIXME: Should really bail out here. */
}
-- 
1.9.1



[PATCH 0/5] HW_LOCK Security Patches

2015-04-23 Thread Peter Antoine
The following series of patches fix a number of security holes in the i915
driver (actually in drm but...). The first three patches remove the actual
security issues that have been found. The last two patches make the functions
optional for all drivers. The only driver that has this feature turned on is
the Nouveau driver, thus hopefully not breaking that driver.

The patch set has been tested on the Intel platforms but has not been tested
on the Nouveau driver. Hopefully someone with a working card and the right
combination of drmlib can verify that the patches do what they say.

There is a i-g-t test that goes with this patchset, but that test SHOULD NOT
be run before the kernel is patches as the test will crash the driver and/or
make the kernel panic.

Peter.

Peter Antoine (5):
  drm: Kernel Crash in drm_unlock
  drm: Fixes unsafe deference in locks.
  drm: Possible lock priority escalation.
  drm: Make HW_LOCK access functions optional.
  drm: Make Legacy Context access functions optional.

 drivers/gpu/drm/drm_context.c | 50 ---
 drivers/gpu/drm/drm_drv.c | 12 +
 drivers/gpu/drm/drm_lock.c| 18 +++--
 drivers/gpu/drm/i915/i915_dma.c   |  3 +++
 drivers/gpu/drm/nouveau/nouveau_drm.c |  3 ++-
 include/drm/drmP.h| 23 
 include/uapi/drm/i915_drm.h   |  1 +
 7 files changed, 87 insertions(+), 23 deletions(-)

-- 
1.9.1



[PATCH i-g-t] tests/drm_hw_lock: Tests for hw_lock fixes.

2015-04-23 Thread Peter Antoine
There are several issues with the hardware locks functions that stretch
from kernel crashes to priority escalations. This new test will test the
the fixes for these features.

This test will cause a driver/kernel crash on un-patched kernels, the
following patches should be applied to stop the crashes:

  drm: Kernel Crash in drm_unlock
  drm: Fixes unsafe deference in locks.

Issue: VIZ-5485
Signed-off-by: Peter Antoine 
---
 lib/ioctl_wrappers.c   |  19 +
 lib/ioctl_wrappers.h   |   1 +
 tests/Makefile.sources |   1 +
 tests/drm_hw_lock.c| 207 +
 4 files changed, 228 insertions(+)
 create mode 100644 tests/drm_hw_lock.c

diff --git a/lib/ioctl_wrappers.c b/lib/ioctl_wrappers.c
index 000d394..ad8b3d3 100644
--- a/lib/ioctl_wrappers.c
+++ b/lib/ioctl_wrappers.c
@@ -964,6 +964,25 @@ bool gem_has_bsd2(int fd)
 {
return gem_has_enable_ring(fd,LOCAL_I915_PARAM_HAS_BSD2);
 }
+#define I915_PARAM_HAS_LEGACY_CONTEXT   35
+bool drm_has_legacy_context(int fd)
+{
+   int tmp = 0;
+   drm_i915_getparam_t gp;
+
+   memset(, 0, sizeof(gp));
+   gp.value = 
+   gp.param = I915_PARAM_HAS_LEGACY_CONTEXT;
+
+   /*
+* if legacy context param is not supported, then it's old and we
+* can assume that the HW_LOCKS are supported.
+*/
+   if (drmIoctl(fd, DRM_IOCTL_I915_GETPARAM, ) != 0)
+   return true;
+
+   return tmp == 1;
+}
 /**
  * gem_available_aperture_size:
  * @fd: open i915 drm file descriptor
diff --git a/lib/ioctl_wrappers.h b/lib/ioctl_wrappers.h
index ced7ef3..3adc700 100644
--- a/lib/ioctl_wrappers.h
+++ b/lib/ioctl_wrappers.h
@@ -120,6 +120,7 @@ bool gem_has_bsd(int fd);
 bool gem_has_blt(int fd);
 bool gem_has_vebox(int fd);
 bool gem_has_bsd2(int fd);
+bool drm_has_legacy_context(int fd);
 bool gem_uses_aliasing_ppgtt(int fd);
 int gem_available_fences(int fd);
 uint64_t gem_available_aperture_size(int fd);
diff --git a/tests/Makefile.sources b/tests/Makefile.sources
index 71de6de..2f69afc 100644
--- a/tests/Makefile.sources
+++ b/tests/Makefile.sources
@@ -84,6 +84,7 @@ TESTS_progs_M = \
pm_sseu \
prime_self_import \
template \
+   drm_hw_lock \
$(NULL)

 TESTS_progs = \
diff --git a/tests/drm_hw_lock.c b/tests/drm_hw_lock.c
new file mode 100644
index 000..aad50ba
--- /dev/null
+++ b/tests/drm_hw_lock.c
@@ -0,0 +1,207 @@
+/*
+ * Copyright © 2015 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ *Peter Antoine 
+ */
+
+/*
+ * Testcase: Test the HW_LOCKs for correct support and non-crashing.
+ *
+ * This test will check that he hw_locks are only g_supported for drivers that
+ * require that support. If it is not g_supported then the functions all return
+ * the correct error code.
+ *
+ * If g_supported it will check that the functions do not crash when the crash
+ * tests are used, also that one of the tests is a security level escalation
+ * that should be rejected.
+ */
+#include 
+#include 
+#include 
+#include 
+#include "drmtest.h"
+#include "igt_core.h"
+#include "ioctl_wrappers.h"
+
+#ifndef DRM_KERNEL_CONTEXT
+#  define DRM_KERNEL_CONTEXT   (0)
+#endif
+
+#ifndef _DRM_LOCK_HELD
+#  define _DRM_LOCK_HELD   0x8000U /**< Hardware lock is held */
+#endif
+
+#ifndef _DRM_LOCK_CONT
+#  define _DRM_LOCK_CONT   0x4000U /**< Hardware lock is contended */
+#endif
+
+static boolg_sig_fired;
+static boolg_supported;
+static struct sigaction old_action;
+
+static void sig_term_handler(int value)
+{
+   g_sig_fired = true;
+}
+
+static bool set_term_handler(void)
+{
+   static struct sigaction new_action;
+
+   new_action.sa_handler = sig_term_handler;
+   sigemptyset(_action.sa_mask);
+   new_action.sa_flags = 0;
+
+