Home | History | Annotate | Line # | Download | only in drm
drm_auth.c revision 1.1.1.3
      1  1.1.1.2  riastrad /*	$NetBSD: drm_auth.c,v 1.1.1.3 2021/12/18 20:10:59 riastradh Exp $	*/
      2      1.1  riastrad 
      3      1.1  riastrad /*
      4      1.1  riastrad  * Created: Tue Feb  2 08:37:54 1999 by faith (at) valinux.com
      5      1.1  riastrad  *
      6      1.1  riastrad  * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
      7      1.1  riastrad  * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
      8      1.1  riastrad  * All Rights Reserved.
      9      1.1  riastrad  *
     10  1.1.1.2  riastrad  * Author Rickard E. (Rik) Faith <faith (at) valinux.com>
     11  1.1.1.2  riastrad  * Author Gareth Hughes <gareth (at) valinux.com>
     12  1.1.1.2  riastrad  *
     13      1.1  riastrad  * Permission is hereby granted, free of charge, to any person obtaining a
     14      1.1  riastrad  * copy of this software and associated documentation files (the "Software"),
     15      1.1  riastrad  * to deal in the Software without restriction, including without limitation
     16      1.1  riastrad  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
     17      1.1  riastrad  * and/or sell copies of the Software, and to permit persons to whom the
     18      1.1  riastrad  * Software is furnished to do so, subject to the following conditions:
     19      1.1  riastrad  *
     20      1.1  riastrad  * The above copyright notice and this permission notice (including the next
     21      1.1  riastrad  * paragraph) shall be included in all copies or substantial portions of the
     22      1.1  riastrad  * Software.
     23      1.1  riastrad  *
     24      1.1  riastrad  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     25      1.1  riastrad  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     26      1.1  riastrad  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     27      1.1  riastrad  * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
     28      1.1  riastrad  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
     29      1.1  riastrad  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
     30      1.1  riastrad  * OTHER DEALINGS IN THE SOFTWARE.
     31      1.1  riastrad  */
     32      1.1  riastrad 
     33  1.1.1.2  riastrad #include <sys/cdefs.h>
     34  1.1.1.2  riastrad __KERNEL_RCSID(0, "$NetBSD: drm_auth.c,v 1.1.1.3 2021/12/18 20:10:59 riastradh Exp $");
     35      1.1  riastrad 
     36  1.1.1.3  riastrad #include <linux/slab.h>
     37  1.1.1.3  riastrad 
     38  1.1.1.3  riastrad #include <drm/drm_auth.h>
     39  1.1.1.3  riastrad #include <drm/drm_drv.h>
     40  1.1.1.3  riastrad #include <drm/drm_file.h>
     41  1.1.1.3  riastrad #include <drm/drm_lease.h>
     42  1.1.1.3  riastrad #include <drm/drm_print.h>
     43  1.1.1.3  riastrad 
     44  1.1.1.2  riastrad #include "drm_internal.h"
     45  1.1.1.3  riastrad #include "drm_legacy.h"
     46      1.1  riastrad 
     47      1.1  riastrad /**
     48  1.1.1.3  riastrad  * DOC: master and authentication
     49  1.1.1.3  riastrad  *
     50  1.1.1.3  riastrad  * &struct drm_master is used to track groups of clients with open
     51  1.1.1.3  riastrad  * primary/legacy device nodes. For every &struct drm_file which has had at
     52  1.1.1.3  riastrad  * least once successfully became the device master (either through the
     53  1.1.1.3  riastrad  * SET_MASTER IOCTL, or implicitly through opening the primary device node when
     54  1.1.1.3  riastrad  * no one else is the current master that time) there exists one &drm_master.
     55  1.1.1.3  riastrad  * This is noted in &drm_file.is_master. All other clients have just a pointer
     56  1.1.1.3  riastrad  * to the &drm_master they are associated with.
     57  1.1.1.3  riastrad  *
     58  1.1.1.3  riastrad  * In addition only one &drm_master can be the current master for a &drm_device.
     59  1.1.1.3  riastrad  * It can be switched through the DROP_MASTER and SET_MASTER IOCTL, or
     60  1.1.1.3  riastrad  * implicitly through closing/openeing the primary device node. See also
     61  1.1.1.3  riastrad  * drm_is_current_master().
     62      1.1  riastrad  *
     63  1.1.1.3  riastrad  * Clients can authenticate against the current master (if it matches their own)
     64  1.1.1.3  riastrad  * using the GETMAGIC and AUTHMAGIC IOCTLs. Together with exchanging masters,
     65  1.1.1.3  riastrad  * this allows controlled access to the device for an entire group of mutually
     66  1.1.1.3  riastrad  * trusted clients.
     67      1.1  riastrad  */
     68  1.1.1.3  riastrad 
     69      1.1  riastrad int drm_getmagic(struct drm_device *dev, void *data, struct drm_file *file_priv)
     70      1.1  riastrad {
     71      1.1  riastrad 	struct drm_auth *auth = data;
     72  1.1.1.2  riastrad 	int ret = 0;
     73      1.1  riastrad 
     74  1.1.1.3  riastrad 	mutex_lock(&dev->master_mutex);
     75  1.1.1.2  riastrad 	if (!file_priv->magic) {
     76  1.1.1.2  riastrad 		ret = idr_alloc(&file_priv->master->magic_map, file_priv,
     77  1.1.1.2  riastrad 				1, 0, GFP_KERNEL);
     78  1.1.1.2  riastrad 		if (ret >= 0)
     79  1.1.1.2  riastrad 			file_priv->magic = ret;
     80      1.1  riastrad 	}
     81  1.1.1.2  riastrad 	auth->magic = file_priv->magic;
     82  1.1.1.3  riastrad 	mutex_unlock(&dev->master_mutex);
     83      1.1  riastrad 
     84      1.1  riastrad 	DRM_DEBUG("%u\n", auth->magic);
     85      1.1  riastrad 
     86  1.1.1.2  riastrad 	return ret < 0 ? ret : 0;
     87      1.1  riastrad }
     88      1.1  riastrad 
     89      1.1  riastrad int drm_authmagic(struct drm_device *dev, void *data,
     90      1.1  riastrad 		  struct drm_file *file_priv)
     91      1.1  riastrad {
     92      1.1  riastrad 	struct drm_auth *auth = data;
     93      1.1  riastrad 	struct drm_file *file;
     94      1.1  riastrad 
     95      1.1  riastrad 	DRM_DEBUG("%u\n", auth->magic);
     96  1.1.1.2  riastrad 
     97  1.1.1.3  riastrad 	mutex_lock(&dev->master_mutex);
     98  1.1.1.2  riastrad 	file = idr_find(&file_priv->master->magic_map, auth->magic);
     99  1.1.1.2  riastrad 	if (file) {
    100      1.1  riastrad 		file->authenticated = 1;
    101  1.1.1.2  riastrad 		idr_replace(&file_priv->master->magic_map, NULL, auth->magic);
    102      1.1  riastrad 	}
    103  1.1.1.3  riastrad 	mutex_unlock(&dev->master_mutex);
    104  1.1.1.2  riastrad 
    105  1.1.1.2  riastrad 	return file ? 0 : -EINVAL;
    106      1.1  riastrad }
    107  1.1.1.3  riastrad 
    108  1.1.1.3  riastrad struct drm_master *drm_master_create(struct drm_device *dev)
    109  1.1.1.3  riastrad {
    110  1.1.1.3  riastrad 	struct drm_master *master;
    111  1.1.1.3  riastrad 
    112  1.1.1.3  riastrad 	master = kzalloc(sizeof(*master), GFP_KERNEL);
    113  1.1.1.3  riastrad 	if (!master)
    114  1.1.1.3  riastrad 		return NULL;
    115  1.1.1.3  riastrad 
    116  1.1.1.3  riastrad 	kref_init(&master->refcount);
    117  1.1.1.3  riastrad 	drm_master_legacy_init(master);
    118  1.1.1.3  riastrad 	idr_init(&master->magic_map);
    119  1.1.1.3  riastrad 	master->dev = dev;
    120  1.1.1.3  riastrad 
    121  1.1.1.3  riastrad 	/* initialize the tree of output resource lessees */
    122  1.1.1.3  riastrad 	INIT_LIST_HEAD(&master->lessees);
    123  1.1.1.3  riastrad 	INIT_LIST_HEAD(&master->lessee_list);
    124  1.1.1.3  riastrad 	idr_init(&master->leases);
    125  1.1.1.3  riastrad 	idr_init(&master->lessee_idr);
    126  1.1.1.3  riastrad 
    127  1.1.1.3  riastrad 	return master;
    128  1.1.1.3  riastrad }
    129  1.1.1.3  riastrad 
    130  1.1.1.3  riastrad static int drm_set_master(struct drm_device *dev, struct drm_file *fpriv,
    131  1.1.1.3  riastrad 			  bool new_master)
    132  1.1.1.3  riastrad {
    133  1.1.1.3  riastrad 	int ret = 0;
    134  1.1.1.3  riastrad 
    135  1.1.1.3  riastrad 	dev->master = drm_master_get(fpriv->master);
    136  1.1.1.3  riastrad 	if (dev->driver->master_set) {
    137  1.1.1.3  riastrad 		ret = dev->driver->master_set(dev, fpriv, new_master);
    138  1.1.1.3  riastrad 		if (unlikely(ret != 0)) {
    139  1.1.1.3  riastrad 			drm_master_put(&dev->master);
    140  1.1.1.3  riastrad 		}
    141  1.1.1.3  riastrad 	}
    142  1.1.1.3  riastrad 
    143  1.1.1.3  riastrad 	return ret;
    144  1.1.1.3  riastrad }
    145  1.1.1.3  riastrad 
    146  1.1.1.3  riastrad static int drm_new_set_master(struct drm_device *dev, struct drm_file *fpriv)
    147  1.1.1.3  riastrad {
    148  1.1.1.3  riastrad 	struct drm_master *old_master;
    149  1.1.1.3  riastrad 	int ret;
    150  1.1.1.3  riastrad 
    151  1.1.1.3  riastrad 	lockdep_assert_held_once(&dev->master_mutex);
    152  1.1.1.3  riastrad 
    153  1.1.1.3  riastrad 	WARN_ON(fpriv->is_master);
    154  1.1.1.3  riastrad 	old_master = fpriv->master;
    155  1.1.1.3  riastrad 	fpriv->master = drm_master_create(dev);
    156  1.1.1.3  riastrad 	if (!fpriv->master) {
    157  1.1.1.3  riastrad 		fpriv->master = old_master;
    158  1.1.1.3  riastrad 		return -ENOMEM;
    159  1.1.1.3  riastrad 	}
    160  1.1.1.3  riastrad 
    161  1.1.1.3  riastrad 	if (dev->driver->master_create) {
    162  1.1.1.3  riastrad 		ret = dev->driver->master_create(dev, fpriv->master);
    163  1.1.1.3  riastrad 		if (ret)
    164  1.1.1.3  riastrad 			goto out_err;
    165  1.1.1.3  riastrad 	}
    166  1.1.1.3  riastrad 	fpriv->is_master = 1;
    167  1.1.1.3  riastrad 	fpriv->authenticated = 1;
    168  1.1.1.3  riastrad 
    169  1.1.1.3  riastrad 	ret = drm_set_master(dev, fpriv, true);
    170  1.1.1.3  riastrad 	if (ret)
    171  1.1.1.3  riastrad 		goto out_err;
    172  1.1.1.3  riastrad 
    173  1.1.1.3  riastrad 	if (old_master)
    174  1.1.1.3  riastrad 		drm_master_put(&old_master);
    175  1.1.1.3  riastrad 
    176  1.1.1.3  riastrad 	return 0;
    177  1.1.1.3  riastrad 
    178  1.1.1.3  riastrad out_err:
    179  1.1.1.3  riastrad 	/* drop references and restore old master on failure */
    180  1.1.1.3  riastrad 	drm_master_put(&fpriv->master);
    181  1.1.1.3  riastrad 	fpriv->master = old_master;
    182  1.1.1.3  riastrad 	fpriv->is_master = 0;
    183  1.1.1.3  riastrad 
    184  1.1.1.3  riastrad 	return ret;
    185  1.1.1.3  riastrad }
    186  1.1.1.3  riastrad 
    187  1.1.1.3  riastrad int drm_setmaster_ioctl(struct drm_device *dev, void *data,
    188  1.1.1.3  riastrad 			struct drm_file *file_priv)
    189  1.1.1.3  riastrad {
    190  1.1.1.3  riastrad 	int ret = 0;
    191  1.1.1.3  riastrad 
    192  1.1.1.3  riastrad 	mutex_lock(&dev->master_mutex);
    193  1.1.1.3  riastrad 	if (drm_is_current_master(file_priv))
    194  1.1.1.3  riastrad 		goto out_unlock;
    195  1.1.1.3  riastrad 
    196  1.1.1.3  riastrad 	if (dev->master) {
    197  1.1.1.3  riastrad 		ret = -EINVAL;
    198  1.1.1.3  riastrad 		goto out_unlock;
    199  1.1.1.3  riastrad 	}
    200  1.1.1.3  riastrad 
    201  1.1.1.3  riastrad 	if (!file_priv->master) {
    202  1.1.1.3  riastrad 		ret = -EINVAL;
    203  1.1.1.3  riastrad 		goto out_unlock;
    204  1.1.1.3  riastrad 	}
    205  1.1.1.3  riastrad 
    206  1.1.1.3  riastrad 	if (!file_priv->is_master) {
    207  1.1.1.3  riastrad 		ret = drm_new_set_master(dev, file_priv);
    208  1.1.1.3  riastrad 		goto out_unlock;
    209  1.1.1.3  riastrad 	}
    210  1.1.1.3  riastrad 
    211  1.1.1.3  riastrad 	if (file_priv->master->lessor != NULL) {
    212  1.1.1.3  riastrad 		DRM_DEBUG_LEASE("Attempt to set lessee %d as master\n", file_priv->master->lessee_id);
    213  1.1.1.3  riastrad 		ret = -EINVAL;
    214  1.1.1.3  riastrad 		goto out_unlock;
    215  1.1.1.3  riastrad 	}
    216  1.1.1.3  riastrad 
    217  1.1.1.3  riastrad 	ret = drm_set_master(dev, file_priv, false);
    218  1.1.1.3  riastrad out_unlock:
    219  1.1.1.3  riastrad 	mutex_unlock(&dev->master_mutex);
    220  1.1.1.3  riastrad 	return ret;
    221  1.1.1.3  riastrad }
    222  1.1.1.3  riastrad 
    223  1.1.1.3  riastrad static void drm_drop_master(struct drm_device *dev,
    224  1.1.1.3  riastrad 			    struct drm_file *fpriv)
    225  1.1.1.3  riastrad {
    226  1.1.1.3  riastrad 	if (dev->driver->master_drop)
    227  1.1.1.3  riastrad 		dev->driver->master_drop(dev, fpriv);
    228  1.1.1.3  riastrad 	drm_master_put(&dev->master);
    229  1.1.1.3  riastrad }
    230  1.1.1.3  riastrad 
    231  1.1.1.3  riastrad int drm_dropmaster_ioctl(struct drm_device *dev, void *data,
    232  1.1.1.3  riastrad 			 struct drm_file *file_priv)
    233  1.1.1.3  riastrad {
    234  1.1.1.3  riastrad 	int ret = -EINVAL;
    235  1.1.1.3  riastrad 
    236  1.1.1.3  riastrad 	mutex_lock(&dev->master_mutex);
    237  1.1.1.3  riastrad 	if (!drm_is_current_master(file_priv))
    238  1.1.1.3  riastrad 		goto out_unlock;
    239  1.1.1.3  riastrad 
    240  1.1.1.3  riastrad 	if (!dev->master)
    241  1.1.1.3  riastrad 		goto out_unlock;
    242  1.1.1.3  riastrad 
    243  1.1.1.3  riastrad 	if (file_priv->master->lessor != NULL) {
    244  1.1.1.3  riastrad 		DRM_DEBUG_LEASE("Attempt to drop lessee %d as master\n", file_priv->master->lessee_id);
    245  1.1.1.3  riastrad 		ret = -EINVAL;
    246  1.1.1.3  riastrad 		goto out_unlock;
    247  1.1.1.3  riastrad 	}
    248  1.1.1.3  riastrad 
    249  1.1.1.3  riastrad 	ret = 0;
    250  1.1.1.3  riastrad 	drm_drop_master(dev, file_priv);
    251  1.1.1.3  riastrad out_unlock:
    252  1.1.1.3  riastrad 	mutex_unlock(&dev->master_mutex);
    253  1.1.1.3  riastrad 	return ret;
    254  1.1.1.3  riastrad }
    255  1.1.1.3  riastrad 
    256  1.1.1.3  riastrad int drm_master_open(struct drm_file *file_priv)
    257  1.1.1.3  riastrad {
    258  1.1.1.3  riastrad 	struct drm_device *dev = file_priv->minor->dev;
    259  1.1.1.3  riastrad 	int ret = 0;
    260  1.1.1.3  riastrad 
    261  1.1.1.3  riastrad 	/* if there is no current master make this fd it, but do not create
    262  1.1.1.3  riastrad 	 * any master object for render clients */
    263  1.1.1.3  riastrad 	mutex_lock(&dev->master_mutex);
    264  1.1.1.3  riastrad 	if (!dev->master)
    265  1.1.1.3  riastrad 		ret = drm_new_set_master(dev, file_priv);
    266  1.1.1.3  riastrad 	else
    267  1.1.1.3  riastrad 		file_priv->master = drm_master_get(dev->master);
    268  1.1.1.3  riastrad 	mutex_unlock(&dev->master_mutex);
    269  1.1.1.3  riastrad 
    270  1.1.1.3  riastrad 	return ret;
    271  1.1.1.3  riastrad }
    272  1.1.1.3  riastrad 
    273  1.1.1.3  riastrad void drm_master_release(struct drm_file *file_priv)
    274  1.1.1.3  riastrad {
    275  1.1.1.3  riastrad 	struct drm_device *dev = file_priv->minor->dev;
    276  1.1.1.3  riastrad 	struct drm_master *master = file_priv->master;
    277  1.1.1.3  riastrad 
    278  1.1.1.3  riastrad 	mutex_lock(&dev->master_mutex);
    279  1.1.1.3  riastrad 	if (file_priv->magic)
    280  1.1.1.3  riastrad 		idr_remove(&file_priv->master->magic_map, file_priv->magic);
    281  1.1.1.3  riastrad 
    282  1.1.1.3  riastrad 	if (!drm_is_current_master(file_priv))
    283  1.1.1.3  riastrad 		goto out;
    284  1.1.1.3  riastrad 
    285  1.1.1.3  riastrad 	drm_legacy_lock_master_cleanup(dev, master);
    286  1.1.1.3  riastrad 
    287  1.1.1.3  riastrad 	if (dev->master == file_priv->master)
    288  1.1.1.3  riastrad 		drm_drop_master(dev, file_priv);
    289  1.1.1.3  riastrad out:
    290  1.1.1.3  riastrad 	if (drm_core_check_feature(dev, DRIVER_MODESET) && file_priv->is_master) {
    291  1.1.1.3  riastrad 		/* Revoke any leases held by this or lessees, but only if
    292  1.1.1.3  riastrad 		 * this is the "real" master
    293  1.1.1.3  riastrad 		 */
    294  1.1.1.3  riastrad 		drm_lease_revoke(master);
    295  1.1.1.3  riastrad 	}
    296  1.1.1.3  riastrad 
    297  1.1.1.3  riastrad 	/* drop the master reference held by the file priv */
    298  1.1.1.3  riastrad 	if (file_priv->master)
    299  1.1.1.3  riastrad 		drm_master_put(&file_priv->master);
    300  1.1.1.3  riastrad 	mutex_unlock(&dev->master_mutex);
    301  1.1.1.3  riastrad }
    302  1.1.1.3  riastrad 
    303  1.1.1.3  riastrad /**
    304  1.1.1.3  riastrad  * drm_is_current_master - checks whether @priv is the current master
    305  1.1.1.3  riastrad  * @fpriv: DRM file private
    306  1.1.1.3  riastrad  *
    307  1.1.1.3  riastrad  * Checks whether @fpriv is current master on its device. This decides whether a
    308  1.1.1.3  riastrad  * client is allowed to run DRM_MASTER IOCTLs.
    309  1.1.1.3  riastrad  *
    310  1.1.1.3  riastrad  * Most of the modern IOCTL which require DRM_MASTER are for kernel modesetting
    311  1.1.1.3  riastrad  * - the current master is assumed to own the non-shareable display hardware.
    312  1.1.1.3  riastrad  */
    313  1.1.1.3  riastrad bool drm_is_current_master(struct drm_file *fpriv)
    314  1.1.1.3  riastrad {
    315  1.1.1.3  riastrad 	return fpriv->is_master && drm_lease_owner(fpriv->master) == fpriv->minor->dev->master;
    316  1.1.1.3  riastrad }
    317  1.1.1.3  riastrad EXPORT_SYMBOL(drm_is_current_master);
    318  1.1.1.3  riastrad 
    319  1.1.1.3  riastrad /**
    320  1.1.1.3  riastrad  * drm_master_get - reference a master pointer
    321  1.1.1.3  riastrad  * @master: &struct drm_master
    322  1.1.1.3  riastrad  *
    323  1.1.1.3  riastrad  * Increments the reference count of @master and returns a pointer to @master.
    324  1.1.1.3  riastrad  */
    325  1.1.1.3  riastrad struct drm_master *drm_master_get(struct drm_master *master)
    326  1.1.1.3  riastrad {
    327  1.1.1.3  riastrad 	kref_get(&master->refcount);
    328  1.1.1.3  riastrad 	return master;
    329  1.1.1.3  riastrad }
    330  1.1.1.3  riastrad EXPORT_SYMBOL(drm_master_get);
    331  1.1.1.3  riastrad 
    332  1.1.1.3  riastrad static void drm_master_destroy(struct kref *kref)
    333  1.1.1.3  riastrad {
    334  1.1.1.3  riastrad 	struct drm_master *master = container_of(kref, struct drm_master, refcount);
    335  1.1.1.3  riastrad 	struct drm_device *dev = master->dev;
    336  1.1.1.3  riastrad 
    337  1.1.1.3  riastrad 	if (drm_core_check_feature(dev, DRIVER_MODESET))
    338  1.1.1.3  riastrad 		drm_lease_destroy(master);
    339  1.1.1.3  riastrad 
    340  1.1.1.3  riastrad 	if (dev->driver->master_destroy)
    341  1.1.1.3  riastrad 		dev->driver->master_destroy(dev, master);
    342  1.1.1.3  riastrad 
    343  1.1.1.3  riastrad 	drm_legacy_master_rmmaps(dev, master);
    344  1.1.1.3  riastrad 
    345  1.1.1.3  riastrad 	idr_destroy(&master->magic_map);
    346  1.1.1.3  riastrad 	idr_destroy(&master->leases);
    347  1.1.1.3  riastrad 	idr_destroy(&master->lessee_idr);
    348  1.1.1.3  riastrad 
    349  1.1.1.3  riastrad 	kfree(master->unique);
    350  1.1.1.3  riastrad 	kfree(master);
    351  1.1.1.3  riastrad }
    352  1.1.1.3  riastrad 
    353  1.1.1.3  riastrad /**
    354  1.1.1.3  riastrad  * drm_master_put - unreference and clear a master pointer
    355  1.1.1.3  riastrad  * @master: pointer to a pointer of &struct drm_master
    356  1.1.1.3  riastrad  *
    357  1.1.1.3  riastrad  * This decrements the &drm_master behind @master and sets it to NULL.
    358  1.1.1.3  riastrad  */
    359  1.1.1.3  riastrad void drm_master_put(struct drm_master **master)
    360  1.1.1.3  riastrad {
    361  1.1.1.3  riastrad 	kref_put(&(*master)->refcount, drm_master_destroy);
    362  1.1.1.3  riastrad 	*master = NULL;
    363  1.1.1.3  riastrad }
    364  1.1.1.3  riastrad EXPORT_SYMBOL(drm_master_put);
    365  1.1.1.3  riastrad 
    366  1.1.1.3  riastrad /* Used by drm_client and drm_fb_helper */
    367  1.1.1.3  riastrad bool drm_master_internal_acquire(struct drm_device *dev)
    368  1.1.1.3  riastrad {
    369  1.1.1.3  riastrad 	mutex_lock(&dev->master_mutex);
    370  1.1.1.3  riastrad 	if (dev->master) {
    371  1.1.1.3  riastrad 		mutex_unlock(&dev->master_mutex);
    372  1.1.1.3  riastrad 		return false;
    373  1.1.1.3  riastrad 	}
    374  1.1.1.3  riastrad 
    375  1.1.1.3  riastrad 	return true;
    376  1.1.1.3  riastrad }
    377  1.1.1.3  riastrad EXPORT_SYMBOL(drm_master_internal_acquire);
    378  1.1.1.3  riastrad 
    379  1.1.1.3  riastrad /* Used by drm_client and drm_fb_helper */
    380  1.1.1.3  riastrad void drm_master_internal_release(struct drm_device *dev)
    381  1.1.1.3  riastrad {
    382  1.1.1.3  riastrad 	mutex_unlock(&dev->master_mutex);
    383  1.1.1.3  riastrad }
    384  1.1.1.3  riastrad EXPORT_SYMBOL(drm_master_internal_release);
    385