hc
2023-12-11 6778948f9de86c3cfaf36725a7c87dcff9ba247f
kernel/drivers/gpu/drm/drm_lease.c
....@@ -1,24 +1,20 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * Copyright © 2017 Keith Packard <keithp@keithp.com>
3
- *
4
- * This program is free software; you can redistribute it and/or modify
5
- * it under the terms of the GNU General Public License as published by
6
- * the Free Software Foundation, either version 2 of the License, or
7
- * (at your option) any later version.
8
- *
9
- * This program is distributed in the hope that it will be useful, but
10
- * WITHOUT ANY WARRANTY; without even the implied warranty of
11
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
- * General Public License for more details.
134 */
5
+#include <linux/file.h>
6
+#include <linux/uaccess.h>
147
15
-#include <drm/drmP.h>
16
-#include "drm_internal.h"
17
-#include "drm_legacy.h"
18
-#include "drm_crtc_internal.h"
19
-#include <drm/drm_lease.h>
208 #include <drm/drm_auth.h>
219 #include <drm/drm_crtc_helper.h>
10
+#include <drm/drm_drv.h>
11
+#include <drm/drm_file.h>
12
+#include <drm/drm_lease.h>
13
+#include <drm/drm_print.h>
14
+
15
+#include "drm_crtc_internal.h"
16
+#include "drm_internal.h"
17
+#include "drm_legacy.h"
2218
2319 #define drm_for_each_lessee(lessee, lessor) \
2420 list_for_each_entry((lessee), &(lessor)->lessees, lessee_list)
....@@ -39,7 +35,6 @@
3935 master = master->lessor;
4036 return master;
4137 }
42
-EXPORT_SYMBOL(drm_lease_owner);
4338
4439 /**
4540 * _drm_find_lessee - find lessee by id (idr_mutex held)
....@@ -112,12 +107,11 @@
112107 */
113108 bool _drm_lease_held(struct drm_file *file_priv, int id)
114109 {
115
- if (file_priv == NULL || file_priv->master == NULL)
110
+ if (!file_priv || !file_priv->master)
116111 return true;
117112
118113 return _drm_lease_held_master(file_priv->master, id);
119114 }
120
-EXPORT_SYMBOL(_drm_lease_held);
121115
122116 /**
123117 * drm_lease_held - check drm_mode_object lease status (idr_mutex not held)
....@@ -135,7 +129,7 @@
135129 struct drm_master *master;
136130 bool ret;
137131
138
- if (file_priv == NULL || file_priv->master == NULL)
132
+ if (!file_priv || !file_priv->master || !file_priv->master->lessor)
139133 return true;
140134
141135 master = file_priv->master;
....@@ -144,7 +138,6 @@
144138 mutex_unlock(&master->dev->mode_config.idr_mutex);
145139 return ret;
146140 }
147
-EXPORT_SYMBOL(drm_lease_held);
148141
149142 /**
150143 * drm_lease_filter_crtcs - restricted crtc set to leased values (idr_mutex not held)
....@@ -162,7 +155,7 @@
162155 int count_in, count_out;
163156 uint32_t crtcs_out = 0;
164157
165
- if (file_priv == NULL || file_priv->master == NULL)
158
+ if (!file_priv || !file_priv->master || !file_priv->master->lessor)
166159 return crtcs_in;
167160
168161 master = file_priv->master;
....@@ -173,8 +166,10 @@
173166 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
174167 if (_drm_lease_held_master(master, crtc->base.id)) {
175168 uint32_t mask_in = 1ul << count_in;
169
+
176170 if ((crtcs_in & mask_in) != 0) {
177171 uint32_t mask_out = 1ul << count_out;
172
+
178173 crtcs_out |= mask_out;
179174 }
180175 count_out++;
....@@ -184,7 +179,6 @@
184179 mutex_unlock(&master->dev->mode_config.idr_mutex);
185180 return crtcs_out;
186181 }
187
-EXPORT_SYMBOL(drm_lease_filter_crtcs);
188182
189183 /*
190184 * drm_lease_create - create a new drm_master with leased objects (idr_mutex not held)
....@@ -195,7 +189,7 @@
195189 * make sure all of the desired objects can be leased, atomically
196190 * leasing them to the new drmmaster.
197191 *
198
- * ERR_PTR(-EACCESS) some other master holds the title to any object
192
+ * ERR_PTR(-EACCES) some other master holds the title to any object
199193 * ERR_PTR(-ENOENT) some object is not a valid DRM object for this device
200194 * ERR_PTR(-EBUSY) some other lessee holds title to this object
201195 * ERR_PTR(-EEXIST) same object specified more than once in the provided list
....@@ -222,10 +216,8 @@
222216
223217 idr_for_each_entry(leases, entry, object) {
224218 error = 0;
225
- if (!idr_find(&dev->mode_config.crtc_idr, object))
219
+ if (!idr_find(&dev->mode_config.object_idr, object))
226220 error = -ENOENT;
227
- else if (!_drm_lease_held_master(lessor, object))
228
- error = -EACCES;
229221 else if (_drm_has_leased(lessor, object))
230222 error = -EBUSY;
231223
....@@ -357,9 +349,9 @@
357349 }
358350
359351 static int validate_lease(struct drm_device *dev,
360
- struct drm_file *lessor_priv,
361352 int object_count,
362
- struct drm_mode_object **objects)
353
+ struct drm_mode_object **objects,
354
+ bool universal_planes)
363355 {
364356 int o;
365357 int has_crtc = -1;
....@@ -376,14 +368,14 @@
376368 if (objects[o]->type == DRM_MODE_OBJECT_CONNECTOR && has_connector == -1)
377369 has_connector = o;
378370
379
- if (lessor_priv->universal_planes) {
371
+ if (universal_planes) {
380372 if (objects[o]->type == DRM_MODE_OBJECT_PLANE && has_plane == -1)
381373 has_plane = o;
382374 }
383375 }
384376 if (has_crtc == -1 || has_connector == -1)
385377 return -EINVAL;
386
- if (lessor_priv->universal_planes && has_plane == -1)
378
+ if (universal_planes && has_plane == -1)
387379 return -EINVAL;
388380 return 0;
389381 }
....@@ -397,6 +389,8 @@
397389 struct drm_mode_object **objects;
398390 u32 o;
399391 int ret;
392
+ bool universal_planes = READ_ONCE(lessor_priv->universal_planes);
393
+
400394 objects = kcalloc(object_count, sizeof(struct drm_mode_object *),
401395 GFP_KERNEL);
402396 if (!objects)
....@@ -405,11 +399,6 @@
405399 /* step one - get references to all the mode objects
406400 and check for validity. */
407401 for (o = 0; o < object_count; o++) {
408
- if ((int) object_ids[o] < 0) {
409
- ret = -EINVAL;
410
- goto out_free_objects;
411
- }
412
-
413402 objects[o] = drm_mode_object_find(dev, lessor_priv,
414403 object_ids[o],
415404 DRM_MODE_OBJECT_ANY);
....@@ -419,26 +408,30 @@
419408 }
420409
421410 if (!drm_mode_object_lease_required(objects[o]->type)) {
411
+ DRM_DEBUG_KMS("invalid object for lease\n");
422412 ret = -EINVAL;
423413 goto out_free_objects;
424414 }
425415 }
426416
427
- ret = validate_lease(dev, lessor_priv, object_count, objects);
428
- if (ret)
417
+ ret = validate_lease(dev, object_count, objects, universal_planes);
418
+ if (ret) {
419
+ DRM_DEBUG_LEASE("lease validation failed\n");
429420 goto out_free_objects;
421
+ }
430422
431423 /* add their IDs to the lease request - taking into account
432424 universal planes */
433425 for (o = 0; o < object_count; o++) {
434426 struct drm_mode_object *obj = objects[o];
435427 u32 object_id = objects[o]->id;
428
+
436429 DRM_DEBUG_LEASE("Adding object %d to lease\n", object_id);
437430
438431 /*
439432 * We're using an IDR to hold the set of leased
440433 * objects, but we don't need to point at the object's
441
- * data structure from the lease as the main crtc_idr
434
+ * data structure from the lease as the main object_idr
442435 * will be used to actually find that. Instead, all we
443436 * really want is a 'leased/not-leased' result, for
444437 * which any non-NULL pointer will work fine.
....@@ -449,8 +442,9 @@
449442 object_id, ret);
450443 goto out_free_objects;
451444 }
452
- if (obj->type == DRM_MODE_OBJECT_CRTC && !lessor_priv->universal_planes) {
445
+ if (obj->type == DRM_MODE_OBJECT_CRTC && !universal_planes) {
453446 struct drm_crtc *crtc = obj_to_crtc(obj);
447
+
454448 ret = idr_alloc(leases, &drm_lease_idr_object, crtc->primary->base.id, crtc->primary->base.id + 1, GFP_KERNEL);
455449 if (ret < 0) {
456450 DRM_DEBUG_LEASE("Object primary plane %d cannot be inserted into leases (%d)\n",
....@@ -506,18 +500,24 @@
506500
507501 /* Can't lease without MODESET */
508502 if (!drm_core_check_feature(dev, DRIVER_MODESET))
509
- return -EINVAL;
503
+ return -EOPNOTSUPP;
510504
511505 /* Do not allow sub-leases */
512
- if (lessor->lessor)
506
+ if (lessor->lessor) {
507
+ DRM_DEBUG_LEASE("recursive leasing not allowed\n");
513508 return -EINVAL;
509
+ }
514510
515511 /* need some objects */
516
- if (cl->object_count == 0)
512
+ if (cl->object_count == 0) {
513
+ DRM_DEBUG_LEASE("no objects in lease\n");
517514 return -EINVAL;
515
+ }
518516
519
- if (cl->flags && (cl->flags & ~(O_CLOEXEC | O_NONBLOCK)))
517
+ if (cl->flags && (cl->flags & ~(O_CLOEXEC | O_NONBLOCK))) {
518
+ DRM_DEBUG_LEASE("invalid flags\n");
520519 return -EINVAL;
520
+ }
521521
522522 object_count = cl->object_count;
523523
....@@ -533,6 +533,7 @@
533533 object_count, object_ids);
534534 kfree(object_ids);
535535 if (ret) {
536
+ DRM_DEBUG_LEASE("lease object lookup failed: %i\n", ret);
536537 idr_destroy(&leases);
537538 return ret;
538539 }
....@@ -617,7 +618,7 @@
617618
618619 /* Can't lease without MODESET */
619620 if (!drm_core_check_feature(dev, DRIVER_MODESET))
620
- return -EINVAL;
621
+ return -EOPNOTSUPP;
621622
622623 DRM_DEBUG_LEASE("List lessees for %d\n", lessor->lessee_id);
623624
....@@ -673,7 +674,7 @@
673674
674675 /* Can't lease without MODESET */
675676 if (!drm_core_check_feature(dev, DRIVER_MODESET))
676
- return -EINVAL;
677
+ return -EOPNOTSUPP;
677678
678679 DRM_DEBUG_LEASE("get lease for %d\n", lessee->lessee_id);
679680
....@@ -681,7 +682,7 @@
681682
682683 if (lessee->lessor == NULL)
683684 /* owner can use all objects */
684
- object_idr = &lessee->dev->mode_config.crtc_idr;
685
+ object_idr = &lessee->dev->mode_config.object_idr;
685686 else
686687 /* lessee can only use allowed object */
687688 object_idr = &lessee->leases;
....@@ -728,7 +729,7 @@
728729
729730 /* Can't lease without MODESET */
730731 if (!drm_core_check_feature(dev, DRIVER_MODESET))
731
- return -EINVAL;
732
+ return -EOPNOTSUPP;
732733
733734 mutex_lock(&dev->mode_config.idr_mutex);
734735