drm_lease.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * Copyright © 2017 Keith Packard <[email protected]>
  4. */
  5. #include <linux/file.h>
  6. #include <linux/uaccess.h>
  7. #include <drm/drm_auth.h>
  8. #include <drm/drm_crtc_helper.h>
  9. #include <drm/drm_drv.h>
  10. #include <drm/drm_file.h>
  11. #include <drm/drm_lease.h>
  12. #include <drm/drm_print.h>
  13. #include "drm_crtc_internal.h"
  14. #include "drm_internal.h"
  15. /**
  16. * DOC: drm leasing
  17. *
  18. * DRM leases provide information about whether a DRM master may control a DRM
  19. * mode setting object. This enables the creation of multiple DRM masters that
  20. * manage subsets of display resources.
  21. *
  22. * The original DRM master of a device 'owns' the available drm resources. It
  23. * may create additional DRM masters and 'lease' resources which it controls
  24. * to the new DRM master. This gives the new DRM master control over the
  25. * leased resources until the owner revokes the lease, or the new DRM master
  26. * is closed. Some helpful terminology:
  27. *
  28. * - An 'owner' is a &struct drm_master that is not leasing objects from
  29. * another &struct drm_master, and hence 'owns' the objects. The owner can be
  30. * identified as the &struct drm_master for which &drm_master.lessor is NULL.
  31. *
  32. * - A 'lessor' is a &struct drm_master which is leasing objects to one or more
  33. * other &struct drm_master. Currently, lessees are not allowed to
  34. * create sub-leases, hence the lessor is the same as the owner.
  35. *
  36. * - A 'lessee' is a &struct drm_master which is leasing objects from some
  37. * other &struct drm_master. Each lessee only leases resources from a single
  38. * lessor recorded in &drm_master.lessor, and holds the set of objects that
  39. * it is leasing in &drm_master.leases.
  40. *
  41. * - A 'lease' is a contract between the lessor and lessee that identifies
  42. * which resources may be controlled by the lessee. All of the resources
  43. * that are leased must be owned by or leased to the lessor, and lessors are
  44. * not permitted to lease the same object to multiple lessees.
  45. *
  46. * The set of objects any &struct drm_master 'controls' is limited to the set
  47. * of objects it leases (for lessees) or all objects (for owners).
  48. *
  49. * Objects not controlled by a &struct drm_master cannot be modified through
  50. * the various state manipulating ioctls, and any state reported back to user
  51. * space will be edited to make them appear idle and/or unusable. For
  52. * instance, connectors always report 'disconnected', while encoders
  53. * report no possible crtcs or clones.
  54. *
  55. * Since each lessee may lease objects from a single lessor, display resource
  56. * leases form a tree of &struct drm_master. As lessees are currently not
  57. * allowed to create sub-leases, the tree depth is limited to 1. All of
  58. * these get activated simultaneously when the top level device owner changes
  59. * through the SETMASTER or DROPMASTER IOCTL, so &drm_device.master points to
  60. * the owner at the top of the lease tree (i.e. the &struct drm_master for which
  61. * &drm_master.lessor is NULL). The full list of lessees that are leasing
  62. * objects from the owner can be searched via the owner's
  63. * &drm_master.lessee_idr.
  64. */
  65. #define drm_for_each_lessee(lessee, lessor) \
  66. list_for_each_entry((lessee), &(lessor)->lessees, lessee_list)
  67. static uint64_t drm_lease_idr_object;
  68. struct drm_master *drm_lease_owner(struct drm_master *master)
  69. {
  70. while (master->lessor != NULL)
  71. master = master->lessor;
  72. return master;
  73. }
  74. static struct drm_master*
  75. _drm_find_lessee(struct drm_master *master, int lessee_id)
  76. {
  77. lockdep_assert_held(&master->dev->mode_config.idr_mutex);
  78. return idr_find(&drm_lease_owner(master)->lessee_idr, lessee_id);
  79. }
  80. static int _drm_lease_held_master(struct drm_master *master, int id)
  81. {
  82. lockdep_assert_held(&master->dev->mode_config.idr_mutex);
  83. if (master->lessor)
  84. return idr_find(&master->leases, id) != NULL;
  85. return true;
  86. }
  87. /* Checks if the given object has been leased to some lessee of drm_master */
  88. static bool _drm_has_leased(struct drm_master *master, int id)
  89. {
  90. struct drm_master *lessee;
  91. lockdep_assert_held(&master->dev->mode_config.idr_mutex);
  92. drm_for_each_lessee(lessee, master)
  93. if (_drm_lease_held_master(lessee, id))
  94. return true;
  95. return false;
  96. }
  97. /* Called with idr_mutex held */
  98. bool _drm_lease_held(struct drm_file *file_priv, int id)
  99. {
  100. bool ret;
  101. struct drm_master *master;
  102. if (!file_priv)
  103. return true;
  104. master = drm_file_get_master(file_priv);
  105. if (!master)
  106. return true;
  107. ret = _drm_lease_held_master(master, id);
  108. drm_master_put(&master);
  109. return ret;
  110. }
  111. bool drm_lease_held(struct drm_file *file_priv, int id)
  112. {
  113. struct drm_master *master;
  114. bool ret;
  115. if (!file_priv)
  116. return true;
  117. master = drm_file_get_master(file_priv);
  118. if (!master)
  119. return true;
  120. if (!master->lessor) {
  121. ret = true;
  122. goto out;
  123. }
  124. mutex_lock(&master->dev->mode_config.idr_mutex);
  125. ret = _drm_lease_held_master(master, id);
  126. mutex_unlock(&master->dev->mode_config.idr_mutex);
  127. out:
  128. drm_master_put(&master);
  129. return ret;
  130. }
  131. /*
  132. * Given a bitmask of crtcs to check, reconstructs a crtc mask based on the
  133. * crtcs which are visible through the specified file.
  134. */
  135. uint32_t drm_lease_filter_crtcs(struct drm_file *file_priv, uint32_t crtcs_in)
  136. {
  137. struct drm_master *master;
  138. struct drm_device *dev;
  139. struct drm_crtc *crtc;
  140. int count_in, count_out;
  141. uint32_t crtcs_out = 0;
  142. if (!file_priv)
  143. return crtcs_in;
  144. master = drm_file_get_master(file_priv);
  145. if (!master)
  146. return crtcs_in;
  147. if (!master->lessor) {
  148. crtcs_out = crtcs_in;
  149. goto out;
  150. }
  151. dev = master->dev;
  152. count_in = count_out = 0;
  153. mutex_lock(&master->dev->mode_config.idr_mutex);
  154. list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
  155. if (_drm_lease_held_master(master, crtc->base.id)) {
  156. uint32_t mask_in = 1ul << count_in;
  157. if ((crtcs_in & mask_in) != 0) {
  158. uint32_t mask_out = 1ul << count_out;
  159. crtcs_out |= mask_out;
  160. }
  161. count_out++;
  162. }
  163. count_in++;
  164. }
  165. mutex_unlock(&master->dev->mode_config.idr_mutex);
  166. out:
  167. drm_master_put(&master);
  168. return crtcs_out;
  169. }
  170. /*
  171. * Uses drm_master_create to allocate a new drm_master, then checks to
  172. * make sure all of the desired objects can be leased, atomically
  173. * leasing them to the new drmmaster.
  174. *
  175. * ERR_PTR(-EACCES) some other master holds the title to any object
  176. * ERR_PTR(-ENOENT) some object is not a valid DRM object for this device
  177. * ERR_PTR(-EBUSY) some other lessee holds title to this object
  178. * ERR_PTR(-EEXIST) same object specified more than once in the provided list
  179. * ERR_PTR(-ENOMEM) allocation failed
  180. */
  181. static struct drm_master *drm_lease_create(struct drm_master *lessor, struct idr *leases)
  182. {
  183. struct drm_device *dev = lessor->dev;
  184. int error;
  185. struct drm_master *lessee;
  186. int object;
  187. int id;
  188. void *entry;
  189. DRM_DEBUG_LEASE("lessor %d\n", lessor->lessee_id);
  190. lessee = drm_master_create(lessor->dev);
  191. if (!lessee) {
  192. DRM_DEBUG_LEASE("drm_master_create failed\n");
  193. return ERR_PTR(-ENOMEM);
  194. }
  195. mutex_lock(&dev->mode_config.idr_mutex);
  196. idr_for_each_entry(leases, entry, object) {
  197. error = 0;
  198. if (!idr_find(&dev->mode_config.object_idr, object))
  199. error = -ENOENT;
  200. else if (_drm_has_leased(lessor, object))
  201. error = -EBUSY;
  202. if (error != 0) {
  203. DRM_DEBUG_LEASE("object %d failed %d\n", object, error);
  204. goto out_lessee;
  205. }
  206. }
  207. /* Insert the new lessee into the tree */
  208. id = idr_alloc(&(drm_lease_owner(lessor)->lessee_idr), lessee, 1, 0, GFP_KERNEL);
  209. if (id < 0) {
  210. error = id;
  211. goto out_lessee;
  212. }
  213. lessee->lessee_id = id;
  214. lessee->lessor = drm_master_get(lessor);
  215. list_add_tail(&lessee->lessee_list, &lessor->lessees);
  216. /* Move the leases over */
  217. lessee->leases = *leases;
  218. DRM_DEBUG_LEASE("new lessee %d %p, lessor %d %p\n", lessee->lessee_id, lessee, lessor->lessee_id, lessor);
  219. mutex_unlock(&dev->mode_config.idr_mutex);
  220. return lessee;
  221. out_lessee:
  222. mutex_unlock(&dev->mode_config.idr_mutex);
  223. drm_master_put(&lessee);
  224. return ERR_PTR(error);
  225. }
  226. void drm_lease_destroy(struct drm_master *master)
  227. {
  228. struct drm_device *dev = master->dev;
  229. mutex_lock(&dev->mode_config.idr_mutex);
  230. DRM_DEBUG_LEASE("drm_lease_destroy %d\n", master->lessee_id);
  231. /* This master is referenced by all lessees, hence it cannot be destroyed
  232. * until all of them have been
  233. */
  234. WARN_ON(!list_empty(&master->lessees));
  235. /* Remove this master from the lessee idr in the owner */
  236. if (master->lessee_id != 0) {
  237. DRM_DEBUG_LEASE("remove master %d from device list of lessees\n", master->lessee_id);
  238. idr_remove(&(drm_lease_owner(master)->lessee_idr), master->lessee_id);
  239. }
  240. /* Remove this master from any lessee list it may be on */
  241. list_del(&master->lessee_list);
  242. mutex_unlock(&dev->mode_config.idr_mutex);
  243. if (master->lessor) {
  244. /* Tell the master to check the lessee list */
  245. drm_sysfs_lease_event(dev);
  246. drm_master_put(&master->lessor);
  247. }
  248. DRM_DEBUG_LEASE("drm_lease_destroy done %d\n", master->lessee_id);
  249. }
  250. static void _drm_lease_revoke(struct drm_master *top)
  251. {
  252. int object;
  253. void *entry;
  254. struct drm_master *master = top;
  255. lockdep_assert_held(&top->dev->mode_config.idr_mutex);
  256. /*
  257. * Walk the tree starting at 'top' emptying all leases. Because
  258. * the tree is fully connected, we can do this without recursing
  259. */
  260. for (;;) {
  261. DRM_DEBUG_LEASE("revoke leases for %p %d\n", master, master->lessee_id);
  262. /* Evacuate the lease */
  263. idr_for_each_entry(&master->leases, entry, object)
  264. idr_remove(&master->leases, object);
  265. /* Depth-first list walk */
  266. /* Down */
  267. if (!list_empty(&master->lessees)) {
  268. master = list_first_entry(&master->lessees, struct drm_master, lessee_list);
  269. } else {
  270. /* Up */
  271. while (master != top && master == list_last_entry(&master->lessor->lessees, struct drm_master, lessee_list))
  272. master = master->lessor;
  273. if (master == top)
  274. break;
  275. /* Over */
  276. master = list_next_entry(master, lessee_list);
  277. }
  278. }
  279. }
  280. void drm_lease_revoke(struct drm_master *top)
  281. {
  282. mutex_lock(&top->dev->mode_config.idr_mutex);
  283. _drm_lease_revoke(top);
  284. mutex_unlock(&top->dev->mode_config.idr_mutex);
  285. }
  286. static int validate_lease(struct drm_device *dev,
  287. int object_count,
  288. struct drm_mode_object **objects,
  289. bool universal_planes)
  290. {
  291. int o;
  292. int has_crtc = -1;
  293. int has_connector = -1;
  294. int has_plane = -1;
  295. /* we want to confirm that there is at least one crtc, plane
  296. connector object. */
  297. for (o = 0; o < object_count; o++) {
  298. if (objects[o]->type == DRM_MODE_OBJECT_CRTC && has_crtc == -1) {
  299. has_crtc = o;
  300. }
  301. if (objects[o]->type == DRM_MODE_OBJECT_CONNECTOR && has_connector == -1)
  302. has_connector = o;
  303. if (universal_planes) {
  304. if (objects[o]->type == DRM_MODE_OBJECT_PLANE && has_plane == -1)
  305. has_plane = o;
  306. }
  307. }
  308. if (has_crtc == -1 || has_connector == -1)
  309. return -EINVAL;
  310. if (universal_planes && has_plane == -1)
  311. return -EINVAL;
  312. return 0;
  313. }
  314. static int fill_object_idr(struct drm_device *dev,
  315. struct drm_file *lessor_priv,
  316. struct idr *leases,
  317. int object_count,
  318. u32 *object_ids)
  319. {
  320. struct drm_mode_object **objects;
  321. u32 o;
  322. int ret;
  323. bool universal_planes = READ_ONCE(lessor_priv->universal_planes);
  324. objects = kcalloc(object_count, sizeof(struct drm_mode_object *),
  325. GFP_KERNEL);
  326. if (!objects)
  327. return -ENOMEM;
  328. /* step one - get references to all the mode objects
  329. and check for validity. */
  330. for (o = 0; o < object_count; o++) {
  331. objects[o] = drm_mode_object_find(dev, lessor_priv,
  332. object_ids[o],
  333. DRM_MODE_OBJECT_ANY);
  334. if (!objects[o]) {
  335. ret = -ENOENT;
  336. goto out_free_objects;
  337. }
  338. if (!drm_mode_object_lease_required(objects[o]->type)) {
  339. DRM_DEBUG_KMS("invalid object for lease\n");
  340. ret = -EINVAL;
  341. goto out_free_objects;
  342. }
  343. }
  344. ret = validate_lease(dev, object_count, objects, universal_planes);
  345. if (ret) {
  346. DRM_DEBUG_LEASE("lease validation failed\n");
  347. goto out_free_objects;
  348. }
  349. /* add their IDs to the lease request - taking into account
  350. universal planes */
  351. for (o = 0; o < object_count; o++) {
  352. struct drm_mode_object *obj = objects[o];
  353. u32 object_id = objects[o]->id;
  354. DRM_DEBUG_LEASE("Adding object %d to lease\n", object_id);
  355. /*
  356. * We're using an IDR to hold the set of leased
  357. * objects, but we don't need to point at the object's
  358. * data structure from the lease as the main object_idr
  359. * will be used to actually find that. Instead, all we
  360. * really want is a 'leased/not-leased' result, for
  361. * which any non-NULL pointer will work fine.
  362. */
  363. ret = idr_alloc(leases, &drm_lease_idr_object , object_id, object_id + 1, GFP_KERNEL);
  364. if (ret < 0) {
  365. DRM_DEBUG_LEASE("Object %d cannot be inserted into leases (%d)\n",
  366. object_id, ret);
  367. goto out_free_objects;
  368. }
  369. if (obj->type == DRM_MODE_OBJECT_CRTC && !universal_planes) {
  370. struct drm_crtc *crtc = obj_to_crtc(obj);
  371. ret = idr_alloc(leases, &drm_lease_idr_object, crtc->primary->base.id, crtc->primary->base.id + 1, GFP_KERNEL);
  372. if (ret < 0) {
  373. DRM_DEBUG_LEASE("Object primary plane %d cannot be inserted into leases (%d)\n",
  374. object_id, ret);
  375. goto out_free_objects;
  376. }
  377. if (crtc->cursor) {
  378. ret = idr_alloc(leases, &drm_lease_idr_object, crtc->cursor->base.id, crtc->cursor->base.id + 1, GFP_KERNEL);
  379. if (ret < 0) {
  380. DRM_DEBUG_LEASE("Object cursor plane %d cannot be inserted into leases (%d)\n",
  381. object_id, ret);
  382. goto out_free_objects;
  383. }
  384. }
  385. }
  386. }
  387. ret = 0;
  388. out_free_objects:
  389. for (o = 0; o < object_count; o++) {
  390. if (objects[o])
  391. drm_mode_object_put(objects[o]);
  392. }
  393. kfree(objects);
  394. return ret;
  395. }
  396. /*
  397. * The master associated with the specified file will have a lease
  398. * created containing the objects specified in the ioctl structure.
  399. * A file descriptor will be allocated for that and returned to the
  400. * application.
  401. */
  402. int drm_mode_create_lease_ioctl(struct drm_device *dev,
  403. void *data, struct drm_file *lessor_priv)
  404. {
  405. struct drm_mode_create_lease *cl = data;
  406. size_t object_count;
  407. int ret = 0;
  408. struct idr leases;
  409. struct drm_master *lessor;
  410. struct drm_master *lessee = NULL;
  411. struct file *lessee_file = NULL;
  412. struct file *lessor_file = lessor_priv->filp;
  413. struct drm_file *lessee_priv;
  414. int fd = -1;
  415. uint32_t *object_ids;
  416. /* Can't lease without MODESET */
  417. if (!drm_core_check_feature(dev, DRIVER_MODESET))
  418. return -EOPNOTSUPP;
  419. if (cl->flags && (cl->flags & ~(O_CLOEXEC | O_NONBLOCK))) {
  420. DRM_DEBUG_LEASE("invalid flags\n");
  421. return -EINVAL;
  422. }
  423. lessor = drm_file_get_master(lessor_priv);
  424. /* Do not allow sub-leases */
  425. if (lessor->lessor) {
  426. DRM_DEBUG_LEASE("recursive leasing not allowed\n");
  427. ret = -EINVAL;
  428. goto out_lessor;
  429. }
  430. object_count = cl->object_count;
  431. /* Handle leased objects, if any */
  432. idr_init(&leases);
  433. if (object_count != 0) {
  434. object_ids = memdup_array_user(u64_to_user_ptr(cl->object_ids),
  435. object_count, sizeof(__u32));
  436. if (IS_ERR(object_ids)) {
  437. ret = PTR_ERR(object_ids);
  438. idr_destroy(&leases);
  439. goto out_lessor;
  440. }
  441. /* fill and validate the object idr */
  442. ret = fill_object_idr(dev, lessor_priv, &leases,
  443. object_count, object_ids);
  444. kfree(object_ids);
  445. if (ret) {
  446. DRM_DEBUG_LEASE("lease object lookup failed: %i\n", ret);
  447. idr_destroy(&leases);
  448. goto out_lessor;
  449. }
  450. }
  451. /* Allocate a file descriptor for the lease */
  452. fd = get_unused_fd_flags(cl->flags & (O_CLOEXEC | O_NONBLOCK));
  453. if (fd < 0) {
  454. idr_destroy(&leases);
  455. ret = fd;
  456. goto out_lessor;
  457. }
  458. DRM_DEBUG_LEASE("Creating lease\n");
  459. /* lessee will take the ownership of leases */
  460. lessee = drm_lease_create(lessor, &leases);
  461. if (IS_ERR(lessee)) {
  462. ret = PTR_ERR(lessee);
  463. idr_destroy(&leases);
  464. goto out_leases;
  465. }
  466. /* Clone the lessor file to create a new file for us */
  467. DRM_DEBUG_LEASE("Allocating lease file\n");
  468. lessee_file = file_clone_open(lessor_file);
  469. if (IS_ERR(lessee_file)) {
  470. ret = PTR_ERR(lessee_file);
  471. goto out_lessee;
  472. }
  473. lessee_priv = lessee_file->private_data;
  474. /* Change the file to a master one */
  475. drm_master_put(&lessee_priv->master);
  476. lessee_priv->master = lessee;
  477. lessee_priv->is_master = 1;
  478. lessee_priv->authenticated = 1;
  479. /* Pass fd back to userspace */
  480. DRM_DEBUG_LEASE("Returning fd %d id %d\n", fd, lessee->lessee_id);
  481. cl->fd = fd;
  482. cl->lessee_id = lessee->lessee_id;
  483. /* Hook up the fd */
  484. fd_install(fd, lessee_file);
  485. drm_master_put(&lessor);
  486. DRM_DEBUG_LEASE("drm_mode_create_lease_ioctl succeeded\n");
  487. return 0;
  488. out_lessee:
  489. drm_master_put(&lessee);
  490. out_leases:
  491. put_unused_fd(fd);
  492. out_lessor:
  493. drm_master_put(&lessor);
  494. DRM_DEBUG_LEASE("drm_mode_create_lease_ioctl failed: %d\n", ret);
  495. return ret;
  496. }
  497. int drm_mode_list_lessees_ioctl(struct drm_device *dev,
  498. void *data, struct drm_file *lessor_priv)
  499. {
  500. struct drm_mode_list_lessees *arg = data;
  501. __u32 __user *lessee_ids = (__u32 __user *) (uintptr_t) (arg->lessees_ptr);
  502. __u32 count_lessees = arg->count_lessees;
  503. struct drm_master *lessor, *lessee;
  504. int count;
  505. int ret = 0;
  506. if (arg->pad)
  507. return -EINVAL;
  508. /* Can't lease without MODESET */
  509. if (!drm_core_check_feature(dev, DRIVER_MODESET))
  510. return -EOPNOTSUPP;
  511. lessor = drm_file_get_master(lessor_priv);
  512. DRM_DEBUG_LEASE("List lessees for %d\n", lessor->lessee_id);
  513. mutex_lock(&dev->mode_config.idr_mutex);
  514. count = 0;
  515. drm_for_each_lessee(lessee, lessor) {
  516. /* Only list un-revoked leases */
  517. if (!idr_is_empty(&lessee->leases)) {
  518. if (count_lessees > count) {
  519. DRM_DEBUG_LEASE("Add lessee %d\n", lessee->lessee_id);
  520. ret = put_user(lessee->lessee_id, lessee_ids + count);
  521. if (ret)
  522. break;
  523. }
  524. count++;
  525. }
  526. }
  527. DRM_DEBUG_LEASE("Lessor leases to %d\n", count);
  528. if (ret == 0)
  529. arg->count_lessees = count;
  530. mutex_unlock(&dev->mode_config.idr_mutex);
  531. drm_master_put(&lessor);
  532. return ret;
  533. }
  534. /* Return the list of leased objects for the specified lessee */
  535. int drm_mode_get_lease_ioctl(struct drm_device *dev,
  536. void *data, struct drm_file *lessee_priv)
  537. {
  538. struct drm_mode_get_lease *arg = data;
  539. __u32 __user *object_ids = (__u32 __user *) (uintptr_t) (arg->objects_ptr);
  540. __u32 count_objects = arg->count_objects;
  541. struct drm_master *lessee;
  542. struct idr *object_idr;
  543. int count;
  544. void *entry;
  545. int object;
  546. int ret = 0;
  547. if (arg->pad)
  548. return -EINVAL;
  549. /* Can't lease without MODESET */
  550. if (!drm_core_check_feature(dev, DRIVER_MODESET))
  551. return -EOPNOTSUPP;
  552. lessee = drm_file_get_master(lessee_priv);
  553. DRM_DEBUG_LEASE("get lease for %d\n", lessee->lessee_id);
  554. mutex_lock(&dev->mode_config.idr_mutex);
  555. if (lessee->lessor == NULL)
  556. /* owner can use all objects */
  557. object_idr = &lessee->dev->mode_config.object_idr;
  558. else
  559. /* lessee can only use allowed object */
  560. object_idr = &lessee->leases;
  561. count = 0;
  562. idr_for_each_entry(object_idr, entry, object) {
  563. if (count_objects > count) {
  564. DRM_DEBUG_LEASE("adding object %d\n", object);
  565. ret = put_user(object, object_ids + count);
  566. if (ret)
  567. break;
  568. }
  569. count++;
  570. }
  571. DRM_DEBUG("lease holds %d objects\n", count);
  572. if (ret == 0)
  573. arg->count_objects = count;
  574. mutex_unlock(&dev->mode_config.idr_mutex);
  575. drm_master_put(&lessee);
  576. return ret;
  577. }
  578. /*
  579. * This removes all of the objects from the lease without
  580. * actually getting rid of the lease itself; that way all
  581. * references to it still work correctly
  582. */
  583. int drm_mode_revoke_lease_ioctl(struct drm_device *dev,
  584. void *data, struct drm_file *lessor_priv)
  585. {
  586. struct drm_mode_revoke_lease *arg = data;
  587. struct drm_master *lessor;
  588. struct drm_master *lessee;
  589. int ret = 0;
  590. DRM_DEBUG_LEASE("revoke lease for %d\n", arg->lessee_id);
  591. /* Can't lease without MODESET */
  592. if (!drm_core_check_feature(dev, DRIVER_MODESET))
  593. return -EOPNOTSUPP;
  594. lessor = drm_file_get_master(lessor_priv);
  595. mutex_lock(&dev->mode_config.idr_mutex);
  596. lessee = _drm_find_lessee(lessor, arg->lessee_id);
  597. /* No such lessee */
  598. if (!lessee) {
  599. ret = -ENOENT;
  600. goto fail;
  601. }
  602. /* Lease is not held by lessor */
  603. if (lessee->lessor != lessor) {
  604. ret = -EACCES;
  605. goto fail;
  606. }
  607. _drm_lease_revoke(lessee);
  608. fail:
  609. mutex_unlock(&dev->mode_config.idr_mutex);
  610. drm_master_put(&lessor);
  611. return ret;
  612. }