* [PATCH v4 1/5] drm: fix null ptr dereference in drm_master_release
2021-08-20 10:02 [PATCH v4 0/5] drm: update locking for modesetting Desmond Cheong Zhi Xi
@ 2021-08-20 10:02 ` Desmond Cheong Zhi Xi
2021-08-20 10:02 ` [PATCH v4 2/5] drm: convert drm_device.master_mutex into a rwsem Desmond Cheong Zhi Xi
` (3 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Desmond Cheong Zhi Xi @ 2021-08-20 10:02 UTC (permalink / raw)
To: maarten.lankhorst, mripard, tzimmermann, airlied, daniel,
sumit.semwal, christian.koenig
Cc: Desmond Cheong Zhi Xi, dri-devel, linux-kernel, intel-gfx,
linux-media, linaro-mm-sig, skhan, gregkh, linux-kernel-mentees
drm_master_release can be called on a drm_file without a master, which
results in a null ptr dereference of file_priv->master->magic_map. The
three cases are:
1. Error path in drm_open_helper
drm_open():
drm_open_helper():
drm_master_open():
drm_new_set_master(); <--- returns -ENOMEM,
drm_file.master not set
drm_file_free():
drm_master_release(); <--- NULL ptr dereference
(file_priv->master->magic_map)
2. Error path in mock_drm_getfile
mock_drm_getfile():
anon_inode_getfile(); <--- returns error, drm_file.master not set
drm_file_free():
drm_master_release(); <--- NULL ptr dereference
(file_priv->master->magic_map)
3. In drm_client_close, as drm_client_open doesn't set up a master
drm_file.master is set up in drm_open_helper through the call to
drm_master_open, so we mirror it with a call to drm_master_release in
drm_close_helper, and remove drm_master_release from drm_file_free to
avoid the null ptr dereference.
Signed-off-by: Desmond Cheong Zhi Xi <desmondcheongzx@gmail.com>
---
drivers/gpu/drm/drm_file.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/drm_file.c b/drivers/gpu/drm/drm_file.c
index ed25168619fc..90b62f360da1 100644
--- a/drivers/gpu/drm/drm_file.c
+++ b/drivers/gpu/drm/drm_file.c
@@ -282,9 +282,6 @@ void drm_file_free(struct drm_file *file)
drm_legacy_ctxbitmap_flush(dev, file);
- if (drm_is_primary_client(file))
- drm_master_release(file);
-
if (dev->driver->postclose)
dev->driver->postclose(dev, file);
@@ -305,6 +302,9 @@ static void drm_close_helper(struct file *filp)
list_del(&file_priv->lhead);
mutex_unlock(&dev->filelist_mutex);
+ if (drm_is_primary_client(file_priv))
+ drm_master_release(file_priv);
+
drm_file_free(file_priv);
}
--
2.25.1
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH v4 2/5] drm: convert drm_device.master_mutex into a rwsem
2021-08-20 10:02 [PATCH v4 0/5] drm: update locking for modesetting Desmond Cheong Zhi Xi
2021-08-20 10:02 ` [PATCH v4 1/5] drm: fix null ptr dereference in drm_master_release Desmond Cheong Zhi Xi
@ 2021-08-20 10:02 ` Desmond Cheong Zhi Xi
2021-08-20 10:02 ` [PATCH v4 3/5] drm: lock drm_global_mutex earlier in the ioctl handler Desmond Cheong Zhi Xi
` (2 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Desmond Cheong Zhi Xi @ 2021-08-20 10:02 UTC (permalink / raw)
To: maarten.lankhorst, mripard, tzimmermann, airlied, daniel,
sumit.semwal, christian.koenig
Cc: Desmond Cheong Zhi Xi, dri-devel, linux-kernel, intel-gfx,
linux-media, linaro-mm-sig, skhan, gregkh, linux-kernel-mentees
drm_device.master_mutex currently protects the following:
- drm_device.master
- drm_file.master
- drm_file.was_master
- drm_file.is_master
- drm_master.unique
- drm_master.unique_len
- drm_master.magic_map
There is a clear separation between functions that read or change
these attributes. Hence, convert master_mutex into a rwsem to enable
concurrent readers.
Signed-off-by: Desmond Cheong Zhi Xi <desmondcheongzx@gmail.com>
---
drivers/gpu/drm/drm_auth.c | 35 ++++++++++++++++++-----------------
drivers/gpu/drm/drm_debugfs.c | 4 ++--
drivers/gpu/drm/drm_drv.c | 3 +--
drivers/gpu/drm/drm_ioctl.c | 10 +++++-----
include/drm/drm_auth.h | 6 +++---
include/drm/drm_device.h | 10 ++++++----
include/drm/drm_file.h | 12 ++++++------
7 files changed, 41 insertions(+), 39 deletions(-)
diff --git a/drivers/gpu/drm/drm_auth.c b/drivers/gpu/drm/drm_auth.c
index 60a6b21474b1..73ade0513ccb 100644
--- a/drivers/gpu/drm/drm_auth.c
+++ b/drivers/gpu/drm/drm_auth.c
@@ -64,7 +64,7 @@
static bool drm_is_current_master_locked(struct drm_file *fpriv)
{
lockdep_assert_once(lockdep_is_held(&fpriv->master_lookup_lock) ||
- lockdep_is_held(&fpriv->minor->dev->master_mutex));
+ lockdep_is_held(&fpriv->minor->dev->master_rwsem));
return fpriv->is_master && drm_lease_owner(fpriv->master) == fpriv->minor->dev->master;
}
@@ -96,7 +96,7 @@ int drm_getmagic(struct drm_device *dev, void *data, struct drm_file *file_priv)
struct drm_auth *auth = data;
int ret = 0;
- mutex_lock(&dev->master_mutex);
+ down_write(&dev->master_rwsem);
if (!file_priv->magic) {
ret = idr_alloc(&file_priv->master->magic_map, file_priv,
1, 0, GFP_KERNEL);
@@ -104,7 +104,7 @@ int drm_getmagic(struct drm_device *dev, void *data, struct drm_file *file_priv)
file_priv->magic = ret;
}
auth->magic = file_priv->magic;
- mutex_unlock(&dev->master_mutex);
+ up_write(&dev->master_rwsem);
DRM_DEBUG("%u\n", auth->magic);
@@ -119,13 +119,13 @@ int drm_authmagic(struct drm_device *dev, void *data,
DRM_DEBUG("%u\n", auth->magic);
- mutex_lock(&dev->master_mutex);
+ down_write(&dev->master_rwsem);
file = idr_find(&file_priv->master->magic_map, auth->magic);
if (file) {
file->authenticated = 1;
idr_replace(&file_priv->master->magic_map, NULL, auth->magic);
}
- mutex_unlock(&dev->master_mutex);
+ up_write(&dev->master_rwsem);
return file ? 0 : -EINVAL;
}
@@ -167,7 +167,7 @@ static int drm_new_set_master(struct drm_device *dev, struct drm_file *fpriv)
struct drm_master *old_master;
struct drm_master *new_master;
- lockdep_assert_held_once(&dev->master_mutex);
+ lockdep_assert_held_once(&dev->master_rwsem);
WARN_ON(fpriv->is_master);
old_master = fpriv->master;
@@ -249,7 +249,7 @@ int drm_setmaster_ioctl(struct drm_device *dev, void *data,
{
int ret;
- mutex_lock(&dev->master_mutex);
+ down_write(&dev->master_rwsem);
ret = drm_master_check_perm(dev, file_priv);
if (ret)
@@ -281,7 +281,7 @@ int drm_setmaster_ioctl(struct drm_device *dev, void *data,
drm_set_master(dev, file_priv, false);
out_unlock:
- mutex_unlock(&dev->master_mutex);
+ up_write(&dev->master_rwsem);
return ret;
}
@@ -298,7 +298,7 @@ int drm_dropmaster_ioctl(struct drm_device *dev, void *data,
{
int ret;
- mutex_lock(&dev->master_mutex);
+ down_write(&dev->master_rwsem);
ret = drm_master_check_perm(dev, file_priv);
if (ret)
@@ -321,8 +321,9 @@ int drm_dropmaster_ioctl(struct drm_device *dev, void *data,
}
drm_drop_master(dev, file_priv);
+
out_unlock:
- mutex_unlock(&dev->master_mutex);
+ up_write(&dev->master_rwsem);
return ret;
}
@@ -334,7 +335,7 @@ int drm_master_open(struct drm_file *file_priv)
/* if there is no current master make this fd it, but do not create
* any master object for render clients
*/
- mutex_lock(&dev->master_mutex);
+ down_write(&dev->master_rwsem);
if (!dev->master) {
ret = drm_new_set_master(dev, file_priv);
} else {
@@ -342,7 +343,7 @@ int drm_master_open(struct drm_file *file_priv)
file_priv->master = drm_master_get(dev->master);
spin_unlock(&file_priv->master_lookup_lock);
}
- mutex_unlock(&dev->master_mutex);
+ up_write(&dev->master_rwsem);
return ret;
}
@@ -352,7 +353,7 @@ void drm_master_release(struct drm_file *file_priv)
struct drm_device *dev = file_priv->minor->dev;
struct drm_master *master;
- mutex_lock(&dev->master_mutex);
+ down_write(&dev->master_rwsem);
master = file_priv->master;
if (file_priv->magic)
idr_remove(&file_priv->master->magic_map, file_priv->magic);
@@ -375,7 +376,7 @@ void drm_master_release(struct drm_file *file_priv)
/* drop the master reference held by the file priv */
if (file_priv->master)
drm_master_put(&file_priv->master);
- mutex_unlock(&dev->master_mutex);
+ up_write(&dev->master_rwsem);
}
/**
@@ -450,9 +451,9 @@ EXPORT_SYMBOL(drm_master_put);
/* Used by drm_client and drm_fb_helper */
bool drm_master_internal_acquire(struct drm_device *dev)
{
- mutex_lock(&dev->master_mutex);
+ down_read(&dev->master_rwsem);
if (dev->master) {
- mutex_unlock(&dev->master_mutex);
+ up_read(&dev->master_rwsem);
return false;
}
@@ -463,6 +464,6 @@ EXPORT_SYMBOL(drm_master_internal_acquire);
/* Used by drm_client and drm_fb_helper */
void drm_master_internal_release(struct drm_device *dev)
{
- mutex_unlock(&dev->master_mutex);
+ up_read(&dev->master_rwsem);
}
EXPORT_SYMBOL(drm_master_internal_release);
diff --git a/drivers/gpu/drm/drm_debugfs.c b/drivers/gpu/drm/drm_debugfs.c
index b0a826489488..b34c9c263188 100644
--- a/drivers/gpu/drm/drm_debugfs.c
+++ b/drivers/gpu/drm/drm_debugfs.c
@@ -55,7 +55,7 @@ static int drm_name_info(struct seq_file *m, void *data)
struct drm_device *dev = minor->dev;
struct drm_master *master;
- mutex_lock(&dev->master_mutex);
+ down_read(&dev->master_rwsem);
master = dev->master;
seq_printf(m, "%s", dev->driver->name);
if (dev->dev)
@@ -65,7 +65,7 @@ static int drm_name_info(struct seq_file *m, void *data)
if (dev->unique)
seq_printf(m, " unique=%s", dev->unique);
seq_printf(m, "\n");
- mutex_unlock(&dev->master_mutex);
+ up_read(&dev->master_rwsem);
return 0;
}
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
index 7a5097467ba5..4556bf42954c 100644
--- a/drivers/gpu/drm/drm_drv.c
+++ b/drivers/gpu/drm/drm_drv.c
@@ -570,7 +570,6 @@ static void drm_dev_init_release(struct drm_device *dev, void *res)
/* Prevent use-after-free in drm_managed_release when debugging is
* enabled. Slightly awkward, but can't really be helped. */
dev->dev = NULL;
- mutex_destroy(&dev->master_mutex);
mutex_destroy(&dev->clientlist_mutex);
mutex_destroy(&dev->filelist_mutex);
mutex_destroy(&dev->struct_mutex);
@@ -611,7 +610,7 @@ static int drm_dev_init(struct drm_device *dev,
mutex_init(&dev->struct_mutex);
mutex_init(&dev->filelist_mutex);
mutex_init(&dev->clientlist_mutex);
- mutex_init(&dev->master_mutex);
+ init_rwsem(&dev->master_rwsem);
ret = drmm_add_action(dev, drm_dev_init_release, NULL);
if (ret)
diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c
index 26f3a9ede8fe..d25713b09b80 100644
--- a/drivers/gpu/drm/drm_ioctl.c
+++ b/drivers/gpu/drm/drm_ioctl.c
@@ -119,16 +119,16 @@ int drm_getunique(struct drm_device *dev, void *data,
struct drm_unique *u = data;
struct drm_master *master;
- mutex_lock(&dev->master_mutex);
+ down_read(&dev->master_rwsem);
master = file_priv->master;
if (u->unique_len >= master->unique_len) {
if (copy_to_user(u->unique, master->unique, master->unique_len)) {
- mutex_unlock(&dev->master_mutex);
+ up_read(&dev->master_rwsem);
return -EFAULT;
}
}
u->unique_len = master->unique_len;
- mutex_unlock(&dev->master_mutex);
+ up_read(&dev->master_rwsem);
return 0;
}
@@ -385,7 +385,7 @@ static int drm_setversion(struct drm_device *dev, void *data, struct drm_file *f
struct drm_set_version *sv = data;
int if_version, retcode = 0;
- mutex_lock(&dev->master_mutex);
+ down_write(&dev->master_rwsem);
if (sv->drm_di_major != -1) {
if (sv->drm_di_major != DRM_IF_MAJOR ||
sv->drm_di_minor < 0 || sv->drm_di_minor > DRM_IF_MINOR) {
@@ -420,7 +420,7 @@ static int drm_setversion(struct drm_device *dev, void *data, struct drm_file *f
sv->drm_di_minor = DRM_IF_MINOR;
sv->drm_dd_major = dev->driver->major;
sv->drm_dd_minor = dev->driver->minor;
- mutex_unlock(&dev->master_mutex);
+ up_write(&dev->master_rwsem);
return retcode;
}
diff --git a/include/drm/drm_auth.h b/include/drm/drm_auth.h
index ba248ca8866f..f0a89e5fcaad 100644
--- a/include/drm/drm_auth.h
+++ b/include/drm/drm_auth.h
@@ -67,17 +67,17 @@ struct drm_master {
struct drm_device *dev;
/**
* @unique: Unique identifier: e.g. busid. Protected by
- * &drm_device.master_mutex.
+ * &drm_device.master_rwsem.
*/
char *unique;
/**
* @unique_len: Length of unique field. Protected by
- * &drm_device.master_mutex.
+ * &drm_device.master_rwsem.
*/
int unique_len;
/**
* @magic_map: Map of used authentication tokens. Protected by
- * &drm_device.master_mutex.
+ * &drm_device.master_rwsem.
*/
struct idr magic_map;
void *driver_priv;
diff --git a/include/drm/drm_device.h b/include/drm/drm_device.h
index 604b1d1b2d72..142fb2f6e74d 100644
--- a/include/drm/drm_device.h
+++ b/include/drm/drm_device.h
@@ -107,7 +107,7 @@ struct drm_device {
* @master:
*
* Currently active master for this device.
- * Protected by &master_mutex
+ * Protected by &master_rwsem
*/
struct drm_master *master;
@@ -146,11 +146,13 @@ struct drm_device {
struct mutex struct_mutex;
/**
- * @master_mutex:
+ * @master_rwsem:
*
- * Lock for &drm_minor.master and &drm_file.is_master
+ * Lock for &drm_device.master, &drm_file.was_master,
+ * &drm_file.is_master, &drm_file.master, &drm_master.unique,
+ * &drm_master.unique_len, and &drm_master.magic_map.
*/
- struct mutex master_mutex;
+ struct rw_semaphore master_rwsem;
/**
* @open_count:
diff --git a/include/drm/drm_file.h b/include/drm/drm_file.h
index a3acb7ac3550..d12bb2ba7814 100644
--- a/include/drm/drm_file.h
+++ b/include/drm/drm_file.h
@@ -205,7 +205,7 @@ struct drm_file {
* @was_master:
*
* This client has or had, master capability. Protected by struct
- * &drm_device.master_mutex.
+ * &drm_device.master_rwsem.
*
* This is used to ensure that CAP_SYS_ADMIN is not enforced, if the
* client is or was master in the past.
@@ -216,7 +216,7 @@ struct drm_file {
* @is_master:
*
* This client is the creator of @master. Protected by struct
- * &drm_device.master_mutex.
+ * &drm_device.master_rwsem.
*
* See also the :ref:`section on primary nodes and authentication
* <drm_primary_node>`.
@@ -227,19 +227,19 @@ struct drm_file {
* @master:
*
* Master this node is currently associated with. Protected by struct
- * &drm_device.master_mutex, and serialized by @master_lookup_lock.
+ * &drm_device.master_rwsem, and serialized by @master_lookup_lock.
*
* Only relevant if drm_is_primary_client() returns true. Note that
* this only matches &drm_device.master if the master is the currently
* active one.
*
- * To update @master, both &drm_device.master_mutex and
+ * To update @master, both &drm_device.master_rwsem and
* @master_lookup_lock need to be held, therefore holding either of
* them is safe and enough for the read side.
*
* When dereferencing this pointer, either hold struct
- * &drm_device.master_mutex for the duration of the pointer's use, or
- * use drm_file_get_master() if struct &drm_device.master_mutex is not
+ * &drm_device.master_rwsem for the duration of the pointer's use, or
+ * use drm_file_get_master() if struct &drm_device.master_rwsem is not
* currently held and there is no other need to hold it. This prevents
* @master from being freed during use.
*
--
2.25.1
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH v4 3/5] drm: lock drm_global_mutex earlier in the ioctl handler
2021-08-20 10:02 [PATCH v4 0/5] drm: update locking for modesetting Desmond Cheong Zhi Xi
2021-08-20 10:02 ` [PATCH v4 1/5] drm: fix null ptr dereference in drm_master_release Desmond Cheong Zhi Xi
2021-08-20 10:02 ` [PATCH v4 2/5] drm: convert drm_device.master_mutex into a rwsem Desmond Cheong Zhi Xi
@ 2021-08-20 10:02 ` Desmond Cheong Zhi Xi
2021-08-20 10:02 ` [PATCH v4 4/5] drm: avoid races with modesetting rights Desmond Cheong Zhi Xi
2021-08-20 10:02 ` [PATCH v4 5/5] drm: remove drm_file.master_lookup_lock Desmond Cheong Zhi Xi
4 siblings, 0 replies; 6+ messages in thread
From: Desmond Cheong Zhi Xi @ 2021-08-20 10:02 UTC (permalink / raw)
To: maarten.lankhorst, mripard, tzimmermann, airlied, daniel,
sumit.semwal, christian.koenig
Cc: Desmond Cheong Zhi Xi, dri-devel, linux-kernel, intel-gfx,
linux-media, linaro-mm-sig, skhan, gregkh, linux-kernel-mentees
In a future patch, a read lock on drm_device.master_rwsem is
held in the ioctl handler before the check for ioctl
permissions. However, this inverts the lock hierarchy of
drm_global_mutex --> master_rwsem.
To avoid this, we do some prep work to grab the drm_global_mutex
before checking for ioctl permissions.
Signed-off-by: Desmond Cheong Zhi Xi <desmondcheongzx@gmail.com>
---
drivers/gpu/drm/drm_ioctl.c | 18 +++++++++---------
1 file changed, 9 insertions(+), 9 deletions(-)
diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c
index d25713b09b80..158629d88319 100644
--- a/drivers/gpu/drm/drm_ioctl.c
+++ b/drivers/gpu/drm/drm_ioctl.c
@@ -772,19 +772,19 @@ long drm_ioctl_kernel(struct file *file, drm_ioctl_t *func, void *kdata,
if (drm_dev_is_unplugged(dev))
return -ENODEV;
+ /* Enforce sane locking for modern driver ioctls. */
+ if (unlikely(drm_core_check_feature(dev, DRIVER_LEGACY)) && !(flags & DRM_UNLOCKED))
+ mutex_lock(&drm_global_mutex);
+
retcode = drm_ioctl_permit(flags, file_priv);
if (unlikely(retcode))
- return retcode;
+ goto out;
- /* Enforce sane locking for modern driver ioctls. */
- if (likely(!drm_core_check_feature(dev, DRIVER_LEGACY)) ||
- (flags & DRM_UNLOCKED))
- retcode = func(dev, kdata, file_priv);
- else {
- mutex_lock(&drm_global_mutex);
- retcode = func(dev, kdata, file_priv);
+ retcode = func(dev, kdata, file_priv);
+
+out:
+ if (unlikely(drm_core_check_feature(dev, DRIVER_LEGACY)) && !(flags & DRM_UNLOCKED))
mutex_unlock(&drm_global_mutex);
- }
return retcode;
}
EXPORT_SYMBOL(drm_ioctl_kernel);
--
2.25.1
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH v4 4/5] drm: avoid races with modesetting rights
2021-08-20 10:02 [PATCH v4 0/5] drm: update locking for modesetting Desmond Cheong Zhi Xi
` (2 preceding siblings ...)
2021-08-20 10:02 ` [PATCH v4 3/5] drm: lock drm_global_mutex earlier in the ioctl handler Desmond Cheong Zhi Xi
@ 2021-08-20 10:02 ` Desmond Cheong Zhi Xi
2021-08-20 10:02 ` [PATCH v4 5/5] drm: remove drm_file.master_lookup_lock Desmond Cheong Zhi Xi
4 siblings, 0 replies; 6+ messages in thread
From: Desmond Cheong Zhi Xi @ 2021-08-20 10:02 UTC (permalink / raw)
To: maarten.lankhorst, mripard, tzimmermann, airlied, daniel,
sumit.semwal, christian.koenig
Cc: Desmond Cheong Zhi Xi, dri-devel, linux-kernel, intel-gfx,
linux-media, linaro-mm-sig, skhan, gregkh, linux-kernel-mentees,
Daniel Vetter
In drm_client_modeset.c and drm_fb_helper.c,
drm_master_internal_{acquire,release} are used to avoid races with DRM
userspace. These functions hold onto drm_device.master_rwsem while
committing, and bail if there's already a master.
However, there are other places where modesetting rights can race. A
time-of-check-to-time-of-use error can occur if an ioctl that changes
the modeset has its rights revoked after it validates its permissions,
but before it completes.
There are four places where modesetting permissions can change:
- DROP_MASTER ioctl removes rights for a master and its leases
- REVOKE_LEASE ioctl revokes rights for a specific lease
- SET_MASTER ioctl sets the device master if the master role hasn't
been acquired yet
- drm_open which can create a new master for a device if one does not
currently exist
These races can be avoided using drm_device.master_rwsem: users that
perform modesetting should hold a read lock on the new
drm_device.master_rwsem, and users that change these permissions
should hold a write lock.
To avoid deadlocks with master_rwsem, for ioctls that need to check
for modesetting permissions, but also need to hold a write lock on
master_rwsem to protect some other attribute (or recurses to some
function that holds a write lock, like drm_mode_create_lease_ioctl
which eventually calls drm_master_open), we remove the DRM_MASTER flag
and push the master_rwsem lock and permissions check into the ioctl.
Reported-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: Desmond Cheong Zhi Xi <desmondcheongzx@gmail.com>
---
drivers/gpu/drm/drm_auth.c | 4 ++++
drivers/gpu/drm/drm_ioctl.c | 20 +++++++++++++++-----
drivers/gpu/drm/drm_lease.c | 35 ++++++++++++++++++++++++-----------
include/drm/drm_device.h | 5 +++++
4 files changed, 48 insertions(+), 16 deletions(-)
diff --git a/drivers/gpu/drm/drm_auth.c b/drivers/gpu/drm/drm_auth.c
index 73ade0513ccb..65065f7e1499 100644
--- a/drivers/gpu/drm/drm_auth.c
+++ b/drivers/gpu/drm/drm_auth.c
@@ -120,6 +120,10 @@ int drm_authmagic(struct drm_device *dev, void *data,
DRM_DEBUG("%u\n", auth->magic);
down_write(&dev->master_rwsem);
+ if (unlikely(!drm_is_current_master(file_priv))) {
+ up_write(&dev->master_rwsem);
+ return -EACCES;
+ }
file = idr_find(&file_priv->master->magic_map, auth->magic);
if (file) {
file->authenticated = 1;
diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c
index 158629d88319..8bea39ffc5c0 100644
--- a/drivers/gpu/drm/drm_ioctl.c
+++ b/drivers/gpu/drm/drm_ioctl.c
@@ -386,6 +386,10 @@ static int drm_setversion(struct drm_device *dev, void *data, struct drm_file *f
int if_version, retcode = 0;
down_write(&dev->master_rwsem);
+ if (unlikely(!drm_is_current_master(file_priv))) {
+ retcode = -EACCES;
+ goto unlock;
+ }
if (sv->drm_di_major != -1) {
if (sv->drm_di_major != DRM_IF_MAJOR ||
sv->drm_di_minor < 0 || sv->drm_di_minor > DRM_IF_MINOR) {
@@ -420,8 +424,9 @@ static int drm_setversion(struct drm_device *dev, void *data, struct drm_file *f
sv->drm_di_minor = DRM_IF_MINOR;
sv->drm_dd_major = dev->driver->major;
sv->drm_dd_minor = dev->driver->minor;
- up_write(&dev->master_rwsem);
+unlock:
+ up_write(&dev->master_rwsem);
return retcode;
}
@@ -574,12 +579,12 @@ static const struct drm_ioctl_desc drm_ioctls[] = {
DRM_IOCTL_DEF(DRM_IOCTL_GET_STATS, drm_getstats, 0),
DRM_IOCTL_DEF(DRM_IOCTL_GET_CAP, drm_getcap, DRM_RENDER_ALLOW),
DRM_IOCTL_DEF(DRM_IOCTL_SET_CLIENT_CAP, drm_setclientcap, 0),
- DRM_IOCTL_DEF(DRM_IOCTL_SET_VERSION, drm_setversion, DRM_MASTER),
+ DRM_IOCTL_DEF(DRM_IOCTL_SET_VERSION, drm_setversion, 0),
DRM_IOCTL_DEF(DRM_IOCTL_SET_UNIQUE, drm_invalid_op, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
DRM_IOCTL_DEF(DRM_IOCTL_BLOCK, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
DRM_IOCTL_DEF(DRM_IOCTL_UNBLOCK, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
- DRM_IOCTL_DEF(DRM_IOCTL_AUTH_MAGIC, drm_authmagic, DRM_MASTER),
+ DRM_IOCTL_DEF(DRM_IOCTL_AUTH_MAGIC, drm_authmagic, 0),
DRM_LEGACY_IOCTL_DEF(DRM_IOCTL_ADD_MAP, drm_legacy_addmap_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
DRM_LEGACY_IOCTL_DEF(DRM_IOCTL_RM_MAP, drm_legacy_rmmap_ioctl, DRM_AUTH),
@@ -706,10 +711,10 @@ static const struct drm_ioctl_desc drm_ioctls[] = {
DRM_RENDER_ALLOW),
DRM_IOCTL_DEF(DRM_IOCTL_CRTC_GET_SEQUENCE, drm_crtc_get_sequence_ioctl, 0),
DRM_IOCTL_DEF(DRM_IOCTL_CRTC_QUEUE_SEQUENCE, drm_crtc_queue_sequence_ioctl, 0),
- DRM_IOCTL_DEF(DRM_IOCTL_MODE_CREATE_LEASE, drm_mode_create_lease_ioctl, DRM_MASTER),
+ DRM_IOCTL_DEF(DRM_IOCTL_MODE_CREATE_LEASE, drm_mode_create_lease_ioctl, 0),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_LIST_LESSEES, drm_mode_list_lessees_ioctl, DRM_MASTER),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_GET_LEASE, drm_mode_get_lease_ioctl, DRM_MASTER),
- DRM_IOCTL_DEF(DRM_IOCTL_MODE_REVOKE_LEASE, drm_mode_revoke_lease_ioctl, DRM_MASTER),
+ DRM_IOCTL_DEF(DRM_IOCTL_MODE_REVOKE_LEASE, drm_mode_revoke_lease_ioctl, 0),
};
#define DRM_CORE_IOCTL_COUNT ARRAY_SIZE( drm_ioctls )
@@ -776,6 +781,9 @@ long drm_ioctl_kernel(struct file *file, drm_ioctl_t *func, void *kdata,
if (unlikely(drm_core_check_feature(dev, DRIVER_LEGACY)) && !(flags & DRM_UNLOCKED))
mutex_lock(&drm_global_mutex);
+ if (unlikely(flags & DRM_MASTER))
+ down_read(&dev->master_rwsem);
+
retcode = drm_ioctl_permit(flags, file_priv);
if (unlikely(retcode))
goto out;
@@ -783,6 +791,8 @@ long drm_ioctl_kernel(struct file *file, drm_ioctl_t *func, void *kdata,
retcode = func(dev, kdata, file_priv);
out:
+ if (unlikely(flags & DRM_MASTER))
+ up_read(&dev->master_rwsem);
if (unlikely(drm_core_check_feature(dev, DRIVER_LEGACY)) && !(flags & DRM_UNLOCKED))
mutex_unlock(&drm_global_mutex);
return retcode;
diff --git a/drivers/gpu/drm/drm_lease.c b/drivers/gpu/drm/drm_lease.c
index dee4f24a1808..bed6f7636cbe 100644
--- a/drivers/gpu/drm/drm_lease.c
+++ b/drivers/gpu/drm/drm_lease.c
@@ -500,6 +500,18 @@ int drm_mode_create_lease_ioctl(struct drm_device *dev,
return -EINVAL;
}
+ /* Clone the lessor file to create a new file for us */
+ DRM_DEBUG_LEASE("Allocating lease file\n");
+ lessee_file = file_clone_open(lessor_file);
+ if (IS_ERR(lessee_file))
+ return PTR_ERR(lessee_file);
+
+ down_read(&dev->master_rwsem);
+ if (unlikely(!drm_is_current_master(lessor_priv))) {
+ ret = -EACCES;
+ goto out_file;
+ }
+
lessor = drm_file_get_master(lessor_priv);
/* Do not allow sub-leases */
if (lessor->lessor) {
@@ -547,14 +559,6 @@ int drm_mode_create_lease_ioctl(struct drm_device *dev,
goto out_leases;
}
- /* Clone the lessor file to create a new file for us */
- DRM_DEBUG_LEASE("Allocating lease file\n");
- lessee_file = file_clone_open(lessor_file);
- if (IS_ERR(lessee_file)) {
- ret = PTR_ERR(lessee_file);
- goto out_lessee;
- }
-
lessee_priv = lessee_file->private_data;
/* Change the file to a master one */
drm_master_put(&lessee_priv->master);
@@ -571,17 +575,19 @@ int drm_mode_create_lease_ioctl(struct drm_device *dev,
fd_install(fd, lessee_file);
drm_master_put(&lessor);
+ up_read(&dev->master_rwsem);
DRM_DEBUG_LEASE("drm_mode_create_lease_ioctl succeeded\n");
return 0;
-out_lessee:
- drm_master_put(&lessee);
-
out_leases:
put_unused_fd(fd);
out_lessor:
drm_master_put(&lessor);
+
+out_file:
+ up_read(&dev->master_rwsem);
+ fput(lessee_file);
DRM_DEBUG_LEASE("drm_mode_create_lease_ioctl failed: %d\n", ret);
return ret;
}
@@ -705,6 +711,11 @@ int drm_mode_revoke_lease_ioctl(struct drm_device *dev,
if (!drm_core_check_feature(dev, DRIVER_MODESET))
return -EOPNOTSUPP;
+ down_write(&dev->master_rwsem);
+ if (unlikely(!drm_is_current_master(lessor_priv))) {
+ ret = -EACCES;
+ goto unlock;
+ }
lessor = drm_file_get_master(lessor_priv);
mutex_lock(&dev->mode_config.idr_mutex);
@@ -728,5 +739,7 @@ int drm_mode_revoke_lease_ioctl(struct drm_device *dev,
mutex_unlock(&dev->mode_config.idr_mutex);
drm_master_put(&lessor);
+unlock:
+ up_write(&dev->master_rwsem);
return ret;
}
diff --git a/include/drm/drm_device.h b/include/drm/drm_device.h
index 142fb2f6e74d..7d32bb69e6db 100644
--- a/include/drm/drm_device.h
+++ b/include/drm/drm_device.h
@@ -151,6 +151,11 @@ struct drm_device {
* Lock for &drm_device.master, &drm_file.was_master,
* &drm_file.is_master, &drm_file.master, &drm_master.unique,
* &drm_master.unique_len, and &drm_master.magic_map.
+ *
+ * Additionally, synchronizes modesetting rights between multiple users.
+ * Users that can change the modeset or display state must hold a read
+ * lock on @master_rwsem, and users that change modesetting rights
+ * should hold a write lock.
*/
struct rw_semaphore master_rwsem;
--
2.25.1
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH v4 5/5] drm: remove drm_file.master_lookup_lock
2021-08-20 10:02 [PATCH v4 0/5] drm: update locking for modesetting Desmond Cheong Zhi Xi
` (3 preceding siblings ...)
2021-08-20 10:02 ` [PATCH v4 4/5] drm: avoid races with modesetting rights Desmond Cheong Zhi Xi
@ 2021-08-20 10:02 ` Desmond Cheong Zhi Xi
4 siblings, 0 replies; 6+ messages in thread
From: Desmond Cheong Zhi Xi @ 2021-08-20 10:02 UTC (permalink / raw)
To: maarten.lankhorst, mripard, tzimmermann, airlied, daniel,
sumit.semwal, christian.koenig
Cc: Desmond Cheong Zhi Xi, dri-devel, linux-kernel, intel-gfx,
linux-media, linaro-mm-sig, skhan, gregkh, linux-kernel-mentees
Previously, master_lookup_lock was introduced in
commit 0b0860a3cf5e ("drm: serialize drm_file.master with a new
spinlock") to serialize accesses to drm_file.master. This then allowed
us to write drm_file_get_master in commit 56f0729a510f ("drm: protect
drm_master pointers in drm_lease.c").
The rationale behind introducing a new spinlock at the time was that
the other lock that could have been used (drm_device.master_mutex) was
the outermost lock, so embedding calls to drm_file_get_master in
various functions easily caused us to invert the lock hierarchy. For
example, we would invert the master_mutex --> mode_config.idr_mutex
hierarchy.
Following the conversion of master_mutex into a rwsem, and its use to
plug races with modesetting rights, we've untangled some lock
hierarchies and removed the need for using drm_file_get_master and the
unlocked version of drm_is_current_master in multiple places.
Hence, we can take this opportunity to clean up the locking design. To
do so, we rewrite drm_file_get_master and drm_is_current_master to use
master_rwsem, clean up their uses, fix remaining inversions (such as
with _drm_lease_held master grabbing master_rwsem while holding onto
mode_config.idr_mutex), then remove master_lookup_lock.
Signed-off-by: Desmond Cheong Zhi Xi <desmondcheongzx@gmail.com>
---
drivers/gpu/drm/drm_auth.c | 19 ++++++----------
drivers/gpu/drm/drm_file.c | 1 -
drivers/gpu/drm/drm_internal.h | 1 +
drivers/gpu/drm/drm_ioctl.c | 4 ++--
drivers/gpu/drm/drm_lease.c | 38 ++++++++-----------------------
drivers/gpu/drm/drm_mode_object.c | 14 +++++++++---
include/drm/drm_file.h | 9 +-------
include/drm/drm_lease.h | 2 +-
8 files changed, 32 insertions(+), 56 deletions(-)
diff --git a/drivers/gpu/drm/drm_auth.c b/drivers/gpu/drm/drm_auth.c
index 65065f7e1499..ff720f67eacb 100644
--- a/drivers/gpu/drm/drm_auth.c
+++ b/drivers/gpu/drm/drm_auth.c
@@ -61,10 +61,9 @@
* trusted clients.
*/
-static bool drm_is_current_master_locked(struct drm_file *fpriv)
+bool drm_is_current_master_locked(struct drm_file *fpriv)
{
- lockdep_assert_once(lockdep_is_held(&fpriv->master_lookup_lock) ||
- lockdep_is_held(&fpriv->minor->dev->master_rwsem));
+ lockdep_assert_held_once(&fpriv->minor->dev->master_rwsem);
return fpriv->is_master && drm_lease_owner(fpriv->master) == fpriv->minor->dev->master;
}
@@ -83,9 +82,9 @@ bool drm_is_current_master(struct drm_file *fpriv)
{
bool ret;
- spin_lock(&fpriv->master_lookup_lock);
+ down_read(&fpriv->minor->dev->master_rwsem);
ret = drm_is_current_master_locked(fpriv);
- spin_unlock(&fpriv->master_lookup_lock);
+ up_read(&fpriv->minor->dev->master_rwsem);
return ret;
}
@@ -120,7 +119,7 @@ int drm_authmagic(struct drm_device *dev, void *data,
DRM_DEBUG("%u\n", auth->magic);
down_write(&dev->master_rwsem);
- if (unlikely(!drm_is_current_master(file_priv))) {
+ if (unlikely(!drm_is_current_master_locked(file_priv))) {
up_write(&dev->master_rwsem);
return -EACCES;
}
@@ -178,9 +177,7 @@ static int drm_new_set_master(struct drm_device *dev, struct drm_file *fpriv)
new_master = drm_master_create(dev);
if (!new_master)
return -ENOMEM;
- spin_lock(&fpriv->master_lookup_lock);
fpriv->master = new_master;
- spin_unlock(&fpriv->master_lookup_lock);
fpriv->is_master = 1;
fpriv->authenticated = 1;
@@ -343,9 +340,7 @@ int drm_master_open(struct drm_file *file_priv)
if (!dev->master) {
ret = drm_new_set_master(dev, file_priv);
} else {
- spin_lock(&file_priv->master_lookup_lock);
file_priv->master = drm_master_get(dev->master);
- spin_unlock(&file_priv->master_lookup_lock);
}
up_write(&dev->master_rwsem);
@@ -410,13 +405,13 @@ struct drm_master *drm_file_get_master(struct drm_file *file_priv)
{
struct drm_master *master = NULL;
- spin_lock(&file_priv->master_lookup_lock);
+ down_read(&file_priv->minor->dev->master_rwsem);
if (!file_priv->master)
goto unlock;
master = drm_master_get(file_priv->master);
unlock:
- spin_unlock(&file_priv->master_lookup_lock);
+ up_read(&file_priv->minor->dev->master_rwsem);
return master;
}
EXPORT_SYMBOL(drm_file_get_master);
diff --git a/drivers/gpu/drm/drm_file.c b/drivers/gpu/drm/drm_file.c
index 90b62f360da1..8c846e0179d7 100644
--- a/drivers/gpu/drm/drm_file.c
+++ b/drivers/gpu/drm/drm_file.c
@@ -176,7 +176,6 @@ struct drm_file *drm_file_alloc(struct drm_minor *minor)
init_waitqueue_head(&file->event_wait);
file->event_space = 4096; /* set aside 4k for event buffer */
- spin_lock_init(&file->master_lookup_lock);
mutex_init(&file->event_read_lock);
if (drm_core_check_feature(dev, DRIVER_GEM))
diff --git a/drivers/gpu/drm/drm_internal.h b/drivers/gpu/drm/drm_internal.h
index 17f3548c8ed2..5d421f749a17 100644
--- a/drivers/gpu/drm/drm_internal.h
+++ b/drivers/gpu/drm/drm_internal.h
@@ -132,6 +132,7 @@ int drm_crtc_queue_sequence_ioctl(struct drm_device *dev, void *data,
struct drm_file *filp);
/* drm_auth.c */
+bool drm_is_current_master_locked(struct drm_file *fpriv);
int drm_getmagic(struct drm_device *dev, void *data,
struct drm_file *file_priv);
int drm_authmagic(struct drm_device *dev, void *data,
diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c
index 8bea39ffc5c0..c728437466c3 100644
--- a/drivers/gpu/drm/drm_ioctl.c
+++ b/drivers/gpu/drm/drm_ioctl.c
@@ -386,7 +386,7 @@ static int drm_setversion(struct drm_device *dev, void *data, struct drm_file *f
int if_version, retcode = 0;
down_write(&dev->master_rwsem);
- if (unlikely(!drm_is_current_master(file_priv))) {
+ if (unlikely(!drm_is_current_master_locked(file_priv))) {
retcode = -EACCES;
goto unlock;
}
@@ -540,7 +540,7 @@ static int drm_ioctl_permit(u32 flags, struct drm_file *file_priv)
/* MASTER is only for master or control clients */
if (unlikely((flags & DRM_MASTER) &&
- !drm_is_current_master(file_priv)))
+ !drm_is_current_master_locked(file_priv)))
return -EACCES;
/* Render clients must be explicitly allowed */
diff --git a/drivers/gpu/drm/drm_lease.c b/drivers/gpu/drm/drm_lease.c
index bed6f7636cbe..c515d40f32c0 100644
--- a/drivers/gpu/drm/drm_lease.c
+++ b/drivers/gpu/drm/drm_lease.c
@@ -85,7 +85,7 @@ _drm_find_lessee(struct drm_master *master, int lessee_id)
return idr_find(&drm_lease_owner(master)->lessee_idr, lessee_id);
}
-static int _drm_lease_held_master(struct drm_master *master, int id)
+bool _drm_lease_held_master(struct drm_master *master, int id)
{
lockdep_assert_held(&master->dev->mode_config.idr_mutex);
if (master->lessor)
@@ -105,24 +105,6 @@ static bool _drm_has_leased(struct drm_master *master, int id)
return false;
}
-/* Called with idr_mutex held */
-bool _drm_lease_held(struct drm_file *file_priv, int id)
-{
- bool ret;
- struct drm_master *master;
-
- if (!file_priv)
- return true;
-
- master = drm_file_get_master(file_priv);
- if (!master)
- return true;
- ret = _drm_lease_held_master(master, id);
- drm_master_put(&master);
-
- return ret;
-}
-
bool drm_lease_held(struct drm_file *file_priv, int id)
{
struct drm_master *master;
@@ -507,12 +489,12 @@ int drm_mode_create_lease_ioctl(struct drm_device *dev,
return PTR_ERR(lessee_file);
down_read(&dev->master_rwsem);
- if (unlikely(!drm_is_current_master(lessor_priv))) {
+ if (unlikely(!drm_is_current_master_locked(lessor_priv))) {
ret = -EACCES;
goto out_file;
}
- lessor = drm_file_get_master(lessor_priv);
+ lessor = lessor_priv->master;
/* Do not allow sub-leases */
if (lessor->lessor) {
DRM_DEBUG_LEASE("recursive leasing not allowed\n");
@@ -574,7 +556,6 @@ int drm_mode_create_lease_ioctl(struct drm_device *dev,
/* Hook up the fd */
fd_install(fd, lessee_file);
- drm_master_put(&lessor);
up_read(&dev->master_rwsem);
DRM_DEBUG_LEASE("drm_mode_create_lease_ioctl succeeded\n");
return 0;
@@ -609,7 +590,8 @@ int drm_mode_list_lessees_ioctl(struct drm_device *dev,
if (!drm_core_check_feature(dev, DRIVER_MODESET))
return -EOPNOTSUPP;
- lessor = drm_file_get_master(lessor_priv);
+ lockdep_assert_held_once(&dev->master_rwsem);
+ lessor = lessor_priv->master;
DRM_DEBUG_LEASE("List lessees for %d\n", lessor->lessee_id);
mutex_lock(&dev->mode_config.idr_mutex);
@@ -633,7 +615,6 @@ int drm_mode_list_lessees_ioctl(struct drm_device *dev,
arg->count_lessees = count;
mutex_unlock(&dev->mode_config.idr_mutex);
- drm_master_put(&lessor);
return ret;
}
@@ -659,7 +640,8 @@ int drm_mode_get_lease_ioctl(struct drm_device *dev,
if (!drm_core_check_feature(dev, DRIVER_MODESET))
return -EOPNOTSUPP;
- lessee = drm_file_get_master(lessee_priv);
+ lockdep_assert_held_once(&dev->master_rwsem);
+ lessee = lessee_priv->master;
DRM_DEBUG_LEASE("get lease for %d\n", lessee->lessee_id);
mutex_lock(&dev->mode_config.idr_mutex);
@@ -687,7 +669,6 @@ int drm_mode_get_lease_ioctl(struct drm_device *dev,
arg->count_objects = count;
mutex_unlock(&dev->mode_config.idr_mutex);
- drm_master_put(&lessee);
return ret;
}
@@ -712,11 +693,11 @@ int drm_mode_revoke_lease_ioctl(struct drm_device *dev,
return -EOPNOTSUPP;
down_write(&dev->master_rwsem);
- if (unlikely(!drm_is_current_master(lessor_priv))) {
+ if (unlikely(!drm_is_current_master_locked(lessor_priv))) {
ret = -EACCES;
goto unlock;
}
- lessor = drm_file_get_master(lessor_priv);
+ lessor = lessor_priv->master;
mutex_lock(&dev->mode_config.idr_mutex);
lessee = _drm_find_lessee(lessor, arg->lessee_id);
@@ -737,7 +718,6 @@ int drm_mode_revoke_lease_ioctl(struct drm_device *dev,
fail:
mutex_unlock(&dev->mode_config.idr_mutex);
- drm_master_put(&lessor);
unlock:
up_write(&dev->master_rwsem);
diff --git a/drivers/gpu/drm/drm_mode_object.c b/drivers/gpu/drm/drm_mode_object.c
index 86d9e907c0b2..f15b81ea347a 100644
--- a/drivers/gpu/drm/drm_mode_object.c
+++ b/drivers/gpu/drm/drm_mode_object.c
@@ -29,6 +29,7 @@
#include <drm/drm_file.h>
#include <drm/drm_mode_object.h>
#include <drm/drm_print.h>
+#include <drm/drm_auth.h>
#include "drm_crtc_internal.h"
@@ -138,6 +139,10 @@ struct drm_mode_object *__drm_mode_object_find(struct drm_device *dev,
uint32_t id, uint32_t type)
{
struct drm_mode_object *obj = NULL;
+ struct drm_master *master = NULL;
+
+ if (file_priv)
+ master = drm_file_get_master(file_priv);
mutex_lock(&dev->mode_config.idr_mutex);
obj = idr_find(&dev->mode_config.object_idr, id);
@@ -146,15 +151,18 @@ struct drm_mode_object *__drm_mode_object_find(struct drm_device *dev,
if (obj && obj->id != id)
obj = NULL;
- if (obj && drm_mode_object_lease_required(obj->type) &&
- !_drm_lease_held(file_priv, obj->id))
- obj = NULL;
+ if (obj && drm_mode_object_lease_required(obj->type)) {
+ if (master && !_drm_lease_held_master(master, obj->id))
+ obj = NULL;
+ }
if (obj && obj->free_cb) {
if (!kref_get_unless_zero(&obj->refcount))
obj = NULL;
}
mutex_unlock(&dev->mode_config.idr_mutex);
+ if (master)
+ drm_master_put(&master);
return obj;
}
diff --git a/include/drm/drm_file.h b/include/drm/drm_file.h
index d12bb2ba7814..e2d49fe3e32d 100644
--- a/include/drm/drm_file.h
+++ b/include/drm/drm_file.h
@@ -227,16 +227,12 @@ struct drm_file {
* @master:
*
* Master this node is currently associated with. Protected by struct
- * &drm_device.master_rwsem, and serialized by @master_lookup_lock.
+ * &drm_device.master_rwsem.
*
* Only relevant if drm_is_primary_client() returns true. Note that
* this only matches &drm_device.master if the master is the currently
* active one.
*
- * To update @master, both &drm_device.master_rwsem and
- * @master_lookup_lock need to be held, therefore holding either of
- * them is safe and enough for the read side.
- *
* When dereferencing this pointer, either hold struct
* &drm_device.master_rwsem for the duration of the pointer's use, or
* use drm_file_get_master() if struct &drm_device.master_rwsem is not
@@ -248,9 +244,6 @@ struct drm_file {
*/
struct drm_master *master;
- /** @master_lock: Serializes @master. */
- spinlock_t master_lookup_lock;
-
/** @pid: Process that opened this file. */
struct pid *pid;
diff --git a/include/drm/drm_lease.h b/include/drm/drm_lease.h
index 5c9ef6a2aeae..a5e47c54bfc3 100644
--- a/include/drm/drm_lease.h
+++ b/include/drm/drm_lease.h
@@ -16,7 +16,7 @@ void drm_lease_destroy(struct drm_master *lessee);
bool drm_lease_held(struct drm_file *file_priv, int id);
-bool _drm_lease_held(struct drm_file *file_priv, int id);
+bool _drm_lease_held_master(struct drm_master *master, int id);
void drm_lease_revoke(struct drm_master *master);
--
2.25.1
^ permalink raw reply [flat|nested] 6+ messages in thread