hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/drivers/gpu/drm/drm_mode_object.c
....@@ -21,9 +21,14 @@
2121 */
2222
2323 #include <linux/export.h>
24
-#include <drm/drmP.h>
25
-#include <drm/drm_mode_object.h>
24
+#include <linux/uaccess.h>
25
+
2626 #include <drm/drm_atomic.h>
27
+#include <drm/drm_drv.h>
28
+#include <drm/drm_device.h>
29
+#include <drm/drm_file.h>
30
+#include <drm/drm_mode_object.h>
31
+#include <drm/drm_print.h>
2732
2833 #include "drm_crtc_internal.h"
2934
....@@ -37,8 +42,11 @@
3742 {
3843 int ret;
3944
45
+ WARN_ON(!dev->driver->load && dev->registered && !obj_free_cb);
46
+
4047 mutex_lock(&dev->mode_config.idr_mutex);
41
- ret = idr_alloc(&dev->mode_config.crtc_idr, register_obj ? obj : NULL, 1, 0, GFP_KERNEL);
48
+ ret = idr_alloc(&dev->mode_config.object_idr, register_obj ? obj : NULL,
49
+ 1, 0, GFP_KERNEL);
4250 if (ret >= 0) {
4351 /*
4452 * Set up the object linking under the protection of the idr
....@@ -78,7 +86,7 @@
7886 struct drm_mode_object *obj)
7987 {
8088 mutex_lock(&dev->mode_config.idr_mutex);
81
- idr_replace(&dev->mode_config.crtc_idr, obj, obj->id);
89
+ idr_replace(&dev->mode_config.object_idr, obj, obj->id);
8290 mutex_unlock(&dev->mode_config.idr_mutex);
8391 }
8492
....@@ -96,9 +104,11 @@
96104 void drm_mode_object_unregister(struct drm_device *dev,
97105 struct drm_mode_object *object)
98106 {
107
+ WARN_ON(!dev->driver->load && dev->registered && !object->free_cb);
108
+
99109 mutex_lock(&dev->mode_config.idr_mutex);
100110 if (object->id) {
101
- idr_remove(&dev->mode_config.crtc_idr, object->id);
111
+ idr_remove(&dev->mode_config.object_idr, object->id);
102112 object->id = 0;
103113 }
104114 mutex_unlock(&dev->mode_config.idr_mutex);
....@@ -130,7 +140,7 @@
130140 struct drm_mode_object *obj = NULL;
131141
132142 mutex_lock(&dev->mode_config.idr_mutex);
133
- obj = idr_find(&dev->mode_config.crtc_idr, id);
143
+ obj = idr_find(&dev->mode_config.object_idr, id);
134144 if (obj && type != DRM_MODE_OBJECT_ANY && obj->type != type)
135145 obj = NULL;
136146 if (obj && obj->id != id)
....@@ -214,12 +224,26 @@
214224 * This attaches the given property to the modeset object with the given initial
215225 * value. Currently this function cannot fail since the properties are stored in
216226 * a statically sized array.
227
+ *
228
+ * Note that all properties must be attached before the object itself is
229
+ * registered and accessible from userspace.
217230 */
218231 void drm_object_attach_property(struct drm_mode_object *obj,
219232 struct drm_property *property,
220233 uint64_t init_val)
221234 {
222235 int count = obj->properties->count;
236
+ struct drm_device *dev = property->dev;
237
+
238
+
239
+ if (obj->type == DRM_MODE_OBJECT_CONNECTOR) {
240
+ struct drm_connector *connector = obj_to_connector(obj);
241
+
242
+ WARN_ON(!dev->driver->load &&
243
+ connector->registration_state == DRM_CONNECTOR_REGISTERED);
244
+ } else {
245
+ WARN_ON(!dev->driver->load && dev->registered);
246
+ }
223247
224248 if (count == DRM_OBJECT_MAX_PROPERTY) {
225249 WARN(1, "Failed to attach object property (type: 0x%x). Please "
....@@ -378,12 +402,13 @@
378402 {
379403 struct drm_mode_obj_get_properties *arg = data;
380404 struct drm_mode_object *obj;
405
+ struct drm_modeset_acquire_ctx ctx;
381406 int ret = 0;
382407
383408 if (!drm_core_check_feature(dev, DRIVER_MODESET))
384
- return -EINVAL;
409
+ return -EOPNOTSUPP;
385410
386
- drm_modeset_lock_all(dev);
411
+ DRM_MODESET_LOCK_ALL_BEGIN(dev, ctx, 0, ret);
387412
388413 obj = drm_mode_object_find(dev, file_priv, arg->obj_id, arg->obj_type);
389414 if (!obj) {
....@@ -403,7 +428,7 @@
403428 out_unref:
404429 drm_mode_object_put(obj);
405430 out:
406
- drm_modeset_unlock_all(dev);
431
+ DRM_MODESET_LOCK_ALL_END(dev, ctx, ret);
407432 return ret;
408433 }
409434
....@@ -425,12 +450,13 @@
425450 {
426451 struct drm_device *dev = prop->dev;
427452 struct drm_mode_object *ref;
453
+ struct drm_modeset_acquire_ctx ctx;
428454 int ret = -EINVAL;
429455
430456 if (!drm_property_change_valid_get(prop, prop_value, &ref))
431457 return -EINVAL;
432458
433
- drm_modeset_lock_all(dev);
459
+ DRM_MODESET_LOCK_ALL_BEGIN(dev, ctx, 0, ret);
434460 switch (obj->type) {
435461 case DRM_MODE_OBJECT_CONNECTOR:
436462 ret = drm_connector_set_obj_prop(obj, prop, prop_value);
....@@ -444,12 +470,13 @@
444470 break;
445471 }
446472 drm_property_change_valid_put(prop, ref);
447
- drm_modeset_unlock_all(dev);
473
+ DRM_MODESET_LOCK_ALL_END(dev, ctx, ret);
448474
449475 return ret;
450476 }
451477
452478 static int set_property_atomic(struct drm_mode_object *obj,
479
+ struct drm_file *file_priv,
453480 struct drm_property *prop,
454481 uint64_t prop_value)
455482 {
....@@ -476,7 +503,7 @@
476503 obj_to_connector(obj),
477504 prop_value);
478505 } else {
479
- ret = drm_atomic_set_property(state, obj, prop, prop_value);
506
+ ret = drm_atomic_set_property(state, file_priv, obj, prop, prop_value);
480507 if (ret)
481508 goto out;
482509 ret = drm_atomic_commit(state);
....@@ -505,7 +532,7 @@
505532 int ret = -EINVAL;
506533
507534 if (!drm_core_check_feature(dev, DRIVER_MODESET))
508
- return -EINVAL;
535
+ return -EOPNOTSUPP;
509536
510537 arg_obj = drm_mode_object_find(dev, file_priv, arg->obj_id, arg->obj_type);
511538 if (!arg_obj)
....@@ -519,7 +546,7 @@
519546 goto out_unref;
520547
521548 if (drm_drv_uses_atomic_modeset(property->dev))
522
- ret = set_property_atomic(arg_obj, property, arg->value);
549
+ ret = set_property_atomic(arg_obj, file_priv, property, arg->value);
523550 else
524551 ret = set_property_legacy(arg_obj, property, arg->value);
525552