0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031 #include <linux/slab.h>
0032
0033 #include <drm/drm_auth.h>
0034 #include <drm/drm_drv.h>
0035 #include <drm/drm_file.h>
0036 #include <drm/drm_lease.h>
0037 #include <drm/drm_print.h>
0038
0039 #include "drm_internal.h"
0040 #include "drm_legacy.h"
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064 static bool drm_is_current_master_locked(struct drm_file *fpriv)
0065 {
0066 lockdep_assert_once(lockdep_is_held(&fpriv->master_lookup_lock) ||
0067 lockdep_is_held(&fpriv->minor->dev->master_mutex));
0068
0069 return fpriv->is_master && drm_lease_owner(fpriv->master) == fpriv->minor->dev->master;
0070 }
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082 bool drm_is_current_master(struct drm_file *fpriv)
0083 {
0084 bool ret;
0085
0086 spin_lock(&fpriv->master_lookup_lock);
0087 ret = drm_is_current_master_locked(fpriv);
0088 spin_unlock(&fpriv->master_lookup_lock);
0089
0090 return ret;
0091 }
0092 EXPORT_SYMBOL(drm_is_current_master);
0093
0094 int drm_getmagic(struct drm_device *dev, void *data, struct drm_file *file_priv)
0095 {
0096 struct drm_auth *auth = data;
0097 int ret = 0;
0098
0099 mutex_lock(&dev->master_mutex);
0100 if (!file_priv->magic) {
0101 ret = idr_alloc(&file_priv->master->magic_map, file_priv,
0102 1, 0, GFP_KERNEL);
0103 if (ret >= 0)
0104 file_priv->magic = ret;
0105 }
0106 auth->magic = file_priv->magic;
0107 mutex_unlock(&dev->master_mutex);
0108
0109 drm_dbg_core(dev, "%u\n", auth->magic);
0110
0111 return ret < 0 ? ret : 0;
0112 }
0113
0114 int drm_authmagic(struct drm_device *dev, void *data,
0115 struct drm_file *file_priv)
0116 {
0117 struct drm_auth *auth = data;
0118 struct drm_file *file;
0119
0120 drm_dbg_core(dev, "%u\n", auth->magic);
0121
0122 mutex_lock(&dev->master_mutex);
0123 file = idr_find(&file_priv->master->magic_map, auth->magic);
0124 if (file) {
0125 file->authenticated = 1;
0126 idr_replace(&file_priv->master->magic_map, NULL, auth->magic);
0127 }
0128 mutex_unlock(&dev->master_mutex);
0129
0130 return file ? 0 : -EINVAL;
0131 }
0132
0133 struct drm_master *drm_master_create(struct drm_device *dev)
0134 {
0135 struct drm_master *master;
0136
0137 master = kzalloc(sizeof(*master), GFP_KERNEL);
0138 if (!master)
0139 return NULL;
0140
0141 kref_init(&master->refcount);
0142 drm_master_legacy_init(master);
0143 idr_init(&master->magic_map);
0144 master->dev = dev;
0145
0146
0147 INIT_LIST_HEAD(&master->lessees);
0148 INIT_LIST_HEAD(&master->lessee_list);
0149 idr_init(&master->leases);
0150 idr_init(&master->lessee_idr);
0151
0152 return master;
0153 }
0154
0155 static void drm_set_master(struct drm_device *dev, struct drm_file *fpriv,
0156 bool new_master)
0157 {
0158 dev->master = drm_master_get(fpriv->master);
0159 if (dev->driver->master_set)
0160 dev->driver->master_set(dev, fpriv, new_master);
0161
0162 fpriv->was_master = true;
0163 }
0164
0165 static int drm_new_set_master(struct drm_device *dev, struct drm_file *fpriv)
0166 {
0167 struct drm_master *old_master;
0168 struct drm_master *new_master;
0169
0170 lockdep_assert_held_once(&dev->master_mutex);
0171
0172 WARN_ON(fpriv->is_master);
0173 old_master = fpriv->master;
0174 new_master = drm_master_create(dev);
0175 if (!new_master)
0176 return -ENOMEM;
0177 spin_lock(&fpriv->master_lookup_lock);
0178 fpriv->master = new_master;
0179 spin_unlock(&fpriv->master_lookup_lock);
0180
0181 fpriv->is_master = 1;
0182 fpriv->authenticated = 1;
0183
0184 drm_set_master(dev, fpriv, true);
0185
0186 if (old_master)
0187 drm_master_put(&old_master);
0188
0189 return 0;
0190 }
0191
0192
0193
0194
0195
0196
0197
0198
0199
0200
0201
0202
0203
0204
0205
0206
0207
0208
0209
0210
0211
0212
0213
0214
0215
0216
0217
0218
0219
0220
0221
0222
0223
0224
0225
0226
0227
0228
0229
0230
0231
0232
0233
0234
0235 static int
0236 drm_master_check_perm(struct drm_device *dev, struct drm_file *file_priv)
0237 {
0238 if (file_priv->pid == task_pid(current) && file_priv->was_master)
0239 return 0;
0240
0241 if (!capable(CAP_SYS_ADMIN))
0242 return -EACCES;
0243
0244 return 0;
0245 }
0246
0247 int drm_setmaster_ioctl(struct drm_device *dev, void *data,
0248 struct drm_file *file_priv)
0249 {
0250 int ret;
0251
0252 mutex_lock(&dev->master_mutex);
0253
0254 ret = drm_master_check_perm(dev, file_priv);
0255 if (ret)
0256 goto out_unlock;
0257
0258 if (drm_is_current_master_locked(file_priv))
0259 goto out_unlock;
0260
0261 if (dev->master) {
0262 ret = -EBUSY;
0263 goto out_unlock;
0264 }
0265
0266 if (!file_priv->master) {
0267 ret = -EINVAL;
0268 goto out_unlock;
0269 }
0270
0271 if (!file_priv->is_master) {
0272 ret = drm_new_set_master(dev, file_priv);
0273 goto out_unlock;
0274 }
0275
0276 if (file_priv->master->lessor != NULL) {
0277 drm_dbg_lease(dev,
0278 "Attempt to set lessee %d as master\n",
0279 file_priv->master->lessee_id);
0280 ret = -EINVAL;
0281 goto out_unlock;
0282 }
0283
0284 drm_set_master(dev, file_priv, false);
0285 out_unlock:
0286 mutex_unlock(&dev->master_mutex);
0287 return ret;
0288 }
0289
0290 static void drm_drop_master(struct drm_device *dev,
0291 struct drm_file *fpriv)
0292 {
0293 if (dev->driver->master_drop)
0294 dev->driver->master_drop(dev, fpriv);
0295 drm_master_put(&dev->master);
0296 }
0297
0298 int drm_dropmaster_ioctl(struct drm_device *dev, void *data,
0299 struct drm_file *file_priv)
0300 {
0301 int ret;
0302
0303 mutex_lock(&dev->master_mutex);
0304
0305 ret = drm_master_check_perm(dev, file_priv);
0306 if (ret)
0307 goto out_unlock;
0308
0309 if (!drm_is_current_master_locked(file_priv)) {
0310 ret = -EINVAL;
0311 goto out_unlock;
0312 }
0313
0314 if (!dev->master) {
0315 ret = -EINVAL;
0316 goto out_unlock;
0317 }
0318
0319 if (file_priv->master->lessor != NULL) {
0320 drm_dbg_lease(dev,
0321 "Attempt to drop lessee %d as master\n",
0322 file_priv->master->lessee_id);
0323 ret = -EINVAL;
0324 goto out_unlock;
0325 }
0326
0327 drm_drop_master(dev, file_priv);
0328 out_unlock:
0329 mutex_unlock(&dev->master_mutex);
0330 return ret;
0331 }
0332
0333 int drm_master_open(struct drm_file *file_priv)
0334 {
0335 struct drm_device *dev = file_priv->minor->dev;
0336 int ret = 0;
0337
0338
0339
0340
0341 mutex_lock(&dev->master_mutex);
0342 if (!dev->master) {
0343 ret = drm_new_set_master(dev, file_priv);
0344 } else {
0345 spin_lock(&file_priv->master_lookup_lock);
0346 file_priv->master = drm_master_get(dev->master);
0347 spin_unlock(&file_priv->master_lookup_lock);
0348 }
0349 mutex_unlock(&dev->master_mutex);
0350
0351 return ret;
0352 }
0353
0354 void drm_master_release(struct drm_file *file_priv)
0355 {
0356 struct drm_device *dev = file_priv->minor->dev;
0357 struct drm_master *master;
0358
0359 mutex_lock(&dev->master_mutex);
0360 master = file_priv->master;
0361 if (file_priv->magic)
0362 idr_remove(&file_priv->master->magic_map, file_priv->magic);
0363
0364 if (!drm_is_current_master_locked(file_priv))
0365 goto out;
0366
0367 drm_legacy_lock_master_cleanup(dev, master);
0368
0369 if (dev->master == file_priv->master)
0370 drm_drop_master(dev, file_priv);
0371 out:
0372 if (drm_core_check_feature(dev, DRIVER_MODESET) && file_priv->is_master) {
0373
0374
0375
0376 drm_lease_revoke(master);
0377 }
0378
0379
0380 if (file_priv->master)
0381 drm_master_put(&file_priv->master);
0382 mutex_unlock(&dev->master_mutex);
0383 }
0384
0385
0386
0387
0388
0389
0390
0391 struct drm_master *drm_master_get(struct drm_master *master)
0392 {
0393 kref_get(&master->refcount);
0394 return master;
0395 }
0396 EXPORT_SYMBOL(drm_master_get);
0397
0398
0399
0400
0401
0402
0403
0404
0405
0406
0407
0408 struct drm_master *drm_file_get_master(struct drm_file *file_priv)
0409 {
0410 struct drm_master *master = NULL;
0411
0412 spin_lock(&file_priv->master_lookup_lock);
0413 if (!file_priv->master)
0414 goto unlock;
0415 master = drm_master_get(file_priv->master);
0416
0417 unlock:
0418 spin_unlock(&file_priv->master_lookup_lock);
0419 return master;
0420 }
0421 EXPORT_SYMBOL(drm_file_get_master);
0422
0423 static void drm_master_destroy(struct kref *kref)
0424 {
0425 struct drm_master *master = container_of(kref, struct drm_master, refcount);
0426 struct drm_device *dev = master->dev;
0427
0428 if (drm_core_check_feature(dev, DRIVER_MODESET))
0429 drm_lease_destroy(master);
0430
0431 drm_legacy_master_rmmaps(dev, master);
0432
0433 idr_destroy(&master->magic_map);
0434 idr_destroy(&master->leases);
0435 idr_destroy(&master->lessee_idr);
0436
0437 kfree(master->unique);
0438 kfree(master);
0439 }
0440
0441
0442
0443
0444
0445
0446
0447 void drm_master_put(struct drm_master **master)
0448 {
0449 kref_put(&(*master)->refcount, drm_master_destroy);
0450 *master = NULL;
0451 }
0452 EXPORT_SYMBOL(drm_master_put);
0453
0454
0455 bool drm_master_internal_acquire(struct drm_device *dev)
0456 {
0457 mutex_lock(&dev->master_mutex);
0458 if (dev->master) {
0459 mutex_unlock(&dev->master_mutex);
0460 return false;
0461 }
0462
0463 return true;
0464 }
0465 EXPORT_SYMBOL(drm_master_internal_acquire);
0466
0467
0468 void drm_master_internal_release(struct drm_device *dev)
0469 {
0470 mutex_unlock(&dev->master_mutex);
0471 }
0472 EXPORT_SYMBOL(drm_master_internal_release);