summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/drm_fops.c
diff options
context:
space:
mode:
authorDavid Herrmann <dh.herrmann@gmail.com>2013-08-25 18:29:00 +0200
committerDave Airlie <airlied@gmail.com>2013-08-30 08:43:57 +1000
commit1793126fcebd7c18834f95d43b55e387a8803aa8 (patch)
tree4e8dddc699ac1fec52b3bb47ca6116d2654abc16 /drivers/gpu/drm/drm_fops.c
parent6cb3b7f1c013fd4bea41e16ee557bcb2f1561787 (diff)
downloadlinux-1793126fcebd7c18834f95d43b55e387a8803aa8.tar.gz
linux-1793126fcebd7c18834f95d43b55e387a8803aa8.tar.bz2
linux-1793126fcebd7c18834f95d43b55e387a8803aa8.zip
drm: implement experimental render nodes
Render nodes provide an API for userspace to use non-privileged GPU commands without any running DRM-Master. It is useful for offscreen rendering, GPGPU clients, and normal render clients which do not perform modesetting. Compared to legacy clients, render clients no longer need any authentication to perform client ioctls. Instead, user-space controls render/client access to GPUs via filesystem access-modes on the render-node. Once a render-node was opened, a client has full access to the client/render operations on the GPU. However, no modesetting or ioctls that affect global state are allowed on render nodes. To prevent privilege-escalation, drivers must explicitly state that they support render nodes. They must mark their render-only ioctls as DRM_RENDER_ALLOW so render clients can use them. Furthermore, they must support clients without any attached master. If filesystem access-modes are not enough for fine-grained access control to render nodes (very unlikely, considering the versaitlity of FS-ACLs), you may still fall-back to fd-passing from server to client (which allows arbitrary access-control). However, note that revoking access is currently impossible and unlikely to get implemented. Note: Render clients no longer have any associated DRM-Master as they are supposed to be independent of any server state. DRM core highly depends on file_priv->master to be non-NULL for modesetting/ctx/etc. commands. Therefore, drivers must be very careful to not require DRM-Master if they support DRIVER_RENDER. So far render-nodes are protected by "drm_rnodes". As long as this module-parameter is not set to 1, a driver will not create render nodes. This allows us to experiment with the API a bit before we stabilize it. v2: drop insecure GEM_FLINK to force use of dmabuf Signed-off-by: David Herrmann <dh.herrmann@gmail.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/drm_fops.c')
-rw-r--r--drivers/gpu/drm/drm_fops.c14
1 files changed, 7 insertions, 7 deletions
diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c
index 136c949307ba..4be8e09a32ef 100644
--- a/drivers/gpu/drm/drm_fops.c
+++ b/drivers/gpu/drm/drm_fops.c
@@ -262,10 +262,10 @@ static int drm_open_helper(struct inode *inode, struct file *filp,
goto out_prime_destroy;
}
-
- /* if there is no current master make this fd it */
+ /* if there is no current master make this fd it, but do not create
+ * any master object for render clients */
mutex_lock(&dev->struct_mutex);
- if (!priv->minor->master) {
+ if (!priv->minor->master && !drm_is_render_client(priv)) {
/* create a new master */
priv->minor->master = drm_master_create(priv->minor);
if (!priv->minor->master) {
@@ -303,12 +303,11 @@ static int drm_open_helper(struct inode *inode, struct file *filp,
goto out_close;
}
}
- mutex_unlock(&dev->struct_mutex);
- } else {
+ } else if (!drm_is_render_client(priv)) {
/* get a reference to the master */
priv->master = drm_master_get(priv->minor->master);
- mutex_unlock(&dev->struct_mutex);
}
+ mutex_unlock(&dev->struct_mutex);
mutex_lock(&dev->struct_mutex);
list_add(&priv->lhead, &dev->filelist);
@@ -478,7 +477,8 @@ int drm_release(struct inode *inode, struct file *filp)
iput(container_of(dev->dev_mapping, struct inode, i_data));
/* drop the reference held my the file priv */
- drm_master_put(&file_priv->master);
+ if (file_priv->master)
+ drm_master_put(&file_priv->master);
file_priv->is_master = 0;
list_del(&file_priv->lhead);
mutex_unlock(&dev->struct_mutex);