]>
git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blob - drivers/gpu/drm/drm_auth.c
2 * Created: Tue Feb 2 08:37:54 1999 by faith@valinux.com
4 * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
5 * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
8 * Author Rickard E. (Rik) Faith <faith@valinux.com>
9 * Author Gareth Hughes <gareth@valinux.com>
11 * Permission is hereby granted, free of charge, to any person obtaining a
12 * copy of this software and associated documentation files (the "Software"),
13 * to deal in the Software without restriction, including without limitation
14 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
15 * and/or sell copies of the Software, and to permit persons to whom the
16 * Software is furnished to do so, subject to the following conditions:
18 * The above copyright notice and this permission notice (including the next
19 * paragraph) shall be included in all copies or substantial portions of the
22 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
25 * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
26 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
27 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
28 * OTHER DEALINGS IN THE SOFTWARE.
32 #include "drm_internal.h"
33 #include "drm_legacy.h"
36 * drm_getmagic - Get unique magic of a client
37 * @dev: DRM device to operate on
38 * @data: ioctl data containing the drm_auth object
39 * @file_priv: DRM file that performs the operation
41 * This looks up the unique magic of the passed client and returns it. If the
42 * client did not have a magic assigned, yet, a new one is registered. The magic
43 * is stored in the passed drm_auth object.
45 * Returns: 0 on success, negative error code on failure.
47 int drm_getmagic(struct drm_device
*dev
, void *data
, struct drm_file
*file_priv
)
49 struct drm_auth
*auth
= data
;
52 mutex_lock(&dev
->master_mutex
);
53 if (!file_priv
->magic
) {
54 ret
= idr_alloc(&file_priv
->master
->magic_map
, file_priv
,
57 file_priv
->magic
= ret
;
59 auth
->magic
= file_priv
->magic
;
60 mutex_unlock(&dev
->master_mutex
);
62 DRM_DEBUG("%u\n", auth
->magic
);
64 return ret
< 0 ? ret
: 0;
68 * drm_authmagic - Authenticate client with a magic
69 * @dev: DRM device to operate on
70 * @data: ioctl data containing the drm_auth object
71 * @file_priv: DRM file that performs the operation
73 * This looks up a DRM client by the passed magic and authenticates it.
75 * Returns: 0 on success, negative error code on failure.
77 int drm_authmagic(struct drm_device
*dev
, void *data
,
78 struct drm_file
*file_priv
)
80 struct drm_auth
*auth
= data
;
81 struct drm_file
*file
;
83 DRM_DEBUG("%u\n", auth
->magic
);
85 mutex_lock(&dev
->master_mutex
);
86 file
= idr_find(&file_priv
->master
->magic_map
, auth
->magic
);
88 file
->authenticated
= 1;
89 idr_replace(&file_priv
->master
->magic_map
, NULL
, auth
->magic
);
91 mutex_unlock(&dev
->master_mutex
);
93 return file
? 0 : -EINVAL
;
96 static struct drm_master
*drm_master_create(struct drm_device
*dev
)
98 struct drm_master
*master
;
100 master
= kzalloc(sizeof(*master
), GFP_KERNEL
);
104 kref_init(&master
->refcount
);
105 spin_lock_init(&master
->lock
.spinlock
);
106 init_waitqueue_head(&master
->lock
.lock_queue
);
107 idr_init(&master
->magic_map
);
113 static int drm_set_master(struct drm_device
*dev
, struct drm_file
*fpriv
,
118 dev
->master
= drm_master_get(fpriv
->master
);
119 fpriv
->is_master
= 1;
120 if (dev
->driver
->master_set
) {
121 ret
= dev
->driver
->master_set(dev
, fpriv
, new_master
);
122 if (unlikely(ret
!= 0)) {
123 fpriv
->is_master
= 0;
124 drm_master_put(&dev
->master
);
132 * drm_new_set_master - Allocate a new master object and become master for the
133 * associated master realm.
135 * @dev: The associated device.
136 * @fpriv: File private identifying the client.
138 * This function must be called with dev::master_mutex held.
139 * Returns negative error code on failure. Zero on success.
141 static int drm_new_set_master(struct drm_device
*dev
, struct drm_file
*fpriv
)
143 struct drm_master
*old_master
;
146 lockdep_assert_held_once(&dev
->master_mutex
);
148 old_master
= fpriv
->master
;
149 fpriv
->master
= drm_master_create(dev
);
150 if (!fpriv
->master
) {
151 fpriv
->master
= old_master
;
155 if (dev
->driver
->master_create
) {
156 ret
= dev
->driver
->master_create(dev
, fpriv
->master
);
160 fpriv
->allowed_master
= 1;
161 fpriv
->authenticated
= 1;
163 ret
= drm_set_master(dev
, fpriv
, true);
168 drm_master_put(&old_master
);
173 /* drop references and restore old master on failure */
174 drm_master_put(&fpriv
->master
);
175 fpriv
->master
= old_master
;
180 int drm_setmaster_ioctl(struct drm_device
*dev
, void *data
,
181 struct drm_file
*file_priv
)
185 mutex_lock(&dev
->master_mutex
);
186 if (drm_is_current_master(file_priv
))
194 if (!file_priv
->master
) {
199 if (!file_priv
->allowed_master
) {
200 ret
= drm_new_set_master(dev
, file_priv
);
204 ret
= drm_set_master(dev
, file_priv
, false);
206 mutex_unlock(&dev
->master_mutex
);
210 static void drm_drop_master(struct drm_device
*dev
,
211 struct drm_file
*fpriv
)
213 if (dev
->driver
->master_drop
)
214 dev
->driver
->master_drop(dev
, fpriv
);
215 drm_master_put(&dev
->master
);
216 fpriv
->is_master
= 0;
219 int drm_dropmaster_ioctl(struct drm_device
*dev
, void *data
,
220 struct drm_file
*file_priv
)
224 mutex_lock(&dev
->master_mutex
);
225 if (!drm_is_current_master(file_priv
))
232 drm_drop_master(dev
, file_priv
);
234 mutex_unlock(&dev
->master_mutex
);
238 int drm_master_open(struct drm_file
*file_priv
)
240 struct drm_device
*dev
= file_priv
->minor
->dev
;
243 /* if there is no current master make this fd it, but do not create
244 * any master object for render clients */
245 mutex_lock(&dev
->master_mutex
);
247 ret
= drm_new_set_master(dev
, file_priv
);
249 file_priv
->master
= drm_master_get(dev
->master
);
250 mutex_unlock(&dev
->master_mutex
);
255 void drm_master_release(struct drm_file
*file_priv
)
257 struct drm_device
*dev
= file_priv
->minor
->dev
;
258 struct drm_master
*master
= file_priv
->master
;
260 mutex_lock(&dev
->master_mutex
);
261 if (file_priv
->magic
)
262 idr_remove(&file_priv
->master
->magic_map
, file_priv
->magic
);
264 if (!drm_is_current_master(file_priv
))
267 if (!drm_core_check_feature(dev
, DRIVER_MODESET
)) {
269 * Since the master is disappearing, so is the
270 * possibility to lock.
272 mutex_lock(&dev
->struct_mutex
);
273 if (master
->lock
.hw_lock
) {
274 if (dev
->sigdata
.lock
== master
->lock
.hw_lock
)
275 dev
->sigdata
.lock
= NULL
;
276 master
->lock
.hw_lock
= NULL
;
277 master
->lock
.file_priv
= NULL
;
278 wake_up_interruptible_all(&master
->lock
.lock_queue
);
280 mutex_unlock(&dev
->struct_mutex
);
283 if (dev
->master
== file_priv
->master
)
284 drm_drop_master(dev
, file_priv
);
286 /* drop the master reference held by the file priv */
287 if (file_priv
->master
)
288 drm_master_put(&file_priv
->master
);
289 mutex_unlock(&dev
->master_mutex
);
292 bool drm_is_current_master(struct drm_file
*fpriv
)
294 return fpriv
->is_master
;
296 EXPORT_SYMBOL(drm_is_current_master
);
298 struct drm_master
*drm_master_get(struct drm_master
*master
)
300 kref_get(&master
->refcount
);
303 EXPORT_SYMBOL(drm_master_get
);
305 static void drm_master_destroy(struct kref
*kref
)
307 struct drm_master
*master
= container_of(kref
, struct drm_master
, refcount
);
308 struct drm_device
*dev
= master
->dev
;
310 if (dev
->driver
->master_destroy
)
311 dev
->driver
->master_destroy(dev
, master
);
313 drm_legacy_master_rmmaps(dev
, master
);
315 idr_destroy(&master
->magic_map
);
316 kfree(master
->unique
);
320 void drm_master_put(struct drm_master
**master
)
322 kref_put(&(*master
)->refcount
, drm_master_destroy
);
325 EXPORT_SYMBOL(drm_master_put
);