aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2014-08-06 03:21:13 -0400
committerDave Airlie <airlied@redhat.com>2014-08-06 03:21:13 -0400
commitacf8294fecd4b805b408d02c321a0fd7eef95555 (patch)
tree1bf751f65495b72c626b5318fc33adbb1f7b5979
parent5b215bcff50d549d73e43c09bcccf8eebcc95bac (diff)
parente7b96070dd9e51a8b16340411a8643d8c7d5a001 (diff)
Merge branch 'drm-next' of git://people.freedesktop.org/~dvdhrm/linux into drm-next
bunch of cleanups * 'drm-next' of git://people.freedesktop.org/~dvdhrm/linux: drm: mark drm_context support as legacy drm: make sysfs device always available for minors drm: make minor->index available early drm: merge drm_drv.c into drm_ioctl.c drm: move module initialization to drm_stub.c drm: don't de-authenticate clients on master-close drm: drop redundant drm_file->is_master drm: extract legacy ctxbitmap flushing
-rw-r--r--drivers/gpu/drm/Makefile2
-rw-r--r--drivers/gpu/drm/drm_context.c102
-rw-r--r--drivers/gpu/drm/drm_crtc.c2
-rw-r--r--drivers/gpu/drm/drm_drv.c471
-rw-r--r--drivers/gpu/drm/drm_fops.c77
-rw-r--r--drivers/gpu/drm/drm_ioctl.c370
-rw-r--r--drivers/gpu/drm/drm_legacy.h51
-rw-r--r--drivers/gpu/drm/drm_lock.c3
-rw-r--r--drivers/gpu/drm/drm_stub.c238
-rw-r--r--drivers/gpu/drm/drm_sysfs.c90
-rw-r--r--drivers/gpu/drm/i915/i915_gem_execbuffer.c4
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_drv.c2
-rw-r--r--drivers/staging/imx-drm/imx-drm-core.c2
-rw-r--r--include/drm/drmP.h61
14 files changed, 727 insertions, 748 deletions
diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index 60eb5d425df2..1f6f40cecf5c 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -6,7 +6,7 @@ ccflags-y := -Iinclude/drm
6 6
7drm-y := drm_auth.o drm_buffer.o drm_bufs.o drm_cache.o \ 7drm-y := drm_auth.o drm_buffer.o drm_bufs.o drm_cache.o \
8 drm_context.o drm_dma.o \ 8 drm_context.o drm_dma.o \
9 drm_drv.o drm_fops.o drm_gem.o drm_ioctl.o drm_irq.o \ 9 drm_fops.o drm_gem.o drm_ioctl.o drm_irq.o \
10 drm_lock.o drm_memory.o drm_stub.o drm_vm.o \ 10 drm_lock.o drm_memory.o drm_stub.o drm_vm.o \
11 drm_agpsupport.o drm_scatter.o drm_pci.o \ 11 drm_agpsupport.o drm_scatter.o drm_pci.o \
12 drm_platform.o drm_sysfs.o drm_hashtab.o drm_mm.o \ 12 drm_platform.o drm_sysfs.o drm_hashtab.o drm_mm.o \
diff --git a/drivers/gpu/drm/drm_context.c b/drivers/gpu/drm/drm_context.c
index a4b017b6849e..9b23525c0ed0 100644
--- a/drivers/gpu/drm/drm_context.c
+++ b/drivers/gpu/drm/drm_context.c
@@ -1,18 +1,13 @@
1/**
2 * \file drm_context.c
3 * IOCTLs for generic contexts
4 *
5 * \author Rickard E. (Rik) Faith <faith@valinux.com>
6 * \author Gareth Hughes <gareth@valinux.com>
7 */
8
9/* 1/*
10 * Created: Fri Nov 24 18:31:37 2000 by gareth@valinux.com 2 * Legacy: Generic DRM Contexts
11 * 3 *
12 * Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas. 4 * Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas.
13 * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. 5 * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
14 * All Rights Reserved. 6 * All Rights Reserved.
15 * 7 *
8 * Author: Rickard E. (Rik) Faith <faith@valinux.com>
9 * Author: Gareth Hughes <gareth@valinux.com>
10 *
16 * Permission is hereby granted, free of charge, to any person obtaining a 11 * Permission is hereby granted, free of charge, to any person obtaining a
17 * copy of this software and associated documentation files (the "Software"), 12 * copy of this software and associated documentation files (the "Software"),
18 * to deal in the Software without restriction, including without limitation 13 * to deal in the Software without restriction, including without limitation
@@ -33,14 +28,14 @@
33 * OTHER DEALINGS IN THE SOFTWARE. 28 * OTHER DEALINGS IN THE SOFTWARE.
34 */ 29 */
35 30
36/*
37 * ChangeLog:
38 * 2001-11-16 Torsten Duwe <duwe@caldera.de>
39 * added context constructor/destructor hooks,
40 * needed by SiS driver's memory management.
41 */
42
43#include <drm/drmP.h> 31#include <drm/drmP.h>
32#include "drm_legacy.h"
33
34struct drm_ctx_list {
35 struct list_head head;
36 drm_context_t handle;
37 struct drm_file *tag;
38};
44 39
45/******************************************************************/ 40/******************************************************************/
46/** \name Context bitmap support */ 41/** \name Context bitmap support */
@@ -56,7 +51,7 @@
56 * in drm_device::ctx_idr, while holding the drm_device::struct_mutex 51 * in drm_device::ctx_idr, while holding the drm_device::struct_mutex
57 * lock. 52 * lock.
58 */ 53 */
59void drm_ctxbitmap_free(struct drm_device * dev, int ctx_handle) 54void drm_legacy_ctxbitmap_free(struct drm_device * dev, int ctx_handle)
60{ 55{
61 mutex_lock(&dev->struct_mutex); 56 mutex_lock(&dev->struct_mutex);
62 idr_remove(&dev->ctx_idr, ctx_handle); 57 idr_remove(&dev->ctx_idr, ctx_handle);
@@ -72,7 +67,7 @@ void drm_ctxbitmap_free(struct drm_device * dev, int ctx_handle)
72 * Allocate a new idr from drm_device::ctx_idr while holding the 67 * Allocate a new idr from drm_device::ctx_idr while holding the
73 * drm_device::struct_mutex lock. 68 * drm_device::struct_mutex lock.
74 */ 69 */
75static int drm_ctxbitmap_next(struct drm_device * dev) 70static int drm_legacy_ctxbitmap_next(struct drm_device * dev)
76{ 71{
77 int ret; 72 int ret;
78 73
@@ -90,7 +85,7 @@ static int drm_ctxbitmap_next(struct drm_device * dev)
90 * 85 *
91 * Initialise the drm_device::ctx_idr 86 * Initialise the drm_device::ctx_idr
92 */ 87 */
93int drm_ctxbitmap_init(struct drm_device * dev) 88int drm_legacy_ctxbitmap_init(struct drm_device * dev)
94{ 89{
95 idr_init(&dev->ctx_idr); 90 idr_init(&dev->ctx_idr);
96 return 0; 91 return 0;
@@ -104,13 +99,43 @@ int drm_ctxbitmap_init(struct drm_device * dev)
104 * Free all idr members using drm_ctx_sarea_free helper function 99 * Free all idr members using drm_ctx_sarea_free helper function
105 * while holding the drm_device::struct_mutex lock. 100 * while holding the drm_device::struct_mutex lock.
106 */ 101 */
107void drm_ctxbitmap_cleanup(struct drm_device * dev) 102void drm_legacy_ctxbitmap_cleanup(struct drm_device * dev)
108{ 103{
109 mutex_lock(&dev->struct_mutex); 104 mutex_lock(&dev->struct_mutex);
110 idr_destroy(&dev->ctx_idr); 105 idr_destroy(&dev->ctx_idr);
111 mutex_unlock(&dev->struct_mutex); 106 mutex_unlock(&dev->struct_mutex);
112} 107}
113 108
109/**
110 * drm_ctxbitmap_flush() - Flush all contexts owned by a file
111 * @dev: DRM device to operate on
112 * @file: Open file to flush contexts for
113 *
114 * This iterates over all contexts on @dev and drops them if they're owned by
115 * @file. Note that after this call returns, new contexts might be added if
116 * the file is still alive.
117 */
118void drm_legacy_ctxbitmap_flush(struct drm_device *dev, struct drm_file *file)
119{
120 struct drm_ctx_list *pos, *tmp;
121
122 mutex_lock(&dev->ctxlist_mutex);
123
124 list_for_each_entry_safe(pos, tmp, &dev->ctxlist, head) {
125 if (pos->tag == file &&
126 pos->handle != DRM_KERNEL_CONTEXT) {
127 if (dev->driver->context_dtor)
128 dev->driver->context_dtor(dev, pos->handle);
129
130 drm_legacy_ctxbitmap_free(dev, pos->handle);
131 list_del(&pos->head);
132 kfree(pos);
133 }
134 }
135
136 mutex_unlock(&dev->ctxlist_mutex);
137}
138
114/*@}*/ 139/*@}*/
115 140
116/******************************************************************/ 141/******************************************************************/
@@ -129,8 +154,8 @@ void drm_ctxbitmap_cleanup(struct drm_device * dev)
129 * Gets the map from drm_device::ctx_idr with the handle specified and 154 * Gets the map from drm_device::ctx_idr with the handle specified and
130 * returns its handle. 155 * returns its handle.
131 */ 156 */
132int drm_getsareactx(struct drm_device *dev, void *data, 157int drm_legacy_getsareactx(struct drm_device *dev, void *data,
133 struct drm_file *file_priv) 158 struct drm_file *file_priv)
134{ 159{
135 struct drm_ctx_priv_map *request = data; 160 struct drm_ctx_priv_map *request = data;
136 struct drm_local_map *map; 161 struct drm_local_map *map;
@@ -173,8 +198,8 @@ int drm_getsareactx(struct drm_device *dev, void *data,
173 * Searches the mapping specified in \p arg and update the entry in 198 * Searches the mapping specified in \p arg and update the entry in
174 * drm_device::ctx_idr with it. 199 * drm_device::ctx_idr with it.
175 */ 200 */
176int drm_setsareactx(struct drm_device *dev, void *data, 201int drm_legacy_setsareactx(struct drm_device *dev, void *data,
177 struct drm_file *file_priv) 202 struct drm_file *file_priv)
178{ 203{
179 struct drm_ctx_priv_map *request = data; 204 struct drm_ctx_priv_map *request = data;
180 struct drm_local_map *map = NULL; 205 struct drm_local_map *map = NULL;
@@ -273,8 +298,8 @@ static int drm_context_switch_complete(struct drm_device *dev,
273 * \param arg user argument pointing to a drm_ctx_res structure. 298 * \param arg user argument pointing to a drm_ctx_res structure.
274 * \return zero on success or a negative number on failure. 299 * \return zero on success or a negative number on failure.
275 */ 300 */
276int drm_resctx(struct drm_device *dev, void *data, 301int drm_legacy_resctx(struct drm_device *dev, void *data,
277 struct drm_file *file_priv) 302 struct drm_file *file_priv)
278{ 303{
279 struct drm_ctx_res *res = data; 304 struct drm_ctx_res *res = data;
280 struct drm_ctx ctx; 305 struct drm_ctx ctx;
@@ -304,16 +329,16 @@ int drm_resctx(struct drm_device *dev, void *data,
304 * 329 *
305 * Get a new handle for the context and copy to userspace. 330 * Get a new handle for the context and copy to userspace.
306 */ 331 */
307int drm_addctx(struct drm_device *dev, void *data, 332int drm_legacy_addctx(struct drm_device *dev, void *data,
308 struct drm_file *file_priv) 333 struct drm_file *file_priv)
309{ 334{
310 struct drm_ctx_list *ctx_entry; 335 struct drm_ctx_list *ctx_entry;
311 struct drm_ctx *ctx = data; 336 struct drm_ctx *ctx = data;
312 337
313 ctx->handle = drm_ctxbitmap_next(dev); 338 ctx->handle = drm_legacy_ctxbitmap_next(dev);
314 if (ctx->handle == DRM_KERNEL_CONTEXT) { 339 if (ctx->handle == DRM_KERNEL_CONTEXT) {
315 /* Skip kernel's context and get a new one. */ 340 /* Skip kernel's context and get a new one. */
316 ctx->handle = drm_ctxbitmap_next(dev); 341 ctx->handle = drm_legacy_ctxbitmap_next(dev);
317 } 342 }
318 DRM_DEBUG("%d\n", ctx->handle); 343 DRM_DEBUG("%d\n", ctx->handle);
319 if (ctx->handle == -1) { 344 if (ctx->handle == -1) {
@@ -348,7 +373,8 @@ int drm_addctx(struct drm_device *dev, void *data,
348 * \param arg user argument pointing to a drm_ctx structure. 373 * \param arg user argument pointing to a drm_ctx structure.
349 * \return zero on success or a negative number on failure. 374 * \return zero on success or a negative number on failure.
350 */ 375 */
351int drm_getctx(struct drm_device *dev, void *data, struct drm_file *file_priv) 376int drm_legacy_getctx(struct drm_device *dev, void *data,
377 struct drm_file *file_priv)
352{ 378{
353 struct drm_ctx *ctx = data; 379 struct drm_ctx *ctx = data;
354 380
@@ -369,8 +395,8 @@ int drm_getctx(struct drm_device *dev, void *data, struct drm_file *file_priv)
369 * 395 *
370 * Calls context_switch(). 396 * Calls context_switch().
371 */ 397 */
372int drm_switchctx(struct drm_device *dev, void *data, 398int drm_legacy_switchctx(struct drm_device *dev, void *data,
373 struct drm_file *file_priv) 399 struct drm_file *file_priv)
374{ 400{
375 struct drm_ctx *ctx = data; 401 struct drm_ctx *ctx = data;
376 402
@@ -389,8 +415,8 @@ int drm_switchctx(struct drm_device *dev, void *data,
389 * 415 *
390 * Calls context_switch_complete(). 416 * Calls context_switch_complete().
391 */ 417 */
392int drm_newctx(struct drm_device *dev, void *data, 418int drm_legacy_newctx(struct drm_device *dev, void *data,
393 struct drm_file *file_priv) 419 struct drm_file *file_priv)
394{ 420{
395 struct drm_ctx *ctx = data; 421 struct drm_ctx *ctx = data;
396 422
@@ -411,8 +437,8 @@ int drm_newctx(struct drm_device *dev, void *data,
411 * 437 *
412 * If not the special kernel context, calls ctxbitmap_free() to free the specified context. 438 * If not the special kernel context, calls ctxbitmap_free() to free the specified context.
413 */ 439 */
414int drm_rmctx(struct drm_device *dev, void *data, 440int drm_legacy_rmctx(struct drm_device *dev, void *data,
415 struct drm_file *file_priv) 441 struct drm_file *file_priv)
416{ 442{
417 struct drm_ctx *ctx = data; 443 struct drm_ctx *ctx = data;
418 444
@@ -420,7 +446,7 @@ int drm_rmctx(struct drm_device *dev, void *data,
420 if (ctx->handle != DRM_KERNEL_CONTEXT) { 446 if (ctx->handle != DRM_KERNEL_CONTEXT) {
421 if (dev->driver->context_dtor) 447 if (dev->driver->context_dtor)
422 dev->driver->context_dtor(dev, ctx->handle); 448 dev->driver->context_dtor(dev, ctx->handle);
423 drm_ctxbitmap_free(dev, ctx->handle); 449 drm_legacy_ctxbitmap_free(dev, ctx->handle);
424 } 450 }
425 451
426 mutex_lock(&dev->ctxlist_mutex); 452 mutex_lock(&dev->ctxlist_mutex);
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index fa2be249999c..ca8bb1bc92a0 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -3244,7 +3244,7 @@ int drm_mode_getfb(struct drm_device *dev,
3244 r->bpp = fb->bits_per_pixel; 3244 r->bpp = fb->bits_per_pixel;
3245 r->pitch = fb->pitches[0]; 3245 r->pitch = fb->pitches[0];
3246 if (fb->funcs->create_handle) { 3246 if (fb->funcs->create_handle) {
3247 if (file_priv->is_master || capable(CAP_SYS_ADMIN) || 3247 if (drm_is_master(file_priv) || capable(CAP_SYS_ADMIN) ||
3248 drm_is_control_client(file_priv)) { 3248 drm_is_control_client(file_priv)) {
3249 ret = fb->funcs->create_handle(fb, file_priv, 3249 ret = fb->funcs->create_handle(fb, file_priv,
3250 &r->handle); 3250 &r->handle);
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
deleted file mode 100644
index 0cc182745e31..000000000000
--- a/drivers/gpu/drm/drm_drv.c
+++ /dev/null
@@ -1,471 +0,0 @@
1/**
2 * \file drm_drv.c
3 * Generic driver template
4 *
5 * \author Rickard E. (Rik) Faith <faith@valinux.com>
6 * \author Gareth Hughes <gareth@valinux.com>
7 *
8 * To use this template, you must at least define the following (samples
9 * given for the MGA driver):
10 *
11 * \code
12 * #define DRIVER_AUTHOR "VA Linux Systems, Inc."
13 *
14 * #define DRIVER_NAME "mga"
15 * #define DRIVER_DESC "Matrox G200/G400"
16 * #define DRIVER_DATE "20001127"
17 *
18 * #define drm_x mga_##x
19 * \endcode
20 */
21
22/*
23 * Created: Thu Nov 23 03:10:50 2000 by gareth@valinux.com
24 *
25 * Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas.
26 * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
27 * All Rights Reserved.
28 *
29 * Permission is hereby granted, free of charge, to any person obtaining a
30 * copy of this software and associated documentation files (the "Software"),
31 * to deal in the Software without restriction, including without limitation
32 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
33 * and/or sell copies of the Software, and to permit persons to whom the
34 * Software is furnished to do so, subject to the following conditions:
35 *
36 * The above copyright notice and this permission notice (including the next
37 * paragraph) shall be included in all copies or substantial portions of the
38 * Software.
39 *
40 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
41 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
42 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
43 * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
44 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
45 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
46 * OTHER DEALINGS IN THE SOFTWARE.
47 */
48
49#include <linux/debugfs.h>
50#include <linux/slab.h>
51#include <linux/export.h>
52#include <drm/drmP.h>
53#include <drm/drm_core.h>
54
55
56static int drm_version(struct drm_device *dev, void *data,
57 struct drm_file *file_priv);
58
59#define DRM_IOCTL_DEF(ioctl, _func, _flags) \
60 [DRM_IOCTL_NR(ioctl)] = {.cmd = ioctl, .func = _func, .flags = _flags, .cmd_drv = 0, .name = #ioctl}
61
62/** Ioctl table */
63static const struct drm_ioctl_desc drm_ioctls[] = {
64 DRM_IOCTL_DEF(DRM_IOCTL_VERSION, drm_version, DRM_UNLOCKED|DRM_RENDER_ALLOW),
65 DRM_IOCTL_DEF(DRM_IOCTL_GET_UNIQUE, drm_getunique, 0),
66 DRM_IOCTL_DEF(DRM_IOCTL_GET_MAGIC, drm_getmagic, 0),
67 DRM_IOCTL_DEF(DRM_IOCTL_IRQ_BUSID, drm_irq_by_busid, DRM_MASTER|DRM_ROOT_ONLY),
68 DRM_IOCTL_DEF(DRM_IOCTL_GET_MAP, drm_getmap, DRM_UNLOCKED),
69 DRM_IOCTL_DEF(DRM_IOCTL_GET_CLIENT, drm_getclient, DRM_UNLOCKED),
70 DRM_IOCTL_DEF(DRM_IOCTL_GET_STATS, drm_getstats, DRM_UNLOCKED),
71 DRM_IOCTL_DEF(DRM_IOCTL_GET_CAP, drm_getcap, DRM_UNLOCKED|DRM_RENDER_ALLOW),
72 DRM_IOCTL_DEF(DRM_IOCTL_SET_CLIENT_CAP, drm_setclientcap, 0),
73 DRM_IOCTL_DEF(DRM_IOCTL_SET_VERSION, drm_setversion, DRM_MASTER),
74
75 DRM_IOCTL_DEF(DRM_IOCTL_SET_UNIQUE, drm_setunique, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
76 DRM_IOCTL_DEF(DRM_IOCTL_BLOCK, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
77 DRM_IOCTL_DEF(DRM_IOCTL_UNBLOCK, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
78 DRM_IOCTL_DEF(DRM_IOCTL_AUTH_MAGIC, drm_authmagic, DRM_AUTH|DRM_MASTER),
79
80 DRM_IOCTL_DEF(DRM_IOCTL_ADD_MAP, drm_addmap_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
81 DRM_IOCTL_DEF(DRM_IOCTL_RM_MAP, drm_rmmap_ioctl, DRM_AUTH),
82
83 DRM_IOCTL_DEF(DRM_IOCTL_SET_SAREA_CTX, drm_setsareactx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
84 DRM_IOCTL_DEF(DRM_IOCTL_GET_SAREA_CTX, drm_getsareactx, DRM_AUTH),
85
86 DRM_IOCTL_DEF(DRM_IOCTL_SET_MASTER, drm_setmaster_ioctl, DRM_ROOT_ONLY),
87 DRM_IOCTL_DEF(DRM_IOCTL_DROP_MASTER, drm_dropmaster_ioctl, DRM_ROOT_ONLY),
88
89 DRM_IOCTL_DEF(DRM_IOCTL_ADD_CTX, drm_addctx, DRM_AUTH|DRM_ROOT_ONLY),
90 DRM_IOCTL_DEF(DRM_IOCTL_RM_CTX, drm_rmctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
91 DRM_IOCTL_DEF(DRM_IOCTL_MOD_CTX, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
92 DRM_IOCTL_DEF(DRM_IOCTL_GET_CTX, drm_getctx, DRM_AUTH),
93 DRM_IOCTL_DEF(DRM_IOCTL_SWITCH_CTX, drm_switchctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
94 DRM_IOCTL_DEF(DRM_IOCTL_NEW_CTX, drm_newctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
95 DRM_IOCTL_DEF(DRM_IOCTL_RES_CTX, drm_resctx, DRM_AUTH),
96
97 DRM_IOCTL_DEF(DRM_IOCTL_ADD_DRAW, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
98 DRM_IOCTL_DEF(DRM_IOCTL_RM_DRAW, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
99
100 DRM_IOCTL_DEF(DRM_IOCTL_LOCK, drm_lock, DRM_AUTH),
101 DRM_IOCTL_DEF(DRM_IOCTL_UNLOCK, drm_unlock, DRM_AUTH),
102
103 DRM_IOCTL_DEF(DRM_IOCTL_FINISH, drm_noop, DRM_AUTH),
104
105 DRM_IOCTL_DEF(DRM_IOCTL_ADD_BUFS, drm_addbufs, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
106 DRM_IOCTL_DEF(DRM_IOCTL_MARK_BUFS, drm_markbufs, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
107 DRM_IOCTL_DEF(DRM_IOCTL_INFO_BUFS, drm_infobufs, DRM_AUTH),
108 DRM_IOCTL_DEF(DRM_IOCTL_MAP_BUFS, drm_mapbufs, DRM_AUTH),
109 DRM_IOCTL_DEF(DRM_IOCTL_FREE_BUFS, drm_freebufs, DRM_AUTH),
110 DRM_IOCTL_DEF(DRM_IOCTL_DMA, drm_dma_ioctl, DRM_AUTH),
111
112 DRM_IOCTL_DEF(DRM_IOCTL_CONTROL, drm_control, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
113
114#if __OS_HAS_AGP
115 DRM_IOCTL_DEF(DRM_IOCTL_AGP_ACQUIRE, drm_agp_acquire_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
116 DRM_IOCTL_DEF(DRM_IOCTL_AGP_RELEASE, drm_agp_release_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
117 DRM_IOCTL_DEF(DRM_IOCTL_AGP_ENABLE, drm_agp_enable_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
118 DRM_IOCTL_DEF(DRM_IOCTL_AGP_INFO, drm_agp_info_ioctl, DRM_AUTH),
119 DRM_IOCTL_DEF(DRM_IOCTL_AGP_ALLOC, drm_agp_alloc_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
120 DRM_IOCTL_DEF(DRM_IOCTL_AGP_FREE, drm_agp_free_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
121 DRM_IOCTL_DEF(DRM_IOCTL_AGP_BIND, drm_agp_bind_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
122 DRM_IOCTL_DEF(DRM_IOCTL_AGP_UNBIND, drm_agp_unbind_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
123#endif
124
125 DRM_IOCTL_DEF(DRM_IOCTL_SG_ALLOC, drm_sg_alloc, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
126 DRM_IOCTL_DEF(DRM_IOCTL_SG_FREE, drm_sg_free, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
127
128 DRM_IOCTL_DEF(DRM_IOCTL_WAIT_VBLANK, drm_wait_vblank, DRM_UNLOCKED),
129
130 DRM_IOCTL_DEF(DRM_IOCTL_MODESET_CTL, drm_modeset_ctl, 0),
131
132 DRM_IOCTL_DEF(DRM_IOCTL_UPDATE_DRAW, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
133
134 DRM_IOCTL_DEF(DRM_IOCTL_GEM_CLOSE, drm_gem_close_ioctl, DRM_UNLOCKED|DRM_RENDER_ALLOW),
135 DRM_IOCTL_DEF(DRM_IOCTL_GEM_FLINK, drm_gem_flink_ioctl, DRM_AUTH|DRM_UNLOCKED),
136 DRM_IOCTL_DEF(DRM_IOCTL_GEM_OPEN, drm_gem_open_ioctl, DRM_AUTH|DRM_UNLOCKED),
137
138 DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETRESOURCES, drm_mode_getresources, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
139
140 DRM_IOCTL_DEF(DRM_IOCTL_PRIME_HANDLE_TO_FD, drm_prime_handle_to_fd_ioctl, DRM_AUTH|DRM_UNLOCKED|DRM_RENDER_ALLOW),
141 DRM_IOCTL_DEF(DRM_IOCTL_PRIME_FD_TO_HANDLE, drm_prime_fd_to_handle_ioctl, DRM_AUTH|DRM_UNLOCKED|DRM_RENDER_ALLOW),
142
143 DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPLANERESOURCES, drm_mode_getplane_res, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
144 DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETCRTC, drm_mode_getcrtc, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
145 DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETCRTC, drm_mode_setcrtc, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
146 DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPLANE, drm_mode_getplane, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
147 DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETPLANE, drm_mode_setplane, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
148 DRM_IOCTL_DEF(DRM_IOCTL_MODE_CURSOR, drm_mode_cursor_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
149 DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETGAMMA, drm_mode_gamma_get_ioctl, DRM_UNLOCKED),
150 DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETGAMMA, drm_mode_gamma_set_ioctl, DRM_MASTER|DRM_UNLOCKED),
151 DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETENCODER, drm_mode_getencoder, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
152 DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETCONNECTOR, drm_mode_getconnector, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
153 DRM_IOCTL_DEF(DRM_IOCTL_MODE_ATTACHMODE, drm_noop, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
154 DRM_IOCTL_DEF(DRM_IOCTL_MODE_DETACHMODE, drm_noop, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
155 DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPROPERTY, drm_mode_getproperty_ioctl, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
156 DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETPROPERTY, drm_mode_connector_property_set_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
157 DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPROPBLOB, drm_mode_getblob_ioctl, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
158 DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETFB, drm_mode_getfb, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
159 DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDFB, drm_mode_addfb, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
160 DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDFB2, drm_mode_addfb2, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
161 DRM_IOCTL_DEF(DRM_IOCTL_MODE_RMFB, drm_mode_rmfb, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
162 DRM_IOCTL_DEF(DRM_IOCTL_MODE_PAGE_FLIP, drm_mode_page_flip_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
163 DRM_IOCTL_DEF(DRM_IOCTL_MODE_DIRTYFB, drm_mode_dirtyfb_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
164 DRM_IOCTL_DEF(DRM_IOCTL_MODE_CREATE_DUMB, drm_mode_create_dumb_ioctl, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
165 DRM_IOCTL_DEF(DRM_IOCTL_MODE_MAP_DUMB, drm_mode_mmap_dumb_ioctl, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
166 DRM_IOCTL_DEF(DRM_IOCTL_MODE_DESTROY_DUMB, drm_mode_destroy_dumb_ioctl, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
167 DRM_IOCTL_DEF(DRM_IOCTL_MODE_OBJ_GETPROPERTIES, drm_mode_obj_get_properties_ioctl, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
168 DRM_IOCTL_DEF(DRM_IOCTL_MODE_OBJ_SETPROPERTY, drm_mode_obj_set_property_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
169 DRM_IOCTL_DEF(DRM_IOCTL_MODE_CURSOR2, drm_mode_cursor2_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
170};
171
172#define DRM_CORE_IOCTL_COUNT ARRAY_SIZE( drm_ioctls )
173
174/** File operations structure */
175static const struct file_operations drm_stub_fops = {
176 .owner = THIS_MODULE,
177 .open = drm_stub_open,
178 .llseek = noop_llseek,
179};
180
181static int __init drm_core_init(void)
182{
183 int ret = -ENOMEM;
184
185 drm_global_init();
186 drm_connector_ida_init();
187 idr_init(&drm_minors_idr);
188
189 if (register_chrdev(DRM_MAJOR, "drm", &drm_stub_fops))
190 goto err_p1;
191
192 drm_class = drm_sysfs_create(THIS_MODULE, "drm");
193 if (IS_ERR(drm_class)) {
194 printk(KERN_ERR "DRM: Error creating drm class.\n");
195 ret = PTR_ERR(drm_class);
196 goto err_p2;
197 }
198
199 drm_debugfs_root = debugfs_create_dir("dri", NULL);
200 if (!drm_debugfs_root) {
201 DRM_ERROR("Cannot create /sys/kernel/debug/dri\n");
202 ret = -1;
203 goto err_p3;
204 }
205
206 DRM_INFO("Initialized %s %d.%d.%d %s\n",
207 CORE_NAME, CORE_MAJOR, CORE_MINOR, CORE_PATCHLEVEL, CORE_DATE);
208 return 0;
209err_p3:
210 drm_sysfs_destroy();
211err_p2:
212 unregister_chrdev(DRM_MAJOR, "drm");
213
214 idr_destroy(&drm_minors_idr);
215err_p1:
216 return ret;
217}
218
219static void __exit drm_core_exit(void)
220{
221 debugfs_remove(drm_debugfs_root);
222 drm_sysfs_destroy();
223
224 unregister_chrdev(DRM_MAJOR, "drm");
225
226 drm_connector_ida_destroy();
227 idr_destroy(&drm_minors_idr);
228}
229
230module_init(drm_core_init);
231module_exit(drm_core_exit);
232
233/**
234 * Copy and IOCTL return string to user space
235 */
236static int drm_copy_field(char __user *buf, size_t *buf_len, const char *value)
237{
238 int len;
239
240 /* don't overflow userbuf */
241 len = strlen(value);
242 if (len > *buf_len)
243 len = *buf_len;
244
245 /* let userspace know exact length of driver value (which could be
246 * larger than the userspace-supplied buffer) */
247 *buf_len = strlen(value);
248
249 /* finally, try filling in the userbuf */
250 if (len && buf)
251 if (copy_to_user(buf, value, len))
252 return -EFAULT;
253 return 0;
254}
255
256/**
257 * Get version information
258 *
259 * \param inode device inode.
260 * \param filp file pointer.
261 * \param cmd command.
262 * \param arg user argument, pointing to a drm_version structure.
263 * \return zero on success or negative number on failure.
264 *
265 * Fills in the version information in \p arg.
266 */
267static int drm_version(struct drm_device *dev, void *data,
268 struct drm_file *file_priv)
269{
270 struct drm_version *version = data;
271 int err;
272
273 version->version_major = dev->driver->major;
274 version->version_minor = dev->driver->minor;
275 version->version_patchlevel = dev->driver->patchlevel;
276 err = drm_copy_field(version->name, &version->name_len,
277 dev->driver->name);
278 if (!err)
279 err = drm_copy_field(version->date, &version->date_len,
280 dev->driver->date);
281 if (!err)
282 err = drm_copy_field(version->desc, &version->desc_len,
283 dev->driver->desc);
284
285 return err;
286}
287
288/**
289 * drm_ioctl_permit - Check ioctl permissions against caller
290 *
291 * @flags: ioctl permission flags.
292 * @file_priv: Pointer to struct drm_file identifying the caller.
293 *
294 * Checks whether the caller is allowed to run an ioctl with the
295 * indicated permissions. If so, returns zero. Otherwise returns an
296 * error code suitable for ioctl return.
297 */
298static int drm_ioctl_permit(u32 flags, struct drm_file *file_priv)
299{
300 /* ROOT_ONLY is only for CAP_SYS_ADMIN */
301 if (unlikely((flags & DRM_ROOT_ONLY) && !capable(CAP_SYS_ADMIN)))
302 return -EACCES;
303
304 /* AUTH is only for authenticated or render client */
305 if (unlikely((flags & DRM_AUTH) && !drm_is_render_client(file_priv) &&
306 !file_priv->authenticated))
307 return -EACCES;
308
309 /* MASTER is only for master or control clients */
310 if (unlikely((flags & DRM_MASTER) && !file_priv->is_master &&
311 !drm_is_control_client(file_priv)))
312 return -EACCES;
313
314 /* Control clients must be explicitly allowed */
315 if (unlikely(!(flags & DRM_CONTROL_ALLOW) &&
316 drm_is_control_client(file_priv)))
317 return -EACCES;
318
319 /* Render clients must be explicitly allowed */
320 if (unlikely(!(flags & DRM_RENDER_ALLOW) &&
321 drm_is_render_client(file_priv)))
322 return -EACCES;
323
324 return 0;
325}
326
327/**
328 * Called whenever a process performs an ioctl on /dev/drm.
329 *
330 * \param inode device inode.
331 * \param file_priv DRM file private.
332 * \param cmd command.
333 * \param arg user argument.
334 * \return zero on success or negative number on failure.
335 *
336 * Looks up the ioctl function in the ::ioctls table, checking for root
337 * previleges if so required, and dispatches to the respective function.
338 */
339long drm_ioctl(struct file *filp,
340 unsigned int cmd, unsigned long arg)
341{
342 struct drm_file *file_priv = filp->private_data;
343 struct drm_device *dev;
344 const struct drm_ioctl_desc *ioctl = NULL;
345 drm_ioctl_t *func;
346 unsigned int nr = DRM_IOCTL_NR(cmd);
347 int retcode = -EINVAL;
348 char stack_kdata[128];
349 char *kdata = NULL;
350 unsigned int usize, asize;
351
352 dev = file_priv->minor->dev;
353
354 if (drm_device_is_unplugged(dev))
355 return -ENODEV;
356
357 if ((nr >= DRM_CORE_IOCTL_COUNT) &&
358 ((nr < DRM_COMMAND_BASE) || (nr >= DRM_COMMAND_END)))
359 goto err_i1;
360 if ((nr >= DRM_COMMAND_BASE) && (nr < DRM_COMMAND_END) &&
361 (nr < DRM_COMMAND_BASE + dev->driver->num_ioctls)) {
362 u32 drv_size;
363 ioctl = &dev->driver->ioctls[nr - DRM_COMMAND_BASE];
364 drv_size = _IOC_SIZE(ioctl->cmd_drv);
365 usize = asize = _IOC_SIZE(cmd);
366 if (drv_size > asize)
367 asize = drv_size;
368 cmd = ioctl->cmd_drv;
369 }
370 else if ((nr >= DRM_COMMAND_END) || (nr < DRM_COMMAND_BASE)) {
371 u32 drv_size;
372
373 ioctl = &drm_ioctls[nr];
374
375 drv_size = _IOC_SIZE(ioctl->cmd);
376 usize = asize = _IOC_SIZE(cmd);
377 if (drv_size > asize)
378 asize = drv_size;
379
380 cmd = ioctl->cmd;
381 } else
382 goto err_i1;
383
384 DRM_DEBUG("pid=%d, dev=0x%lx, auth=%d, %s\n",
385 task_pid_nr(current),
386 (long)old_encode_dev(file_priv->minor->kdev->devt),
387 file_priv->authenticated, ioctl->name);
388
389 /* Do not trust userspace, use our own definition */
390 func = ioctl->func;
391
392 if (unlikely(!func)) {
393 DRM_DEBUG("no function\n");
394 retcode = -EINVAL;
395 goto err_i1;
396 }
397
398 retcode = drm_ioctl_permit(ioctl->flags, file_priv);
399 if (unlikely(retcode))
400 goto err_i1;
401
402 if (cmd & (IOC_IN | IOC_OUT)) {
403 if (asize <= sizeof(stack_kdata)) {
404 kdata = stack_kdata;
405 } else {
406 kdata = kmalloc(asize, GFP_KERNEL);
407 if (!kdata) {
408 retcode = -ENOMEM;
409 goto err_i1;
410 }
411 }
412 if (asize > usize)
413 memset(kdata + usize, 0, asize - usize);
414 }
415
416 if (cmd & IOC_IN) {
417 if (copy_from_user(kdata, (void __user *)arg,
418 usize) != 0) {
419 retcode = -EFAULT;
420 goto err_i1;
421 }
422 } else if (cmd & IOC_OUT) {
423 memset(kdata, 0, usize);
424 }
425
426 if (ioctl->flags & DRM_UNLOCKED)
427 retcode = func(dev, kdata, file_priv);
428 else {
429 mutex_lock(&drm_global_mutex);
430 retcode = func(dev, kdata, file_priv);
431 mutex_unlock(&drm_global_mutex);
432 }
433
434 if (cmd & IOC_OUT) {
435 if (copy_to_user((void __user *)arg, kdata,
436 usize) != 0)
437 retcode = -EFAULT;
438 }
439
440 err_i1:
441 if (!ioctl)
442 DRM_DEBUG("invalid ioctl: pid=%d, dev=0x%lx, auth=%d, cmd=0x%02x, nr=0x%02x\n",
443 task_pid_nr(current),
444 (long)old_encode_dev(file_priv->minor->kdev->devt),
445 file_priv->authenticated, cmd, nr);
446
447 if (kdata != stack_kdata)
448 kfree(kdata);
449 if (retcode)
450 DRM_DEBUG("ret = %d\n", retcode);
451 return retcode;
452}
453EXPORT_SYMBOL(drm_ioctl);
454
455/**
456 * drm_ioctl_flags - Check for core ioctl and return ioctl permission flags
457 *
458 * @nr: Ioctl number.
459 * @flags: Where to return the ioctl permission flags
460 */
461bool drm_ioctl_flags(unsigned int nr, unsigned int *flags)
462{
463 if ((nr >= DRM_COMMAND_END && nr < DRM_CORE_IOCTL_COUNT) ||
464 (nr < DRM_COMMAND_BASE)) {
465 *flags = drm_ioctls[nr].flags;
466 return true;
467 }
468
469 return false;
470}
471EXPORT_SYMBOL(drm_ioctl_flags);
diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c
index 8f91062db5b6..4b060942cb3c 100644
--- a/drivers/gpu/drm/drm_fops.c
+++ b/drivers/gpu/drm/drm_fops.c
@@ -38,6 +38,7 @@
38#include <linux/poll.h> 38#include <linux/poll.h>
39#include <linux/slab.h> 39#include <linux/slab.h>
40#include <linux/module.h> 40#include <linux/module.h>
41#include "drm_legacy.h"
41 42
42/* from BKL pushdown */ 43/* from BKL pushdown */
43DEFINE_MUTEX(drm_global_mutex); 44DEFINE_MUTEX(drm_global_mutex);
@@ -112,45 +113,6 @@ err_undo:
112EXPORT_SYMBOL(drm_open); 113EXPORT_SYMBOL(drm_open);
113 114
114/** 115/**
115 * File \c open operation.
116 *
117 * \param inode device inode.
118 * \param filp file pointer.
119 *
120 * Puts the dev->fops corresponding to the device minor number into
121 * \p filp, call the \c open method, and restore the file operations.
122 */
123int drm_stub_open(struct inode *inode, struct file *filp)
124{
125 struct drm_device *dev;
126 struct drm_minor *minor;
127 int err = -ENODEV;
128 const struct file_operations *new_fops;
129
130 DRM_DEBUG("\n");
131
132 mutex_lock(&drm_global_mutex);
133 minor = drm_minor_acquire(iminor(inode));
134 if (IS_ERR(minor))
135 goto out_unlock;
136
137 dev = minor->dev;
138 new_fops = fops_get(dev->driver->fops);
139 if (!new_fops)
140 goto out_release;
141
142 replace_fops(filp, new_fops);
143 if (filp->f_op->open)
144 err = filp->f_op->open(inode, filp);
145
146out_release:
147 drm_minor_release(minor);
148out_unlock:
149 mutex_unlock(&drm_global_mutex);
150 return err;
151}
152
153/**
154 * Check whether DRI will run on this CPU. 116 * Check whether DRI will run on this CPU.
155 * 117 *
156 * \return non-zero if the DRI will run on this CPU, or zero otherwise. 118 * \return non-zero if the DRI will run on this CPU, or zero otherwise.
@@ -199,8 +161,7 @@ static int drm_open_helper(struct file *filp, struct drm_minor *minor)
199 priv->minor = minor; 161 priv->minor = minor;
200 162
201 /* for compatibility root is always authenticated */ 163 /* for compatibility root is always authenticated */
202 priv->always_authenticated = capable(CAP_SYS_ADMIN); 164 priv->authenticated = capable(CAP_SYS_ADMIN);
203 priv->authenticated = priv->always_authenticated;
204 priv->lock_count = 0; 165 priv->lock_count = 0;
205 166
206 INIT_LIST_HEAD(&priv->lhead); 167 INIT_LIST_HEAD(&priv->lhead);
@@ -233,7 +194,6 @@ static int drm_open_helper(struct file *filp, struct drm_minor *minor)
233 goto out_close; 194 goto out_close;
234 } 195 }
235 196
236 priv->is_master = 1;
237 /* take another reference for the copy in the local file priv */ 197 /* take another reference for the copy in the local file priv */
238 priv->master = drm_master_get(priv->minor->master); 198 priv->master = drm_master_get(priv->minor->master);
239 priv->authenticated = 1; 199 priv->authenticated = 1;
@@ -461,44 +421,18 @@ int drm_release(struct inode *inode, struct file *filp)
461 if (dev->driver->driver_features & DRIVER_GEM) 421 if (dev->driver->driver_features & DRIVER_GEM)
462 drm_gem_release(dev, file_priv); 422 drm_gem_release(dev, file_priv);
463 423
464 mutex_lock(&dev->ctxlist_mutex); 424 drm_legacy_ctxbitmap_flush(dev, file_priv);
465 if (!list_empty(&dev->ctxlist)) {
466 struct drm_ctx_list *pos, *n;
467
468 list_for_each_entry_safe(pos, n, &dev->ctxlist, head) {
469 if (pos->tag == file_priv &&
470 pos->handle != DRM_KERNEL_CONTEXT) {
471 if (dev->driver->context_dtor)
472 dev->driver->context_dtor(dev,
473 pos->handle);
474
475 drm_ctxbitmap_free(dev, pos->handle);
476
477 list_del(&pos->head);
478 kfree(pos);
479 }
480 }
481 }
482 mutex_unlock(&dev->ctxlist_mutex);
483 425
484 mutex_lock(&dev->master_mutex); 426 mutex_lock(&dev->master_mutex);
485 427
486 if (file_priv->is_master) { 428 if (drm_is_master(file_priv)) {
487 struct drm_master *master = file_priv->master; 429 struct drm_master *master = file_priv->master;
488 struct drm_file *temp;
489
490 mutex_lock(&dev->struct_mutex);
491 list_for_each_entry(temp, &dev->filelist, lhead) {
492 if ((temp->master == file_priv->master) &&
493 (temp != file_priv))
494 temp->authenticated = temp->always_authenticated;
495 }
496 430
497 /** 431 /**
498 * Since the master is disappearing, so is the 432 * Since the master is disappearing, so is the
499 * possibility to lock. 433 * possibility to lock.
500 */ 434 */
501 435 mutex_lock(&dev->struct_mutex);
502 if (master->lock.hw_lock) { 436 if (master->lock.hw_lock) {
503 if (dev->sigdata.lock == master->lock.hw_lock) 437 if (dev->sigdata.lock == master->lock.hw_lock)
504 dev->sigdata.lock = NULL; 438 dev->sigdata.lock = NULL;
@@ -519,7 +453,6 @@ int drm_release(struct inode *inode, struct file *filp)
519 /* drop the master reference held by the file priv */ 453 /* drop the master reference held by the file priv */
520 if (file_priv->master) 454 if (file_priv->master)
521 drm_master_put(&file_priv->master); 455 drm_master_put(&file_priv->master);
522 file_priv->is_master = 0;
523 mutex_unlock(&dev->master_mutex); 456 mutex_unlock(&dev->master_mutex);
524 457
525 if (dev->driver->postclose) 458 if (dev->driver->postclose)
diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c
index ad66f961170e..d3d1a8c72e98 100644
--- a/drivers/gpu/drm/drm_ioctl.c
+++ b/drivers/gpu/drm/drm_ioctl.c
@@ -1,11 +1,3 @@
1/**
2 * \file drm_ioctl.c
3 * IOCTL processing for DRM
4 *
5 * \author Rickard E. (Rik) Faith <faith@valinux.com>
6 * \author Gareth Hughes <gareth@valinux.com>
7 */
8
9/* 1/*
10 * Created: Fri Jan 8 09:01:26 1999 by faith@valinux.com 2 * Created: Fri Jan 8 09:01:26 1999 by faith@valinux.com
11 * 3 *
@@ -13,6 +5,9 @@
13 * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. 5 * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
14 * All Rights Reserved. 6 * All Rights Reserved.
15 * 7 *
8 * Author Rickard E. (Rik) Faith <faith@valinux.com>
9 * Author Gareth Hughes <gareth@valinux.com>
10 *
16 * Permission is hereby granted, free of charge, to any person obtaining a 11 * Permission is hereby granted, free of charge, to any person obtaining a
17 * copy of this software and associated documentation files (the "Software"), 12 * copy of this software and associated documentation files (the "Software"),
18 * to deal in the Software without restriction, including without limitation 13 * to deal in the Software without restriction, including without limitation
@@ -35,6 +30,7 @@
35 30
36#include <drm/drmP.h> 31#include <drm/drmP.h>
37#include <drm/drm_core.h> 32#include <drm/drm_core.h>
33#include "drm_legacy.h"
38 34
39#include <linux/pci.h> 35#include <linux/pci.h>
40#include <linux/export.h> 36#include <linux/export.h>
@@ -42,6 +38,124 @@
42#include <asm/mtrr.h> 38#include <asm/mtrr.h>
43#endif 39#endif
44 40
41static int drm_version(struct drm_device *dev, void *data,
42 struct drm_file *file_priv);
43
44#define DRM_IOCTL_DEF(ioctl, _func, _flags) \
45 [DRM_IOCTL_NR(ioctl)] = {.cmd = ioctl, .func = _func, .flags = _flags, .cmd_drv = 0, .name = #ioctl}
46
47/** Ioctl table */
48static const struct drm_ioctl_desc drm_ioctls[] = {
49 DRM_IOCTL_DEF(DRM_IOCTL_VERSION, drm_version, DRM_UNLOCKED|DRM_RENDER_ALLOW),
50 DRM_IOCTL_DEF(DRM_IOCTL_GET_UNIQUE, drm_getunique, 0),
51 DRM_IOCTL_DEF(DRM_IOCTL_GET_MAGIC, drm_getmagic, 0),
52 DRM_IOCTL_DEF(DRM_IOCTL_IRQ_BUSID, drm_irq_by_busid, DRM_MASTER|DRM_ROOT_ONLY),
53 DRM_IOCTL_DEF(DRM_IOCTL_GET_MAP, drm_getmap, DRM_UNLOCKED),
54 DRM_IOCTL_DEF(DRM_IOCTL_GET_CLIENT, drm_getclient, DRM_UNLOCKED),
55 DRM_IOCTL_DEF(DRM_IOCTL_GET_STATS, drm_getstats, DRM_UNLOCKED),
56 DRM_IOCTL_DEF(DRM_IOCTL_GET_CAP, drm_getcap, DRM_UNLOCKED|DRM_RENDER_ALLOW),
57 DRM_IOCTL_DEF(DRM_IOCTL_SET_CLIENT_CAP, drm_setclientcap, 0),
58 DRM_IOCTL_DEF(DRM_IOCTL_SET_VERSION, drm_setversion, DRM_MASTER),
59
60 DRM_IOCTL_DEF(DRM_IOCTL_SET_UNIQUE, drm_setunique, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
61 DRM_IOCTL_DEF(DRM_IOCTL_BLOCK, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
62 DRM_IOCTL_DEF(DRM_IOCTL_UNBLOCK, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
63 DRM_IOCTL_DEF(DRM_IOCTL_AUTH_MAGIC, drm_authmagic, DRM_AUTH|DRM_MASTER),
64
65 DRM_IOCTL_DEF(DRM_IOCTL_ADD_MAP, drm_addmap_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
66 DRM_IOCTL_DEF(DRM_IOCTL_RM_MAP, drm_rmmap_ioctl, DRM_AUTH),
67
68 DRM_IOCTL_DEF(DRM_IOCTL_SET_SAREA_CTX, drm_legacy_setsareactx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
69 DRM_IOCTL_DEF(DRM_IOCTL_GET_SAREA_CTX, drm_legacy_getsareactx, DRM_AUTH),
70
71 DRM_IOCTL_DEF(DRM_IOCTL_SET_MASTER, drm_setmaster_ioctl, DRM_ROOT_ONLY),
72 DRM_IOCTL_DEF(DRM_IOCTL_DROP_MASTER, drm_dropmaster_ioctl, DRM_ROOT_ONLY),
73
74 DRM_IOCTL_DEF(DRM_IOCTL_ADD_CTX, drm_legacy_addctx, DRM_AUTH|DRM_ROOT_ONLY),
75 DRM_IOCTL_DEF(DRM_IOCTL_RM_CTX, drm_legacy_rmctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
76 DRM_IOCTL_DEF(DRM_IOCTL_MOD_CTX, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
77 DRM_IOCTL_DEF(DRM_IOCTL_GET_CTX, drm_legacy_getctx, DRM_AUTH),
78 DRM_IOCTL_DEF(DRM_IOCTL_SWITCH_CTX, drm_legacy_switchctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
79 DRM_IOCTL_DEF(DRM_IOCTL_NEW_CTX, drm_legacy_newctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
80 DRM_IOCTL_DEF(DRM_IOCTL_RES_CTX, drm_legacy_resctx, DRM_AUTH),
81
82 DRM_IOCTL_DEF(DRM_IOCTL_ADD_DRAW, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
83 DRM_IOCTL_DEF(DRM_IOCTL_RM_DRAW, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
84
85 DRM_IOCTL_DEF(DRM_IOCTL_LOCK, drm_lock, DRM_AUTH),
86 DRM_IOCTL_DEF(DRM_IOCTL_UNLOCK, drm_unlock, DRM_AUTH),
87
88 DRM_IOCTL_DEF(DRM_IOCTL_FINISH, drm_noop, DRM_AUTH),
89
90 DRM_IOCTL_DEF(DRM_IOCTL_ADD_BUFS, drm_addbufs, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
91 DRM_IOCTL_DEF(DRM_IOCTL_MARK_BUFS, drm_markbufs, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
92 DRM_IOCTL_DEF(DRM_IOCTL_INFO_BUFS, drm_infobufs, DRM_AUTH),
93 DRM_IOCTL_DEF(DRM_IOCTL_MAP_BUFS, drm_mapbufs, DRM_AUTH),
94 DRM_IOCTL_DEF(DRM_IOCTL_FREE_BUFS, drm_freebufs, DRM_AUTH),
95 DRM_IOCTL_DEF(DRM_IOCTL_DMA, drm_dma_ioctl, DRM_AUTH),
96
97 DRM_IOCTL_DEF(DRM_IOCTL_CONTROL, drm_control, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
98
99#if __OS_HAS_AGP
100 DRM_IOCTL_DEF(DRM_IOCTL_AGP_ACQUIRE, drm_agp_acquire_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
101 DRM_IOCTL_DEF(DRM_IOCTL_AGP_RELEASE, drm_agp_release_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
102 DRM_IOCTL_DEF(DRM_IOCTL_AGP_ENABLE, drm_agp_enable_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
103 DRM_IOCTL_DEF(DRM_IOCTL_AGP_INFO, drm_agp_info_ioctl, DRM_AUTH),
104 DRM_IOCTL_DEF(DRM_IOCTL_AGP_ALLOC, drm_agp_alloc_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
105 DRM_IOCTL_DEF(DRM_IOCTL_AGP_FREE, drm_agp_free_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
106 DRM_IOCTL_DEF(DRM_IOCTL_AGP_BIND, drm_agp_bind_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
107 DRM_IOCTL_DEF(DRM_IOCTL_AGP_UNBIND, drm_agp_unbind_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
108#endif
109
110 DRM_IOCTL_DEF(DRM_IOCTL_SG_ALLOC, drm_sg_alloc, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
111 DRM_IOCTL_DEF(DRM_IOCTL_SG_FREE, drm_sg_free, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
112
113 DRM_IOCTL_DEF(DRM_IOCTL_WAIT_VBLANK, drm_wait_vblank, DRM_UNLOCKED),
114
115 DRM_IOCTL_DEF(DRM_IOCTL_MODESET_CTL, drm_modeset_ctl, 0),
116
117 DRM_IOCTL_DEF(DRM_IOCTL_UPDATE_DRAW, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
118
119 DRM_IOCTL_DEF(DRM_IOCTL_GEM_CLOSE, drm_gem_close_ioctl, DRM_UNLOCKED|DRM_RENDER_ALLOW),
120 DRM_IOCTL_DEF(DRM_IOCTL_GEM_FLINK, drm_gem_flink_ioctl, DRM_AUTH|DRM_UNLOCKED),
121 DRM_IOCTL_DEF(DRM_IOCTL_GEM_OPEN, drm_gem_open_ioctl, DRM_AUTH|DRM_UNLOCKED),
122
123 DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETRESOURCES, drm_mode_getresources, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
124
125 DRM_IOCTL_DEF(DRM_IOCTL_PRIME_HANDLE_TO_FD, drm_prime_handle_to_fd_ioctl, DRM_AUTH|DRM_UNLOCKED|DRM_RENDER_ALLOW),
126 DRM_IOCTL_DEF(DRM_IOCTL_PRIME_FD_TO_HANDLE, drm_prime_fd_to_handle_ioctl, DRM_AUTH|DRM_UNLOCKED|DRM_RENDER_ALLOW),
127
128 DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPLANERESOURCES, drm_mode_getplane_res, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
129 DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETCRTC, drm_mode_getcrtc, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
130 DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETCRTC, drm_mode_setcrtc, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
131 DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPLANE, drm_mode_getplane, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
132 DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETPLANE, drm_mode_setplane, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
133 DRM_IOCTL_DEF(DRM_IOCTL_MODE_CURSOR, drm_mode_cursor_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
134 DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETGAMMA, drm_mode_gamma_get_ioctl, DRM_UNLOCKED),
135 DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETGAMMA, drm_mode_gamma_set_ioctl, DRM_MASTER|DRM_UNLOCKED),
136 DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETENCODER, drm_mode_getencoder, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
137 DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETCONNECTOR, drm_mode_getconnector, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
138 DRM_IOCTL_DEF(DRM_IOCTL_MODE_ATTACHMODE, drm_noop, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
139 DRM_IOCTL_DEF(DRM_IOCTL_MODE_DETACHMODE, drm_noop, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
140 DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPROPERTY, drm_mode_getproperty_ioctl, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
141 DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETPROPERTY, drm_mode_connector_property_set_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
142 DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPROPBLOB, drm_mode_getblob_ioctl, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
143 DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETFB, drm_mode_getfb, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
144 DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDFB, drm_mode_addfb, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
145 DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDFB2, drm_mode_addfb2, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
146 DRM_IOCTL_DEF(DRM_IOCTL_MODE_RMFB, drm_mode_rmfb, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
147 DRM_IOCTL_DEF(DRM_IOCTL_MODE_PAGE_FLIP, drm_mode_page_flip_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
148 DRM_IOCTL_DEF(DRM_IOCTL_MODE_DIRTYFB, drm_mode_dirtyfb_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
149 DRM_IOCTL_DEF(DRM_IOCTL_MODE_CREATE_DUMB, drm_mode_create_dumb_ioctl, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
150 DRM_IOCTL_DEF(DRM_IOCTL_MODE_MAP_DUMB, drm_mode_mmap_dumb_ioctl, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
151 DRM_IOCTL_DEF(DRM_IOCTL_MODE_DESTROY_DUMB, drm_mode_destroy_dumb_ioctl, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
152 DRM_IOCTL_DEF(DRM_IOCTL_MODE_OBJ_GETPROPERTIES, drm_mode_obj_get_properties_ioctl, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
153 DRM_IOCTL_DEF(DRM_IOCTL_MODE_OBJ_SETPROPERTY, drm_mode_obj_set_property_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
154 DRM_IOCTL_DEF(DRM_IOCTL_MODE_CURSOR2, drm_mode_cursor2_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
155};
156
157#define DRM_CORE_IOCTL_COUNT ARRAY_SIZE( drm_ioctls )
158
45/** 159/**
46 * Get the bus id. 160 * Get the bus id.
47 * 161 *
@@ -415,3 +529,243 @@ int drm_noop(struct drm_device *dev, void *data,
415 return 0; 529 return 0;
416} 530}
417EXPORT_SYMBOL(drm_noop); 531EXPORT_SYMBOL(drm_noop);
532
533/**
534 * Copy and IOCTL return string to user space
535 */
536static int drm_copy_field(char __user *buf, size_t *buf_len, const char *value)
537{
538 int len;
539
540 /* don't overflow userbuf */
541 len = strlen(value);
542 if (len > *buf_len)
543 len = *buf_len;
544
545 /* let userspace know exact length of driver value (which could be
546 * larger than the userspace-supplied buffer) */
547 *buf_len = strlen(value);
548
549 /* finally, try filling in the userbuf */
550 if (len && buf)
551 if (copy_to_user(buf, value, len))
552 return -EFAULT;
553 return 0;
554}
555
556/**
557 * Get version information
558 *
559 * \param inode device inode.
560 * \param filp file pointer.
561 * \param cmd command.
562 * \param arg user argument, pointing to a drm_version structure.
563 * \return zero on success or negative number on failure.
564 *
565 * Fills in the version information in \p arg.
566 */
567static int drm_version(struct drm_device *dev, void *data,
568 struct drm_file *file_priv)
569{
570 struct drm_version *version = data;
571 int err;
572
573 version->version_major = dev->driver->major;
574 version->version_minor = dev->driver->minor;
575 version->version_patchlevel = dev->driver->patchlevel;
576 err = drm_copy_field(version->name, &version->name_len,
577 dev->driver->name);
578 if (!err)
579 err = drm_copy_field(version->date, &version->date_len,
580 dev->driver->date);
581 if (!err)
582 err = drm_copy_field(version->desc, &version->desc_len,
583 dev->driver->desc);
584
585 return err;
586}
587
588/**
589 * drm_ioctl_permit - Check ioctl permissions against caller
590 *
591 * @flags: ioctl permission flags.
592 * @file_priv: Pointer to struct drm_file identifying the caller.
593 *
594 * Checks whether the caller is allowed to run an ioctl with the
595 * indicated permissions. If so, returns zero. Otherwise returns an
596 * error code suitable for ioctl return.
597 */
598static int drm_ioctl_permit(u32 flags, struct drm_file *file_priv)
599{
600 /* ROOT_ONLY is only for CAP_SYS_ADMIN */
601 if (unlikely((flags & DRM_ROOT_ONLY) && !capable(CAP_SYS_ADMIN)))
602 return -EACCES;
603
604 /* AUTH is only for authenticated or render client */
605 if (unlikely((flags & DRM_AUTH) && !drm_is_render_client(file_priv) &&
606 !file_priv->authenticated))
607 return -EACCES;
608
609 /* MASTER is only for master or control clients */
610 if (unlikely((flags & DRM_MASTER) && !drm_is_master(file_priv) &&
611 !drm_is_control_client(file_priv)))
612 return -EACCES;
613
614 /* Control clients must be explicitly allowed */
615 if (unlikely(!(flags & DRM_CONTROL_ALLOW) &&
616 drm_is_control_client(file_priv)))
617 return -EACCES;
618
619 /* Render clients must be explicitly allowed */
620 if (unlikely(!(flags & DRM_RENDER_ALLOW) &&
621 drm_is_render_client(file_priv)))
622 return -EACCES;
623
624 return 0;
625}
626
627/**
628 * Called whenever a process performs an ioctl on /dev/drm.
629 *
630 * \param inode device inode.
631 * \param file_priv DRM file private.
632 * \param cmd command.
633 * \param arg user argument.
634 * \return zero on success or negative number on failure.
635 *
636 * Looks up the ioctl function in the ::ioctls table, checking for root
637 * previleges if so required, and dispatches to the respective function.
638 */
639long drm_ioctl(struct file *filp,
640 unsigned int cmd, unsigned long arg)
641{
642 struct drm_file *file_priv = filp->private_data;
643 struct drm_device *dev;
644 const struct drm_ioctl_desc *ioctl = NULL;
645 drm_ioctl_t *func;
646 unsigned int nr = DRM_IOCTL_NR(cmd);
647 int retcode = -EINVAL;
648 char stack_kdata[128];
649 char *kdata = NULL;
650 unsigned int usize, asize;
651
652 dev = file_priv->minor->dev;
653
654 if (drm_device_is_unplugged(dev))
655 return -ENODEV;
656
657 if ((nr >= DRM_CORE_IOCTL_COUNT) &&
658 ((nr < DRM_COMMAND_BASE) || (nr >= DRM_COMMAND_END)))
659 goto err_i1;
660 if ((nr >= DRM_COMMAND_BASE) && (nr < DRM_COMMAND_END) &&
661 (nr < DRM_COMMAND_BASE + dev->driver->num_ioctls)) {
662 u32 drv_size;
663 ioctl = &dev->driver->ioctls[nr - DRM_COMMAND_BASE];
664 drv_size = _IOC_SIZE(ioctl->cmd_drv);
665 usize = asize = _IOC_SIZE(cmd);
666 if (drv_size > asize)
667 asize = drv_size;
668 cmd = ioctl->cmd_drv;
669 }
670 else if ((nr >= DRM_COMMAND_END) || (nr < DRM_COMMAND_BASE)) {
671 u32 drv_size;
672
673 ioctl = &drm_ioctls[nr];
674
675 drv_size = _IOC_SIZE(ioctl->cmd);
676 usize = asize = _IOC_SIZE(cmd);
677 if (drv_size > asize)
678 asize = drv_size;
679
680 cmd = ioctl->cmd;
681 } else
682 goto err_i1;
683
684 DRM_DEBUG("pid=%d, dev=0x%lx, auth=%d, %s\n",
685 task_pid_nr(current),
686 (long)old_encode_dev(file_priv->minor->kdev->devt),
687 file_priv->authenticated, ioctl->name);
688
689 /* Do not trust userspace, use our own definition */
690 func = ioctl->func;
691
692 if (unlikely(!func)) {
693 DRM_DEBUG("no function\n");
694 retcode = -EINVAL;
695 goto err_i1;
696 }
697
698 retcode = drm_ioctl_permit(ioctl->flags, file_priv);
699 if (unlikely(retcode))
700 goto err_i1;
701
702 if (cmd & (IOC_IN | IOC_OUT)) {
703 if (asize <= sizeof(stack_kdata)) {
704 kdata = stack_kdata;
705 } else {
706 kdata = kmalloc(asize, GFP_KERNEL);
707 if (!kdata) {
708 retcode = -ENOMEM;
709 goto err_i1;
710 }
711 }
712 if (asize > usize)
713 memset(kdata + usize, 0, asize - usize);
714 }
715
716 if (cmd & IOC_IN) {
717 if (copy_from_user(kdata, (void __user *)arg,
718 usize) != 0) {
719 retcode = -EFAULT;
720 goto err_i1;
721 }
722 } else if (cmd & IOC_OUT) {
723 memset(kdata, 0, usize);
724 }
725
726 if (ioctl->flags & DRM_UNLOCKED)
727 retcode = func(dev, kdata, file_priv);
728 else {
729 mutex_lock(&drm_global_mutex);
730 retcode = func(dev, kdata, file_priv);
731 mutex_unlock(&drm_global_mutex);
732 }
733
734 if (cmd & IOC_OUT) {
735 if (copy_to_user((void __user *)arg, kdata,
736 usize) != 0)
737 retcode = -EFAULT;
738 }
739
740 err_i1:
741 if (!ioctl)
742 DRM_DEBUG("invalid ioctl: pid=%d, dev=0x%lx, auth=%d, cmd=0x%02x, nr=0x%02x\n",
743 task_pid_nr(current),
744 (long)old_encode_dev(file_priv->minor->kdev->devt),
745 file_priv->authenticated, cmd, nr);
746
747 if (kdata != stack_kdata)
748 kfree(kdata);
749 if (retcode)
750 DRM_DEBUG("ret = %d\n", retcode);
751 return retcode;
752}
753EXPORT_SYMBOL(drm_ioctl);
754
755/**
756 * drm_ioctl_flags - Check for core ioctl and return ioctl permission flags
757 *
758 * @nr: Ioctl number.
759 * @flags: Where to return the ioctl permission flags
760 */
761bool drm_ioctl_flags(unsigned int nr, unsigned int *flags)
762{
763 if ((nr >= DRM_COMMAND_END && nr < DRM_CORE_IOCTL_COUNT) ||
764 (nr < DRM_COMMAND_BASE)) {
765 *flags = drm_ioctls[nr].flags;
766 return true;
767 }
768
769 return false;
770}
771EXPORT_SYMBOL(drm_ioctl_flags);
diff --git a/drivers/gpu/drm/drm_legacy.h b/drivers/gpu/drm/drm_legacy.h
new file mode 100644
index 000000000000..d34f20a79b7c
--- /dev/null
+++ b/drivers/gpu/drm/drm_legacy.h
@@ -0,0 +1,51 @@
1#ifndef __DRM_LEGACY_H__
2#define __DRM_LEGACY_H__
3
4/*
5 * Copyright (c) 2014 David Herrmann <dh.herrmann@gmail.com>
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
21 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
22 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23 * OTHER DEALINGS IN THE SOFTWARE.
24 */
25
26struct drm_device;
27struct drm_file;
28
29/*
30 * Generic DRM Contexts
31 */
32
33#define DRM_KERNEL_CONTEXT 0
34#define DRM_RESERVED_CONTEXTS 1
35
36int drm_legacy_ctxbitmap_init(struct drm_device *dev);
37void drm_legacy_ctxbitmap_cleanup(struct drm_device *dev);
38void drm_legacy_ctxbitmap_free(struct drm_device *dev, int ctx_handle);
39void drm_legacy_ctxbitmap_flush(struct drm_device *dev, struct drm_file *file);
40
41int drm_legacy_resctx(struct drm_device *d, void *v, struct drm_file *f);
42int drm_legacy_addctx(struct drm_device *d, void *v, struct drm_file *f);
43int drm_legacy_getctx(struct drm_device *d, void *v, struct drm_file *f);
44int drm_legacy_switchctx(struct drm_device *d, void *v, struct drm_file *f);
45int drm_legacy_newctx(struct drm_device *d, void *v, struct drm_file *f);
46int drm_legacy_rmctx(struct drm_device *d, void *v, struct drm_file *f);
47
48int drm_legacy_setsareactx(struct drm_device *d, void *v, struct drm_file *f);
49int drm_legacy_getsareactx(struct drm_device *d, void *v, struct drm_file *f);
50
51#endif /* __DRM_LEGACY_H__ */
diff --git a/drivers/gpu/drm/drm_lock.c b/drivers/gpu/drm/drm_lock.c
index f6452682141b..ea1572596578 100644
--- a/drivers/gpu/drm/drm_lock.c
+++ b/drivers/gpu/drm/drm_lock.c
@@ -35,6 +35,7 @@
35 35
36#include <linux/export.h> 36#include <linux/export.h>
37#include <drm/drmP.h> 37#include <drm/drmP.h>
38#include "drm_legacy.h"
38 39
39static int drm_notifier(void *priv); 40static int drm_notifier(void *priv);
40 41
@@ -111,7 +112,7 @@ int drm_lock(struct drm_device *dev, void *data, struct drm_file *file_priv)
111 /* don't set the block all signals on the master process for now 112 /* don't set the block all signals on the master process for now
112 * really probably not the correct answer but lets us debug xkb 113 * really probably not the correct answer but lets us debug xkb
113 * xserver for now */ 114 * xserver for now */
114 if (!file_priv->is_master) { 115 if (!drm_is_master(file_priv)) {
115 sigemptyset(&dev->sigmask); 116 sigemptyset(&dev->sigmask);
116 sigaddset(&dev->sigmask, SIGSTOP); 117 sigaddset(&dev->sigmask, SIGSTOP);
117 sigaddset(&dev->sigmask, SIGTSTP); 118 sigaddset(&dev->sigmask, SIGTSTP);
diff --git a/drivers/gpu/drm/drm_stub.c b/drivers/gpu/drm/drm_stub.c
index 233ea208c9fe..92bc6b1d9646 100644
--- a/drivers/gpu/drm/drm_stub.c
+++ b/drivers/gpu/drm/drm_stub.c
@@ -26,6 +26,7 @@
26 * DEALINGS IN THE SOFTWARE. 26 * DEALINGS IN THE SOFTWARE.
27 */ 27 */
28 28
29#include <linux/debugfs.h>
29#include <linux/fs.h> 30#include <linux/fs.h>
30#include <linux/module.h> 31#include <linux/module.h>
31#include <linux/moduleparam.h> 32#include <linux/moduleparam.h>
@@ -33,6 +34,7 @@
33#include <linux/slab.h> 34#include <linux/slab.h>
34#include <drm/drmP.h> 35#include <drm/drmP.h>
35#include <drm/drm_core.h> 36#include <drm/drm_core.h>
37#include "drm_legacy.h"
36 38
37unsigned int drm_debug = 0; /* 1 to enable debug output */ 39unsigned int drm_debug = 0; /* 1 to enable debug output */
38EXPORT_SYMBOL(drm_debug); 40EXPORT_SYMBOL(drm_debug);
@@ -61,10 +63,10 @@ module_param_named(timestamp_precision_usec, drm_timestamp_precision, int, 0600)
61module_param_named(timestamp_monotonic, drm_timestamp_monotonic, int, 0600); 63module_param_named(timestamp_monotonic, drm_timestamp_monotonic, int, 0600);
62 64
63static DEFINE_SPINLOCK(drm_minor_lock); 65static DEFINE_SPINLOCK(drm_minor_lock);
64struct idr drm_minors_idr; 66static struct idr drm_minors_idr;
65 67
66struct class *drm_class; 68struct class *drm_class;
67struct dentry *drm_debugfs_root; 69static struct dentry *drm_debugfs_root;
68 70
69int drm_err(const char *func, const char *format, ...) 71int drm_err(const char *func, const char *format, ...)
70{ 72{
@@ -177,7 +179,7 @@ int drm_setmaster_ioctl(struct drm_device *dev, void *data,
177 int ret = 0; 179 int ret = 0;
178 180
179 mutex_lock(&dev->master_mutex); 181 mutex_lock(&dev->master_mutex);
180 if (file_priv->is_master) 182 if (drm_is_master(file_priv))
181 goto out_unlock; 183 goto out_unlock;
182 184
183 if (file_priv->minor->master) { 185 if (file_priv->minor->master) {
@@ -191,13 +193,10 @@ int drm_setmaster_ioctl(struct drm_device *dev, void *data,
191 } 193 }
192 194
193 file_priv->minor->master = drm_master_get(file_priv->master); 195 file_priv->minor->master = drm_master_get(file_priv->master);
194 file_priv->is_master = 1;
195 if (dev->driver->master_set) { 196 if (dev->driver->master_set) {
196 ret = dev->driver->master_set(dev, file_priv, false); 197 ret = dev->driver->master_set(dev, file_priv, false);
197 if (unlikely(ret != 0)) { 198 if (unlikely(ret != 0))
198 file_priv->is_master = 0;
199 drm_master_put(&file_priv->minor->master); 199 drm_master_put(&file_priv->minor->master);
200 }
201 } 200 }
202 201
203out_unlock: 202out_unlock:
@@ -211,7 +210,7 @@ int drm_dropmaster_ioctl(struct drm_device *dev, void *data,
211 int ret = -EINVAL; 210 int ret = -EINVAL;
212 211
213 mutex_lock(&dev->master_mutex); 212 mutex_lock(&dev->master_mutex);
214 if (!file_priv->is_master) 213 if (!drm_is_master(file_priv))
215 goto out_unlock; 214 goto out_unlock;
216 215
217 if (!file_priv->minor->master) 216 if (!file_priv->minor->master)
@@ -221,7 +220,6 @@ int drm_dropmaster_ioctl(struct drm_device *dev, void *data,
221 if (dev->driver->master_drop) 220 if (dev->driver->master_drop)
222 dev->driver->master_drop(dev, file_priv, false); 221 dev->driver->master_drop(dev, file_priv, false);
223 drm_master_put(&file_priv->minor->master); 222 drm_master_put(&file_priv->minor->master);
224 file_priv->is_master = 0;
225 223
226out_unlock: 224out_unlock:
227 mutex_unlock(&dev->master_mutex); 225 mutex_unlock(&dev->master_mutex);
@@ -259,6 +257,8 @@ static struct drm_minor **drm_minor_get_slot(struct drm_device *dev,
259static int drm_minor_alloc(struct drm_device *dev, unsigned int type) 257static int drm_minor_alloc(struct drm_device *dev, unsigned int type)
260{ 258{
261 struct drm_minor *minor; 259 struct drm_minor *minor;
260 unsigned long flags;
261 int r;
262 262
263 minor = kzalloc(sizeof(*minor), GFP_KERNEL); 263 minor = kzalloc(sizeof(*minor), GFP_KERNEL);
264 if (!minor) 264 if (!minor)
@@ -267,77 +267,92 @@ static int drm_minor_alloc(struct drm_device *dev, unsigned int type)
267 minor->type = type; 267 minor->type = type;
268 minor->dev = dev; 268 minor->dev = dev;
269 269
270 idr_preload(GFP_KERNEL);
271 spin_lock_irqsave(&drm_minor_lock, flags);
272 r = idr_alloc(&drm_minors_idr,
273 NULL,
274 64 * type,
275 64 * (type + 1),
276 GFP_NOWAIT);
277 spin_unlock_irqrestore(&drm_minor_lock, flags);
278 idr_preload_end();
279
280 if (r < 0)
281 goto err_free;
282
283 minor->index = r;
284
285 minor->kdev = drm_sysfs_minor_alloc(minor);
286 if (IS_ERR(minor->kdev)) {
287 r = PTR_ERR(minor->kdev);
288 goto err_index;
289 }
290
270 *drm_minor_get_slot(dev, type) = minor; 291 *drm_minor_get_slot(dev, type) = minor;
271 return 0; 292 return 0;
293
294err_index:
295 spin_lock_irqsave(&drm_minor_lock, flags);
296 idr_remove(&drm_minors_idr, minor->index);
297 spin_unlock_irqrestore(&drm_minor_lock, flags);
298err_free:
299 kfree(minor);
300 return r;
272} 301}
273 302
274static void drm_minor_free(struct drm_device *dev, unsigned int type) 303static void drm_minor_free(struct drm_device *dev, unsigned int type)
275{ 304{
276 struct drm_minor **slot; 305 struct drm_minor **slot, *minor;
306 unsigned long flags;
277 307
278 slot = drm_minor_get_slot(dev, type); 308 slot = drm_minor_get_slot(dev, type);
279 if (*slot) { 309 minor = *slot;
280 drm_mode_group_destroy(&(*slot)->mode_group); 310 if (!minor)
281 kfree(*slot); 311 return;
282 *slot = NULL; 312
283 } 313 drm_mode_group_destroy(&minor->mode_group);
314 put_device(minor->kdev);
315
316 spin_lock_irqsave(&drm_minor_lock, flags);
317 idr_remove(&drm_minors_idr, minor->index);
318 spin_unlock_irqrestore(&drm_minor_lock, flags);
319
320 kfree(minor);
321 *slot = NULL;
284} 322}
285 323
286static int drm_minor_register(struct drm_device *dev, unsigned int type) 324static int drm_minor_register(struct drm_device *dev, unsigned int type)
287{ 325{
288 struct drm_minor *new_minor; 326 struct drm_minor *minor;
289 unsigned long flags; 327 unsigned long flags;
290 int ret; 328 int ret;
291 int minor_id;
292 329
293 DRM_DEBUG("\n"); 330 DRM_DEBUG("\n");
294 331
295 new_minor = *drm_minor_get_slot(dev, type); 332 minor = *drm_minor_get_slot(dev, type);
296 if (!new_minor) 333 if (!minor)
297 return 0; 334 return 0;
298 335
299 idr_preload(GFP_KERNEL); 336 ret = drm_debugfs_init(minor, minor->index, drm_debugfs_root);
300 spin_lock_irqsave(&drm_minor_lock, flags);
301 minor_id = idr_alloc(&drm_minors_idr,
302 NULL,
303 64 * type,
304 64 * (type + 1),
305 GFP_NOWAIT);
306 spin_unlock_irqrestore(&drm_minor_lock, flags);
307 idr_preload_end();
308
309 if (minor_id < 0)
310 return minor_id;
311
312 new_minor->index = minor_id;
313
314 ret = drm_debugfs_init(new_minor, minor_id, drm_debugfs_root);
315 if (ret) { 337 if (ret) {
316 DRM_ERROR("DRM: Failed to initialize /sys/kernel/debug/dri.\n"); 338 DRM_ERROR("DRM: Failed to initialize /sys/kernel/debug/dri.\n");
317 goto err_id; 339 return ret;
318 } 340 }
319 341
320 ret = drm_sysfs_device_add(new_minor); 342 ret = device_add(minor->kdev);
321 if (ret) { 343 if (ret)
322 DRM_ERROR("DRM: Error sysfs_device_add.\n");
323 goto err_debugfs; 344 goto err_debugfs;
324 }
325 345
326 /* replace NULL with @minor so lookups will succeed from now on */ 346 /* replace NULL with @minor so lookups will succeed from now on */
327 spin_lock_irqsave(&drm_minor_lock, flags); 347 spin_lock_irqsave(&drm_minor_lock, flags);
328 idr_replace(&drm_minors_idr, new_minor, new_minor->index); 348 idr_replace(&drm_minors_idr, minor, minor->index);
329 spin_unlock_irqrestore(&drm_minor_lock, flags); 349 spin_unlock_irqrestore(&drm_minor_lock, flags);
330 350
331 DRM_DEBUG("new minor assigned %d\n", minor_id); 351 DRM_DEBUG("new minor registered %d\n", minor->index);
332 return 0; 352 return 0;
333 353
334err_debugfs: 354err_debugfs:
335 drm_debugfs_cleanup(new_minor); 355 drm_debugfs_cleanup(minor);
336err_id:
337 spin_lock_irqsave(&drm_minor_lock, flags);
338 idr_remove(&drm_minors_idr, minor_id);
339 spin_unlock_irqrestore(&drm_minor_lock, flags);
340 new_minor->index = 0;
341 return ret; 356 return ret;
342} 357}
343 358
@@ -347,16 +362,17 @@ static void drm_minor_unregister(struct drm_device *dev, unsigned int type)
347 unsigned long flags; 362 unsigned long flags;
348 363
349 minor = *drm_minor_get_slot(dev, type); 364 minor = *drm_minor_get_slot(dev, type);
350 if (!minor || !minor->kdev) 365 if (!minor || !device_is_registered(minor->kdev))
351 return; 366 return;
352 367
368 /* replace @minor with NULL so lookups will fail from now on */
353 spin_lock_irqsave(&drm_minor_lock, flags); 369 spin_lock_irqsave(&drm_minor_lock, flags);
354 idr_remove(&drm_minors_idr, minor->index); 370 idr_replace(&drm_minors_idr, NULL, minor->index);
355 spin_unlock_irqrestore(&drm_minor_lock, flags); 371 spin_unlock_irqrestore(&drm_minor_lock, flags);
356 minor->index = 0;
357 372
373 device_del(minor->kdev);
374 dev_set_drvdata(minor->kdev, NULL); /* safety belt */
358 drm_debugfs_cleanup(minor); 375 drm_debugfs_cleanup(minor);
359 drm_sysfs_device_remove(minor);
360} 376}
361 377
362/** 378/**
@@ -589,7 +605,7 @@ struct drm_device *drm_dev_alloc(struct drm_driver *driver,
589 if (drm_ht_create(&dev->map_hash, 12)) 605 if (drm_ht_create(&dev->map_hash, 12))
590 goto err_minors; 606 goto err_minors;
591 607
592 ret = drm_ctxbitmap_init(dev); 608 ret = drm_legacy_ctxbitmap_init(dev);
593 if (ret) { 609 if (ret) {
594 DRM_ERROR("Cannot allocate memory for context bitmap.\n"); 610 DRM_ERROR("Cannot allocate memory for context bitmap.\n");
595 goto err_ht; 611 goto err_ht;
@@ -606,7 +622,7 @@ struct drm_device *drm_dev_alloc(struct drm_driver *driver,
606 return dev; 622 return dev;
607 623
608err_ctxbitmap: 624err_ctxbitmap:
609 drm_ctxbitmap_cleanup(dev); 625 drm_legacy_ctxbitmap_cleanup(dev);
610err_ht: 626err_ht:
611 drm_ht_remove(&dev->map_hash); 627 drm_ht_remove(&dev->map_hash);
612err_minors: 628err_minors:
@@ -628,7 +644,7 @@ static void drm_dev_release(struct kref *ref)
628 if (dev->driver->driver_features & DRIVER_GEM) 644 if (dev->driver->driver_features & DRIVER_GEM)
629 drm_gem_destroy(dev); 645 drm_gem_destroy(dev);
630 646
631 drm_ctxbitmap_cleanup(dev); 647 drm_legacy_ctxbitmap_cleanup(dev);
632 drm_ht_remove(&dev->map_hash); 648 drm_ht_remove(&dev->map_hash);
633 drm_fs_inode_free(dev->anon_inode); 649 drm_fs_inode_free(dev->anon_inode);
634 650
@@ -791,3 +807,115 @@ int drm_dev_set_unique(struct drm_device *dev, const char *fmt, ...)
791 return dev->unique ? 0 : -ENOMEM; 807 return dev->unique ? 0 : -ENOMEM;
792} 808}
793EXPORT_SYMBOL(drm_dev_set_unique); 809EXPORT_SYMBOL(drm_dev_set_unique);
810
811/*
812 * DRM Core
813 * The DRM core module initializes all global DRM objects and makes them
814 * available to drivers. Once setup, drivers can probe their respective
815 * devices.
816 * Currently, core management includes:
817 * - The "DRM-Global" key/value database
818 * - Global ID management for connectors
819 * - DRM major number allocation
820 * - DRM minor management
821 * - DRM sysfs class
822 * - DRM debugfs root
823 *
824 * Furthermore, the DRM core provides dynamic char-dev lookups. For each
825 * interface registered on a DRM device, you can request minor numbers from DRM
826 * core. DRM core takes care of major-number management and char-dev
827 * registration. A stub ->open() callback forwards any open() requests to the
828 * registered minor.
829 */
830
831static int drm_stub_open(struct inode *inode, struct file *filp)
832{
833 const struct file_operations *new_fops;
834 struct drm_minor *minor;
835 int err;
836
837 DRM_DEBUG("\n");
838
839 mutex_lock(&drm_global_mutex);
840 minor = drm_minor_acquire(iminor(inode));
841 if (IS_ERR(minor)) {
842 err = PTR_ERR(minor);
843 goto out_unlock;
844 }
845
846 new_fops = fops_get(minor->dev->driver->fops);
847 if (!new_fops) {
848 err = -ENODEV;
849 goto out_release;
850 }
851
852 replace_fops(filp, new_fops);
853 if (filp->f_op->open)
854 err = filp->f_op->open(inode, filp);
855 else
856 err = 0;
857
858out_release:
859 drm_minor_release(minor);
860out_unlock:
861 mutex_unlock(&drm_global_mutex);
862 return err;
863}
864
865static const struct file_operations drm_stub_fops = {
866 .owner = THIS_MODULE,
867 .open = drm_stub_open,
868 .llseek = noop_llseek,
869};
870
871static int __init drm_core_init(void)
872{
873 int ret = -ENOMEM;
874
875 drm_global_init();
876 drm_connector_ida_init();
877 idr_init(&drm_minors_idr);
878
879 if (register_chrdev(DRM_MAJOR, "drm", &drm_stub_fops))
880 goto err_p1;
881
882 drm_class = drm_sysfs_create(THIS_MODULE, "drm");
883 if (IS_ERR(drm_class)) {
884 printk(KERN_ERR "DRM: Error creating drm class.\n");
885 ret = PTR_ERR(drm_class);
886 goto err_p2;
887 }
888
889 drm_debugfs_root = debugfs_create_dir("dri", NULL);
890 if (!drm_debugfs_root) {
891 DRM_ERROR("Cannot create /sys/kernel/debug/dri\n");
892 ret = -1;
893 goto err_p3;
894 }
895
896 DRM_INFO("Initialized %s %d.%d.%d %s\n",
897 CORE_NAME, CORE_MAJOR, CORE_MINOR, CORE_PATCHLEVEL, CORE_DATE);
898 return 0;
899err_p3:
900 drm_sysfs_destroy();
901err_p2:
902 unregister_chrdev(DRM_MAJOR, "drm");
903
904 idr_destroy(&drm_minors_idr);
905err_p1:
906 return ret;
907}
908
909static void __exit drm_core_exit(void)
910{
911 debugfs_remove(drm_debugfs_root);
912 drm_sysfs_destroy();
913
914 unregister_chrdev(DRM_MAJOR, "drm");
915
916 drm_connector_ida_destroy();
917 idr_destroy(&drm_minors_idr);
918}
919
920module_init(drm_core_init);
921module_exit(drm_core_exit);
diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c
index 7827dad8fcf4..ab1a5f6dde8a 100644
--- a/drivers/gpu/drm/drm_sysfs.c
+++ b/drivers/gpu/drm/drm_sysfs.c
@@ -493,71 +493,55 @@ static void drm_sysfs_release(struct device *dev)
493} 493}
494 494
495/** 495/**
496 * drm_sysfs_device_add - adds a class device to sysfs for a character driver 496 * drm_sysfs_minor_alloc() - Allocate sysfs device for given minor
497 * @dev: DRM device to be added 497 * @minor: minor to allocate sysfs device for
498 * @head: DRM head in question
499 * 498 *
500 * Add a DRM device to the DRM's device model class. We use @dev's PCI device 499 * This allocates a new sysfs device for @minor and returns it. The device is
501 * as the parent for the Linux device, and make sure it has a file containing 500 * not registered nor linked. The caller has to use device_add() and
502 * the driver we're using (for userspace compatibility). 501 * device_del() to register and unregister it.
502 *
503 * Note that dev_get_drvdata() on the new device will return the minor.
504 * However, the device does not hold a ref-count to the minor nor to the
505 * underlying drm_device. This is unproblematic as long as you access the
506 * private data only in sysfs callbacks. device_del() disables those
507 * synchronously, so they cannot be called after you cleanup a minor.
503 */ 508 */
504int drm_sysfs_device_add(struct drm_minor *minor) 509struct device *drm_sysfs_minor_alloc(struct drm_minor *minor)
505{ 510{
506 char *minor_str; 511 const char *minor_str;
512 struct device *kdev;
507 int r; 513 int r;
508 514
509 if (minor->type == DRM_MINOR_CONTROL) 515 if (minor->type == DRM_MINOR_CONTROL)
510 minor_str = "controlD%d"; 516 minor_str = "controlD%d";
511 else if (minor->type == DRM_MINOR_RENDER) 517 else if (minor->type == DRM_MINOR_RENDER)
512 minor_str = "renderD%d"; 518 minor_str = "renderD%d";
513 else 519 else
514 minor_str = "card%d"; 520 minor_str = "card%d";
515 521
516 minor->kdev = kzalloc(sizeof(*minor->kdev), GFP_KERNEL); 522 kdev = kzalloc(sizeof(*kdev), GFP_KERNEL);
517 if (!minor->kdev) { 523 if (!kdev)
518 r = -ENOMEM; 524 return ERR_PTR(-ENOMEM);
519 goto error; 525
520 } 526 device_initialize(kdev);
521 527 kdev->devt = MKDEV(DRM_MAJOR, minor->index);
522 device_initialize(minor->kdev); 528 kdev->class = drm_class;
523 minor->kdev->devt = MKDEV(DRM_MAJOR, minor->index); 529 kdev->type = &drm_sysfs_device_minor;
524 minor->kdev->class = drm_class; 530 kdev->parent = minor->dev->dev;
525 minor->kdev->type = &drm_sysfs_device_minor; 531 kdev->release = drm_sysfs_release;
526 minor->kdev->parent = minor->dev->dev; 532 dev_set_drvdata(kdev, minor);
527 minor->kdev->release = drm_sysfs_release; 533
528 dev_set_drvdata(minor->kdev, minor); 534 r = dev_set_name(kdev, minor_str, minor->index);
529
530 r = dev_set_name(minor->kdev, minor_str, minor->index);
531 if (r < 0) 535 if (r < 0)
532 goto error; 536 goto err_free;
533
534 r = device_add(minor->kdev);
535 if (r < 0)
536 goto error;
537
538 return 0;
539 537
540error: 538 return kdev;
541 DRM_ERROR("device create failed %d\n", r);
542 put_device(minor->kdev);
543 return r;
544}
545 539
546/** 540err_free:
547 * drm_sysfs_device_remove - remove DRM device 541 put_device(kdev);
548 * @dev: DRM device to remove 542 return ERR_PTR(r);
549 *
550 * This call unregisters and cleans up a class device that was created with a
551 * call to drm_sysfs_device_add()
552 */
553void drm_sysfs_device_remove(struct drm_minor *minor)
554{
555 if (minor->kdev)
556 device_unregister(minor->kdev);
557 minor->kdev = NULL;
558} 543}
559 544
560
561/** 545/**
562 * drm_class_device_register - Register a struct device in the drm class. 546 * drm_class_device_register - Register a struct device in the drm class.
563 * 547 *
diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
index 60998fc4e5b2..2dd19da6b4b3 100644
--- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
@@ -1260,7 +1260,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
1260 1260
1261 flags = 0; 1261 flags = 0;
1262 if (args->flags & I915_EXEC_SECURE) { 1262 if (args->flags & I915_EXEC_SECURE) {
1263 if (!file->is_master || !capable(CAP_SYS_ADMIN)) 1263 if (!drm_is_master(file) || !capable(CAP_SYS_ADMIN))
1264 return -EPERM; 1264 return -EPERM;
1265 1265
1266 flags |= I915_DISPATCH_SECURE; 1266 flags |= I915_DISPATCH_SECURE;
@@ -1369,7 +1369,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
1369 ret = i915_parse_cmds(ring, 1369 ret = i915_parse_cmds(ring,
1370 batch_obj, 1370 batch_obj,
1371 args->batch_start_offset, 1371 args->batch_start_offset,
1372 file->is_master); 1372 drm_is_master(file));
1373 if (ret) 1373 if (ret)
1374 goto err; 1374 goto err;
1375 1375
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
index 18b54acacfbb..63c4d6f0281e 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
@@ -990,7 +990,7 @@ static struct vmw_master *vmw_master_check(struct drm_device *dev,
990 if (unlikely(ret != 0)) 990 if (unlikely(ret != 0))
991 return ERR_PTR(-ERESTARTSYS); 991 return ERR_PTR(-ERESTARTSYS);
992 992
993 if (file_priv->is_master) { 993 if (drm_is_master(file_priv)) {
994 mutex_unlock(&dev->master_mutex); 994 mutex_unlock(&dev->master_mutex);
995 return NULL; 995 return NULL;
996 } 996 }
diff --git a/drivers/staging/imx-drm/imx-drm-core.c b/drivers/staging/imx-drm/imx-drm-core.c
index 6f54ff4f9372..72913b299047 100644
--- a/drivers/staging/imx-drm/imx-drm-core.c
+++ b/drivers/staging/imx-drm/imx-drm-core.c
@@ -182,7 +182,7 @@ static void imx_drm_driver_preclose(struct drm_device *drm,
182{ 182{
183 int i; 183 int i;
184 184
185 if (!file->is_master) 185 if (!drm_is_master(file))
186 return; 186 return;
187 187
188 for (i = 0; i < MAX_CRTC; i++) 188 for (i = 0; i < MAX_CRTC; i++)
diff --git a/include/drm/drmP.h b/include/drm/drmP.h
index d3d9be6b83ef..a57646382086 100644
--- a/include/drm/drmP.h
+++ b/include/drm/drmP.h
@@ -151,8 +151,6 @@ int drm_err(const char *func, const char *format, ...);
151 also include looping detection. */ 151 also include looping detection. */
152 152
153#define DRM_MAGIC_HASH_ORDER 4 /**< Size of key hash table. Must be power of 2. */ 153#define DRM_MAGIC_HASH_ORDER 4 /**< Size of key hash table. Must be power of 2. */
154#define DRM_KERNEL_CONTEXT 0 /**< Change drm_resctx if changed */
155#define DRM_RESERVED_CONTEXTS 1 /**< Change drm_resctx if changed */
156 154
157#define DRM_MAP_HASH_OFFSET 0x10000000 155#define DRM_MAP_HASH_OFFSET 0x10000000
158 156
@@ -385,10 +383,7 @@ struct drm_prime_file_private {
385 383
386/** File private data */ 384/** File private data */
387struct drm_file { 385struct drm_file {
388 unsigned always_authenticated :1;
389 unsigned authenticated :1; 386 unsigned authenticated :1;
390 /* Whether we're master for a minor. Protected by master_mutex */
391 unsigned is_master :1;
392 /* true when the client has asked us to expose stereo 3D mode flags */ 387 /* true when the client has asked us to expose stereo 3D mode flags */
393 unsigned stereo_allowed :1; 388 unsigned stereo_allowed :1;
394 /* 389 /*
@@ -538,15 +533,6 @@ struct drm_map_list {
538 struct drm_master *master; 533 struct drm_master *master;
539}; 534};
540 535
541/**
542 * Context handle list
543 */
544struct drm_ctx_list {
545 struct list_head head; /**< list head */
546 drm_context_t handle; /**< context handle */
547 struct drm_file *tag; /**< associated fd private data */
548};
549
550/* location of GART table */ 536/* location of GART table */
551#define DRM_ATI_GART_MAIN 1 537#define DRM_ATI_GART_MAIN 1
552#define DRM_ATI_GART_FB 2 538#define DRM_ATI_GART_FB 2
@@ -1034,7 +1020,7 @@ struct drm_device {
1034 /** \name Locks */ 1020 /** \name Locks */
1035 /*@{ */ 1021 /*@{ */
1036 struct mutex struct_mutex; /**< For others */ 1022 struct mutex struct_mutex; /**< For others */
1037 struct mutex master_mutex; /**< For drm_minor::master and drm_file::is_master */ 1023 struct mutex master_mutex; /**< For drm_minor::master */
1038 /*@} */ 1024 /*@} */
1039 1025
1040 /** \name Usage Counters */ 1026 /** \name Usage Counters */
@@ -1172,6 +1158,21 @@ static inline bool drm_is_primary_client(const struct drm_file *file_priv)
1172 return file_priv->minor->type == DRM_MINOR_LEGACY; 1158 return file_priv->minor->type == DRM_MINOR_LEGACY;
1173} 1159}
1174 1160
1161/**
1162 * drm_is_master() - Check whether a DRM open-file is DRM-Master
1163 * @file: DRM open-file context
1164 *
1165 * This checks whether a DRM open-file context is owner of the master context
1166 * attached to it. If a file owns a master context, it's called DRM-Master.
1167 * Per DRM device, only one such file can be DRM-Master at a time.
1168 *
1169 * Returns: True if the file is DRM-Master, otherwise false.
1170 */
1171static inline bool drm_is_master(const struct drm_file *file)
1172{
1173 return file->master && file->master == file->minor->master;
1174}
1175
1175/******************************************************************/ 1176/******************************************************************/
1176/** \name Internal function definitions */ 1177/** \name Internal function definitions */
1177/*@{*/ 1178/*@{*/
@@ -1187,7 +1188,6 @@ extern bool drm_ioctl_flags(unsigned int nr, unsigned int *flags);
1187 /* Device support (drm_fops.h) */ 1188 /* Device support (drm_fops.h) */
1188extern struct mutex drm_global_mutex; 1189extern struct mutex drm_global_mutex;
1189extern int drm_open(struct inode *inode, struct file *filp); 1190extern int drm_open(struct inode *inode, struct file *filp);
1190extern int drm_stub_open(struct inode *inode, struct file *filp);
1191extern ssize_t drm_read(struct file *filp, char __user *buffer, 1191extern ssize_t drm_read(struct file *filp, char __user *buffer,
1192 size_t count, loff_t *offset); 1192 size_t count, loff_t *offset);
1193extern int drm_release(struct inode *inode, struct file *filp); 1193extern int drm_release(struct inode *inode, struct file *filp);
@@ -1225,29 +1225,6 @@ extern int drm_setversion(struct drm_device *dev, void *data,
1225extern int drm_noop(struct drm_device *dev, void *data, 1225extern int drm_noop(struct drm_device *dev, void *data,
1226 struct drm_file *file_priv); 1226 struct drm_file *file_priv);
1227 1227
1228 /* Context IOCTL support (drm_context.h) */
1229extern int drm_resctx(struct drm_device *dev, void *data,
1230 struct drm_file *file_priv);
1231extern int drm_addctx(struct drm_device *dev, void *data,
1232 struct drm_file *file_priv);
1233extern int drm_getctx(struct drm_device *dev, void *data,
1234 struct drm_file *file_priv);
1235extern int drm_switchctx(struct drm_device *dev, void *data,
1236 struct drm_file *file_priv);
1237extern int drm_newctx(struct drm_device *dev, void *data,
1238 struct drm_file *file_priv);
1239extern int drm_rmctx(struct drm_device *dev, void *data,
1240 struct drm_file *file_priv);
1241
1242extern int drm_ctxbitmap_init(struct drm_device *dev);
1243extern void drm_ctxbitmap_cleanup(struct drm_device *dev);
1244extern void drm_ctxbitmap_free(struct drm_device *dev, int ctx_handle);
1245
1246extern int drm_setsareactx(struct drm_device *dev, void *data,
1247 struct drm_file *file_priv);
1248extern int drm_getsareactx(struct drm_device *dev, void *data,
1249 struct drm_file *file_priv);
1250
1251 /* Authentication IOCTL support (drm_auth.h) */ 1228 /* Authentication IOCTL support (drm_auth.h) */
1252extern int drm_getmagic(struct drm_device *dev, void *data, 1229extern int drm_getmagic(struct drm_device *dev, void *data,
1253 struct drm_file *file_priv); 1230 struct drm_file *file_priv);
@@ -1373,9 +1350,6 @@ extern unsigned int drm_timestamp_precision;
1373extern unsigned int drm_timestamp_monotonic; 1350extern unsigned int drm_timestamp_monotonic;
1374 1351
1375extern struct class *drm_class; 1352extern struct class *drm_class;
1376extern struct dentry *drm_debugfs_root;
1377
1378extern struct idr drm_minors_idr;
1379 1353
1380extern struct drm_local_map *drm_getsarea(struct drm_device *dev); 1354extern struct drm_local_map *drm_getsarea(struct drm_device *dev);
1381 1355
@@ -1493,9 +1467,8 @@ extern int drm_pci_set_unique(struct drm_device *dev,
1493struct drm_sysfs_class; 1467struct drm_sysfs_class;
1494extern struct class *drm_sysfs_create(struct module *owner, char *name); 1468extern struct class *drm_sysfs_create(struct module *owner, char *name);
1495extern void drm_sysfs_destroy(void); 1469extern void drm_sysfs_destroy(void);
1496extern int drm_sysfs_device_add(struct drm_minor *minor); 1470extern struct device *drm_sysfs_minor_alloc(struct drm_minor *minor);
1497extern void drm_sysfs_hotplug_event(struct drm_device *dev); 1471extern void drm_sysfs_hotplug_event(struct drm_device *dev);
1498extern void drm_sysfs_device_remove(struct drm_minor *minor);
1499extern int drm_sysfs_connector_add(struct drm_connector *connector); 1472extern int drm_sysfs_connector_add(struct drm_connector *connector);
1500extern void drm_sysfs_connector_remove(struct drm_connector *connector); 1473extern void drm_sysfs_connector_remove(struct drm_connector *connector);
1501 1474