aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/drm_auth.c
diff options
context:
space:
mode:
authorKeith Packard <keithp@keithp.com>2017-03-15 01:26:41 -0400
committerDave Airlie <airlied@redhat.com>2017-10-25 02:31:29 -0400
commit2ed077e467eedb033032bc4b6e349365517662d6 (patch)
tree57ca45b9dd2cd3c014ca70a247931341deeaf7cd /drivers/gpu/drm/drm_auth.c
parente7646f84ad4f654e1ee503b03a12e520d947884f (diff)
drm: Add drm_object lease infrastructure [v5]
This provides new data structures to hold "lease" information about drm mode setting objects, and provides for creating new drm_masters which have access to a subset of the available drm resources. An 'owner' is a drm_master which is not leasing the objects from another drm_master, and hence 'owns' them. A 'lessee' is a drm_master which is leasing objects from some other drm_master. Each lessee holds the set of objects which it is leasing from the lessor. A 'lessor' is a drm_master which is leasing objects to another drm_master. This is the same as the owner in the current code. The set of objects any drm_master 'controls' is limited to the set of objects it leases (for lessees) or all objects (for owners). Objects not controlled by a drm_master cannot be modified through the various state manipulating ioctls, and any state reported back to user space will be edited to make them appear idle and/or unusable. For instance, connectors always report 'disconnected', while encoders report no possible crtcs or clones. The full list of lessees leasing objects from an owner (either directly, or indirectly through another lessee), can be searched from an idr in the drm_master of the owner. Changes for v2 as suggested by Daniel Vetter <daniel.vetter@ffwll.ch>: * Sub-leasing has been disabled. * BUG_ON for lock checking replaced with lockdep_assert_held * 'change' ioctl has been removed. * Leased objects can always be controlled by the lessor; the 'mask_lease' flag has been removed * Checking for leased status has been simplified, replacing the drm_lease_check function with drm_lease_held. Changes in v3, some suggested by Dave Airlie <airlied@gmail.com> * Add revocation. This allows leases to be effectively revoked by removing all of the objects they have access to. The lease itself hangs around as it's hanging off a file. * Free the leases IDR when the master is destroyed * _drm_lease_held should look at lessees, not lessor * Allow non-master files to check for lease status Changes in v4, suggested by Dave Airlie <airlied@gmail.com> * Formatting and whitespace changes Changes in v5 (airlied) * check DRIVER_MODESET before lease destroy call * check DRIVER_MODESET for lease revoke (Chris) * Use idr_mutex uniformly for all lease elements of struct drm_master. (Keith) Signed-off-by: Keith Packard <keithp@keithp.com>
Diffstat (limited to 'drivers/gpu/drm/drm_auth.c')
-rw-r--r--drivers/gpu/drm/drm_auth.c30
1 files changed, 29 insertions, 1 deletions
diff --git a/drivers/gpu/drm/drm_auth.c b/drivers/gpu/drm/drm_auth.c
index 7ff697389d74..4f0e274f4111 100644
--- a/drivers/gpu/drm/drm_auth.c
+++ b/drivers/gpu/drm/drm_auth.c
@@ -31,6 +31,7 @@
31#include <drm/drmP.h> 31#include <drm/drmP.h>
32#include "drm_internal.h" 32#include "drm_internal.h"
33#include "drm_legacy.h" 33#include "drm_legacy.h"
34#include <drm/drm_lease.h>
34 35
35/** 36/**
36 * DOC: master and authentication 37 * DOC: master and authentication
@@ -93,7 +94,7 @@ int drm_authmagic(struct drm_device *dev, void *data,
93 return file ? 0 : -EINVAL; 94 return file ? 0 : -EINVAL;
94} 95}
95 96
96static struct drm_master *drm_master_create(struct drm_device *dev) 97struct drm_master *drm_master_create(struct drm_device *dev)
97{ 98{
98 struct drm_master *master; 99 struct drm_master *master;
99 100
@@ -107,6 +108,14 @@ static struct drm_master *drm_master_create(struct drm_device *dev)
107 idr_init(&master->magic_map); 108 idr_init(&master->magic_map);
108 master->dev = dev; 109 master->dev = dev;
109 110
111 /* initialize the tree of output resource lessees */
112 master->lessor = NULL;
113 master->lessee_id = 0;
114 INIT_LIST_HEAD(&master->lessees);
115 INIT_LIST_HEAD(&master->lessee_list);
116 idr_init(&master->leases);
117 idr_init(&master->lessee_idr);
118
110 return master; 119 return master;
111} 120}
112 121
@@ -189,6 +198,12 @@ int drm_setmaster_ioctl(struct drm_device *dev, void *data,
189 goto out_unlock; 198 goto out_unlock;
190 } 199 }
191 200
201 if (file_priv->master->lessor != NULL) {
202 DRM_DEBUG_LEASE("Attempt to set lessee %d as master\n", file_priv->master->lessee_id);
203 ret = -EINVAL;
204 goto out_unlock;
205 }
206
192 ret = drm_set_master(dev, file_priv, false); 207 ret = drm_set_master(dev, file_priv, false);
193out_unlock: 208out_unlock:
194 mutex_unlock(&dev->master_mutex); 209 mutex_unlock(&dev->master_mutex);
@@ -270,6 +285,13 @@ void drm_master_release(struct drm_file *file_priv)
270 if (dev->master == file_priv->master) 285 if (dev->master == file_priv->master)
271 drm_drop_master(dev, file_priv); 286 drm_drop_master(dev, file_priv);
272out: 287out:
288 if (drm_core_check_feature(dev, DRIVER_MODESET) && file_priv->is_master) {
289 /* Revoke any leases held by this or lessees, but only if
290 * this is the "real" master
291 */
292 drm_lease_revoke(master);
293 }
294
273 /* drop the master reference held by the file priv */ 295 /* drop the master reference held by the file priv */
274 if (file_priv->master) 296 if (file_priv->master)
275 drm_master_put(&file_priv->master); 297 drm_master_put(&file_priv->master);
@@ -310,12 +332,18 @@ static void drm_master_destroy(struct kref *kref)
310 struct drm_master *master = container_of(kref, struct drm_master, refcount); 332 struct drm_master *master = container_of(kref, struct drm_master, refcount);
311 struct drm_device *dev = master->dev; 333 struct drm_device *dev = master->dev;
312 334
335 if (drm_core_check_feature(dev, DRIVER_MODESET))
336 drm_lease_destroy(master);
337
313 if (dev->driver->master_destroy) 338 if (dev->driver->master_destroy)
314 dev->driver->master_destroy(dev, master); 339 dev->driver->master_destroy(dev, master);
315 340
316 drm_legacy_master_rmmaps(dev, master); 341 drm_legacy_master_rmmaps(dev, master);
317 342
318 idr_destroy(&master->magic_map); 343 idr_destroy(&master->magic_map);
344 idr_destroy(&master->leases);
345 idr_destroy(&master->lessee_idr);
346
319 kfree(master->unique); 347 kfree(master->unique);
320 kfree(master); 348 kfree(master);
321} 349}