Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * Copyright © 2017 Keith Packard <keithp@keithp.com>
0004  */
0005 #include <linux/file.h>
0006 #include <linux/uaccess.h>
0007 
0008 #include <drm/drm_auth.h>
0009 #include <drm/drm_crtc_helper.h>
0010 #include <drm/drm_drv.h>
0011 #include <drm/drm_file.h>
0012 #include <drm/drm_lease.h>
0013 #include <drm/drm_print.h>
0014 
0015 #include "drm_crtc_internal.h"
0016 #include "drm_internal.h"
0017 
0018 /**
0019  * DOC: drm leasing
0020  *
0021  * DRM leases provide information about whether a DRM master may control a DRM
0022  * mode setting object. This enables the creation of multiple DRM masters that
0023  * manage subsets of display resources.
0024  *
0025  * The original DRM master of a device 'owns' the available drm resources. It
0026  * may create additional DRM masters and 'lease' resources which it controls
0027  * to the new DRM master. This gives the new DRM master control over the
0028  * leased resources until the owner revokes the lease, or the new DRM master
0029  * is closed. Some helpful terminology:
0030  *
0031  * - An 'owner' is a &struct drm_master that is not leasing objects from
0032  *   another &struct drm_master, and hence 'owns' the objects. The owner can be
0033  *   identified as the &struct drm_master for which &drm_master.lessor is NULL.
0034  *
0035  * - A 'lessor' is a &struct drm_master which is leasing objects to one or more
0036  *   other &struct drm_master. Currently, lessees are not allowed to
0037  *   create sub-leases, hence the lessor is the same as the owner.
0038  *
0039  * - A 'lessee' is a &struct drm_master which is leasing objects from some
0040  *   other &struct drm_master. Each lessee only leases resources from a single
0041  *   lessor recorded in &drm_master.lessor, and holds the set of objects that
0042  *   it is leasing in &drm_master.leases.
0043  *
0044  * - A 'lease' is a contract between the lessor and lessee that identifies
0045  *   which resources may be controlled by the lessee. All of the resources
0046  *   that are leased must be owned by or leased to the lessor, and lessors are
0047  *   not permitted to lease the same object to multiple lessees.
0048  *
0049  * The set of objects any &struct drm_master 'controls' is limited to the set
0050  * of objects it leases (for lessees) or all objects (for owners).
0051  *
0052  * Objects not controlled by a &struct drm_master cannot be modified through
0053  * the various state manipulating ioctls, and any state reported back to user
0054  * space will be edited to make them appear idle and/or unusable. For
0055  * instance, connectors always report 'disconnected', while encoders
0056  * report no possible crtcs or clones.
0057  *
0058  * Since each lessee may lease objects from a single lessor, display resource
0059  * leases form a tree of &struct drm_master. As lessees are currently not
0060  * allowed to create sub-leases, the tree depth is limited to 1. All of
0061  * these get activated simultaneously when the top level device owner changes
0062  * through the SETMASTER or DROPMASTER IOCTL, so &drm_device.master points to
0063  * the owner at the top of the lease tree (i.e. the &struct drm_master for which
0064  * &drm_master.lessor is NULL). The full list of lessees that are leasing
0065  * objects from the owner can be searched via the owner's
0066  * &drm_master.lessee_idr.
0067  */
0068 
0069 #define drm_for_each_lessee(lessee, lessor) \
0070     list_for_each_entry((lessee), &(lessor)->lessees, lessee_list)
0071 
0072 static uint64_t drm_lease_idr_object;
0073 
0074 struct drm_master *drm_lease_owner(struct drm_master *master)
0075 {
0076     while (master->lessor != NULL)
0077         master = master->lessor;
0078     return master;
0079 }
0080 
0081 static struct drm_master*
0082 _drm_find_lessee(struct drm_master *master, int lessee_id)
0083 {
0084     lockdep_assert_held(&master->dev->mode_config.idr_mutex);
0085     return idr_find(&drm_lease_owner(master)->lessee_idr, lessee_id);
0086 }
0087 
0088 static int _drm_lease_held_master(struct drm_master *master, int id)
0089 {
0090     lockdep_assert_held(&master->dev->mode_config.idr_mutex);
0091     if (master->lessor)
0092         return idr_find(&master->leases, id) != NULL;
0093     return true;
0094 }
0095 
0096 /* Checks if the given object has been leased to some lessee of drm_master */
0097 static bool _drm_has_leased(struct drm_master *master, int id)
0098 {
0099     struct drm_master *lessee;
0100 
0101     lockdep_assert_held(&master->dev->mode_config.idr_mutex);
0102     drm_for_each_lessee(lessee, master)
0103         if (_drm_lease_held_master(lessee, id))
0104             return true;
0105     return false;
0106 }
0107 
0108 /* Called with idr_mutex held */
0109 bool _drm_lease_held(struct drm_file *file_priv, int id)
0110 {
0111     bool ret;
0112     struct drm_master *master;
0113 
0114     if (!file_priv)
0115         return true;
0116 
0117     master = drm_file_get_master(file_priv);
0118     if (!master)
0119         return true;
0120     ret = _drm_lease_held_master(master, id);
0121     drm_master_put(&master);
0122 
0123     return ret;
0124 }
0125 
0126 bool drm_lease_held(struct drm_file *file_priv, int id)
0127 {
0128     struct drm_master *master;
0129     bool ret;
0130 
0131     if (!file_priv)
0132         return true;
0133 
0134     master = drm_file_get_master(file_priv);
0135     if (!master)
0136         return true;
0137     if (!master->lessor) {
0138         ret = true;
0139         goto out;
0140     }
0141     mutex_lock(&master->dev->mode_config.idr_mutex);
0142     ret = _drm_lease_held_master(master, id);
0143     mutex_unlock(&master->dev->mode_config.idr_mutex);
0144 
0145 out:
0146     drm_master_put(&master);
0147     return ret;
0148 }
0149 
0150 /*
0151  * Given a bitmask of crtcs to check, reconstructs a crtc mask based on the
0152  * crtcs which are visible through the specified file.
0153  */
0154 uint32_t drm_lease_filter_crtcs(struct drm_file *file_priv, uint32_t crtcs_in)
0155 {
0156     struct drm_master *master;
0157     struct drm_device *dev;
0158     struct drm_crtc *crtc;
0159     int count_in, count_out;
0160     uint32_t crtcs_out = 0;
0161 
0162     if (!file_priv)
0163         return crtcs_in;
0164 
0165     master = drm_file_get_master(file_priv);
0166     if (!master)
0167         return crtcs_in;
0168     if (!master->lessor) {
0169         crtcs_out = crtcs_in;
0170         goto out;
0171     }
0172     dev = master->dev;
0173 
0174     count_in = count_out = 0;
0175     mutex_lock(&master->dev->mode_config.idr_mutex);
0176     list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
0177         if (_drm_lease_held_master(master, crtc->base.id)) {
0178             uint32_t mask_in = 1ul << count_in;
0179 
0180             if ((crtcs_in & mask_in) != 0) {
0181                 uint32_t mask_out = 1ul << count_out;
0182 
0183                 crtcs_out |= mask_out;
0184             }
0185             count_out++;
0186         }
0187         count_in++;
0188     }
0189     mutex_unlock(&master->dev->mode_config.idr_mutex);
0190 
0191 out:
0192     drm_master_put(&master);
0193     return crtcs_out;
0194 }
0195 
0196 /*
0197  * Uses drm_master_create to allocate a new drm_master, then checks to
0198  * make sure all of the desired objects can be leased, atomically
0199  * leasing them to the new drmmaster.
0200  *
0201  *  ERR_PTR(-EACCES)    some other master holds the title to any object
0202  *  ERR_PTR(-ENOENT)    some object is not a valid DRM object for this device
0203  *  ERR_PTR(-EBUSY)     some other lessee holds title to this object
0204  *  ERR_PTR(-EEXIST)    same object specified more than once in the provided list
0205  *  ERR_PTR(-ENOMEM)    allocation failed
0206  */
0207 static struct drm_master *drm_lease_create(struct drm_master *lessor, struct idr *leases)
0208 {
0209     struct drm_device *dev = lessor->dev;
0210     int error;
0211     struct drm_master *lessee;
0212     int object;
0213     int id;
0214     void *entry;
0215 
0216     DRM_DEBUG_LEASE("lessor %d\n", lessor->lessee_id);
0217 
0218     lessee = drm_master_create(lessor->dev);
0219     if (!lessee) {
0220         DRM_DEBUG_LEASE("drm_master_create failed\n");
0221         return ERR_PTR(-ENOMEM);
0222     }
0223 
0224     mutex_lock(&dev->mode_config.idr_mutex);
0225 
0226     idr_for_each_entry(leases, entry, object) {
0227         error = 0;
0228         if (!idr_find(&dev->mode_config.object_idr, object))
0229             error = -ENOENT;
0230         else if (_drm_has_leased(lessor, object))
0231             error = -EBUSY;
0232 
0233         if (error != 0) {
0234             DRM_DEBUG_LEASE("object %d failed %d\n", object, error);
0235             goto out_lessee;
0236         }
0237     }
0238 
0239     /* Insert the new lessee into the tree */
0240     id = idr_alloc(&(drm_lease_owner(lessor)->lessee_idr), lessee, 1, 0, GFP_KERNEL);
0241     if (id < 0) {
0242         error = id;
0243         goto out_lessee;
0244     }
0245 
0246     lessee->lessee_id = id;
0247     lessee->lessor = drm_master_get(lessor);
0248     list_add_tail(&lessee->lessee_list, &lessor->lessees);
0249 
0250     /* Move the leases over */
0251     lessee->leases = *leases;
0252     DRM_DEBUG_LEASE("new lessee %d %p, lessor %d %p\n", lessee->lessee_id, lessee, lessor->lessee_id, lessor);
0253 
0254     mutex_unlock(&dev->mode_config.idr_mutex);
0255     return lessee;
0256 
0257 out_lessee:
0258     mutex_unlock(&dev->mode_config.idr_mutex);
0259 
0260     drm_master_put(&lessee);
0261 
0262     return ERR_PTR(error);
0263 }
0264 
0265 void drm_lease_destroy(struct drm_master *master)
0266 {
0267     struct drm_device *dev = master->dev;
0268 
0269     mutex_lock(&dev->mode_config.idr_mutex);
0270 
0271     DRM_DEBUG_LEASE("drm_lease_destroy %d\n", master->lessee_id);
0272 
0273     /* This master is referenced by all lessees, hence it cannot be destroyed
0274      * until all of them have been
0275      */
0276     WARN_ON(!list_empty(&master->lessees));
0277 
0278     /* Remove this master from the lessee idr in the owner */
0279     if (master->lessee_id != 0) {
0280         DRM_DEBUG_LEASE("remove master %d from device list of lessees\n", master->lessee_id);
0281         idr_remove(&(drm_lease_owner(master)->lessee_idr), master->lessee_id);
0282     }
0283 
0284     /* Remove this master from any lessee list it may be on */
0285     list_del(&master->lessee_list);
0286 
0287     mutex_unlock(&dev->mode_config.idr_mutex);
0288 
0289     if (master->lessor) {
0290         /* Tell the master to check the lessee list */
0291         drm_sysfs_lease_event(dev);
0292         drm_master_put(&master->lessor);
0293     }
0294 
0295     DRM_DEBUG_LEASE("drm_lease_destroy done %d\n", master->lessee_id);
0296 }
0297 
0298 static void _drm_lease_revoke(struct drm_master *top)
0299 {
0300     int object;
0301     void *entry;
0302     struct drm_master *master = top;
0303 
0304     lockdep_assert_held(&top->dev->mode_config.idr_mutex);
0305 
0306     /*
0307      * Walk the tree starting at 'top' emptying all leases. Because
0308      * the tree is fully connected, we can do this without recursing
0309      */
0310     for (;;) {
0311         DRM_DEBUG_LEASE("revoke leases for %p %d\n", master, master->lessee_id);
0312 
0313         /* Evacuate the lease */
0314         idr_for_each_entry(&master->leases, entry, object)
0315             idr_remove(&master->leases, object);
0316 
0317         /* Depth-first list walk */
0318 
0319         /* Down */
0320         if (!list_empty(&master->lessees)) {
0321             master = list_first_entry(&master->lessees, struct drm_master, lessee_list);
0322         } else {
0323             /* Up */
0324             while (master != top && master == list_last_entry(&master->lessor->lessees, struct drm_master, lessee_list))
0325                 master = master->lessor;
0326 
0327             if (master == top)
0328                 break;
0329 
0330             /* Over */
0331             master = list_next_entry(master, lessee_list);
0332         }
0333     }
0334 }
0335 
0336 void drm_lease_revoke(struct drm_master *top)
0337 {
0338     mutex_lock(&top->dev->mode_config.idr_mutex);
0339     _drm_lease_revoke(top);
0340     mutex_unlock(&top->dev->mode_config.idr_mutex);
0341 }
0342 
0343 static int validate_lease(struct drm_device *dev,
0344               int object_count,
0345               struct drm_mode_object **objects,
0346               bool universal_planes)
0347 {
0348     int o;
0349     int has_crtc = -1;
0350     int has_connector = -1;
0351     int has_plane = -1;
0352 
0353     /* we want to confirm that there is at least one crtc, plane
0354        connector object. */
0355 
0356     for (o = 0; o < object_count; o++) {
0357         if (objects[o]->type == DRM_MODE_OBJECT_CRTC && has_crtc == -1) {
0358             has_crtc = o;
0359         }
0360         if (objects[o]->type == DRM_MODE_OBJECT_CONNECTOR && has_connector == -1)
0361             has_connector = o;
0362 
0363         if (universal_planes) {
0364             if (objects[o]->type == DRM_MODE_OBJECT_PLANE && has_plane == -1)
0365                 has_plane = o;
0366         }
0367     }
0368     if (has_crtc == -1 || has_connector == -1)
0369         return -EINVAL;
0370     if (universal_planes && has_plane == -1)
0371         return -EINVAL;
0372     return 0;
0373 }
0374 
0375 static int fill_object_idr(struct drm_device *dev,
0376                struct drm_file *lessor_priv,
0377                struct idr *leases,
0378                int object_count,
0379                u32 *object_ids)
0380 {
0381     struct drm_mode_object **objects;
0382     u32 o;
0383     int ret;
0384     bool universal_planes = READ_ONCE(lessor_priv->universal_planes);
0385 
0386     objects = kcalloc(object_count, sizeof(struct drm_mode_object *),
0387               GFP_KERNEL);
0388     if (!objects)
0389         return -ENOMEM;
0390 
0391     /* step one - get references to all the mode objects
0392        and check for validity. */
0393     for (o = 0; o < object_count; o++) {
0394         objects[o] = drm_mode_object_find(dev, lessor_priv,
0395                           object_ids[o],
0396                           DRM_MODE_OBJECT_ANY);
0397         if (!objects[o]) {
0398             ret = -ENOENT;
0399             goto out_free_objects;
0400         }
0401 
0402         if (!drm_mode_object_lease_required(objects[o]->type)) {
0403             DRM_DEBUG_KMS("invalid object for lease\n");
0404             ret = -EINVAL;
0405             goto out_free_objects;
0406         }
0407     }
0408 
0409     ret = validate_lease(dev, object_count, objects, universal_planes);
0410     if (ret) {
0411         DRM_DEBUG_LEASE("lease validation failed\n");
0412         goto out_free_objects;
0413     }
0414 
0415     /* add their IDs to the lease request - taking into account
0416        universal planes */
0417     for (o = 0; o < object_count; o++) {
0418         struct drm_mode_object *obj = objects[o];
0419         u32 object_id = objects[o]->id;
0420 
0421         DRM_DEBUG_LEASE("Adding object %d to lease\n", object_id);
0422 
0423         /*
0424          * We're using an IDR to hold the set of leased
0425          * objects, but we don't need to point at the object's
0426          * data structure from the lease as the main object_idr
0427          * will be used to actually find that. Instead, all we
0428          * really want is a 'leased/not-leased' result, for
0429          * which any non-NULL pointer will work fine.
0430          */
0431         ret = idr_alloc(leases, &drm_lease_idr_object , object_id, object_id + 1, GFP_KERNEL);
0432         if (ret < 0) {
0433             DRM_DEBUG_LEASE("Object %d cannot be inserted into leases (%d)\n",
0434                     object_id, ret);
0435             goto out_free_objects;
0436         }
0437         if (obj->type == DRM_MODE_OBJECT_CRTC && !universal_planes) {
0438             struct drm_crtc *crtc = obj_to_crtc(obj);
0439 
0440             ret = idr_alloc(leases, &drm_lease_idr_object, crtc->primary->base.id, crtc->primary->base.id + 1, GFP_KERNEL);
0441             if (ret < 0) {
0442                 DRM_DEBUG_LEASE("Object primary plane %d cannot be inserted into leases (%d)\n",
0443                         object_id, ret);
0444                 goto out_free_objects;
0445             }
0446             if (crtc->cursor) {
0447                 ret = idr_alloc(leases, &drm_lease_idr_object, crtc->cursor->base.id, crtc->cursor->base.id + 1, GFP_KERNEL);
0448                 if (ret < 0) {
0449                     DRM_DEBUG_LEASE("Object cursor plane %d cannot be inserted into leases (%d)\n",
0450                             object_id, ret);
0451                     goto out_free_objects;
0452                 }
0453             }
0454         }
0455     }
0456 
0457     ret = 0;
0458 out_free_objects:
0459     for (o = 0; o < object_count; o++) {
0460         if (objects[o])
0461             drm_mode_object_put(objects[o]);
0462     }
0463     kfree(objects);
0464     return ret;
0465 }
0466 
0467 /*
0468  * The master associated with the specified file will have a lease
0469  * created containing the objects specified in the ioctl structure.
0470  * A file descriptor will be allocated for that and returned to the
0471  * application.
0472  */
0473 int drm_mode_create_lease_ioctl(struct drm_device *dev,
0474                 void *data, struct drm_file *lessor_priv)
0475 {
0476     struct drm_mode_create_lease *cl = data;
0477     size_t object_count;
0478     int ret = 0;
0479     struct idr leases;
0480     struct drm_master *lessor;
0481     struct drm_master *lessee = NULL;
0482     struct file *lessee_file = NULL;
0483     struct file *lessor_file = lessor_priv->filp;
0484     struct drm_file *lessee_priv;
0485     int fd = -1;
0486     uint32_t *object_ids;
0487 
0488     /* Can't lease without MODESET */
0489     if (!drm_core_check_feature(dev, DRIVER_MODESET))
0490         return -EOPNOTSUPP;
0491 
0492     if (cl->flags && (cl->flags & ~(O_CLOEXEC | O_NONBLOCK))) {
0493         DRM_DEBUG_LEASE("invalid flags\n");
0494         return -EINVAL;
0495     }
0496 
0497     lessor = drm_file_get_master(lessor_priv);
0498     /* Do not allow sub-leases */
0499     if (lessor->lessor) {
0500         DRM_DEBUG_LEASE("recursive leasing not allowed\n");
0501         ret = -EINVAL;
0502         goto out_lessor;
0503     }
0504 
0505     object_count = cl->object_count;
0506 
0507     /* Handle leased objects, if any */
0508     idr_init(&leases);
0509     if (object_count != 0) {
0510         object_ids = memdup_user(u64_to_user_ptr(cl->object_ids),
0511                      array_size(object_count, sizeof(__u32)));
0512         if (IS_ERR(object_ids)) {
0513             ret = PTR_ERR(object_ids);
0514             idr_destroy(&leases);
0515             goto out_lessor;
0516         }
0517 
0518         /* fill and validate the object idr */
0519         ret = fill_object_idr(dev, lessor_priv, &leases,
0520                       object_count, object_ids);
0521         kfree(object_ids);
0522         if (ret) {
0523             DRM_DEBUG_LEASE("lease object lookup failed: %i\n", ret);
0524             idr_destroy(&leases);
0525             goto out_lessor;
0526         }
0527     }
0528 
0529     /* Allocate a file descriptor for the lease */
0530     fd = get_unused_fd_flags(cl->flags & (O_CLOEXEC | O_NONBLOCK));
0531     if (fd < 0) {
0532         idr_destroy(&leases);
0533         ret = fd;
0534         goto out_lessor;
0535     }
0536 
0537     DRM_DEBUG_LEASE("Creating lease\n");
0538     /* lessee will take the ownership of leases */
0539     lessee = drm_lease_create(lessor, &leases);
0540 
0541     if (IS_ERR(lessee)) {
0542         ret = PTR_ERR(lessee);
0543         idr_destroy(&leases);
0544         goto out_leases;
0545     }
0546 
0547     /* Clone the lessor file to create a new file for us */
0548     DRM_DEBUG_LEASE("Allocating lease file\n");
0549     lessee_file = file_clone_open(lessor_file);
0550     if (IS_ERR(lessee_file)) {
0551         ret = PTR_ERR(lessee_file);
0552         goto out_lessee;
0553     }
0554 
0555     lessee_priv = lessee_file->private_data;
0556     /* Change the file to a master one */
0557     drm_master_put(&lessee_priv->master);
0558     lessee_priv->master = lessee;
0559     lessee_priv->is_master = 1;
0560     lessee_priv->authenticated = 1;
0561 
0562     /* Pass fd back to userspace */
0563     DRM_DEBUG_LEASE("Returning fd %d id %d\n", fd, lessee->lessee_id);
0564     cl->fd = fd;
0565     cl->lessee_id = lessee->lessee_id;
0566 
0567     /* Hook up the fd */
0568     fd_install(fd, lessee_file);
0569 
0570     drm_master_put(&lessor);
0571     DRM_DEBUG_LEASE("drm_mode_create_lease_ioctl succeeded\n");
0572     return 0;
0573 
0574 out_lessee:
0575     drm_master_put(&lessee);
0576 
0577 out_leases:
0578     put_unused_fd(fd);
0579 
0580 out_lessor:
0581     drm_master_put(&lessor);
0582     DRM_DEBUG_LEASE("drm_mode_create_lease_ioctl failed: %d\n", ret);
0583     return ret;
0584 }
0585 
0586 int drm_mode_list_lessees_ioctl(struct drm_device *dev,
0587                    void *data, struct drm_file *lessor_priv)
0588 {
0589     struct drm_mode_list_lessees *arg = data;
0590     __u32 __user *lessee_ids = (__u32 __user *) (uintptr_t) (arg->lessees_ptr);
0591     __u32 count_lessees = arg->count_lessees;
0592     struct drm_master *lessor, *lessee;
0593     int count;
0594     int ret = 0;
0595 
0596     if (arg->pad)
0597         return -EINVAL;
0598 
0599     /* Can't lease without MODESET */
0600     if (!drm_core_check_feature(dev, DRIVER_MODESET))
0601         return -EOPNOTSUPP;
0602 
0603     lessor = drm_file_get_master(lessor_priv);
0604     DRM_DEBUG_LEASE("List lessees for %d\n", lessor->lessee_id);
0605 
0606     mutex_lock(&dev->mode_config.idr_mutex);
0607 
0608     count = 0;
0609     drm_for_each_lessee(lessee, lessor) {
0610         /* Only list un-revoked leases */
0611         if (!idr_is_empty(&lessee->leases)) {
0612             if (count_lessees > count) {
0613                 DRM_DEBUG_LEASE("Add lessee %d\n", lessee->lessee_id);
0614                 ret = put_user(lessee->lessee_id, lessee_ids + count);
0615                 if (ret)
0616                     break;
0617             }
0618             count++;
0619         }
0620     }
0621 
0622     DRM_DEBUG_LEASE("Lessor leases to %d\n", count);
0623     if (ret == 0)
0624         arg->count_lessees = count;
0625 
0626     mutex_unlock(&dev->mode_config.idr_mutex);
0627     drm_master_put(&lessor);
0628 
0629     return ret;
0630 }
0631 
0632 /* Return the list of leased objects for the specified lessee */
0633 int drm_mode_get_lease_ioctl(struct drm_device *dev,
0634                  void *data, struct drm_file *lessee_priv)
0635 {
0636     struct drm_mode_get_lease *arg = data;
0637     __u32 __user *object_ids = (__u32 __user *) (uintptr_t) (arg->objects_ptr);
0638     __u32 count_objects = arg->count_objects;
0639     struct drm_master *lessee;
0640     struct idr *object_idr;
0641     int count;
0642     void *entry;
0643     int object;
0644     int ret = 0;
0645 
0646     if (arg->pad)
0647         return -EINVAL;
0648 
0649     /* Can't lease without MODESET */
0650     if (!drm_core_check_feature(dev, DRIVER_MODESET))
0651         return -EOPNOTSUPP;
0652 
0653     lessee = drm_file_get_master(lessee_priv);
0654     DRM_DEBUG_LEASE("get lease for %d\n", lessee->lessee_id);
0655 
0656     mutex_lock(&dev->mode_config.idr_mutex);
0657 
0658     if (lessee->lessor == NULL)
0659         /* owner can use all objects */
0660         object_idr = &lessee->dev->mode_config.object_idr;
0661     else
0662         /* lessee can only use allowed object */
0663         object_idr = &lessee->leases;
0664 
0665     count = 0;
0666     idr_for_each_entry(object_idr, entry, object) {
0667         if (count_objects > count) {
0668             DRM_DEBUG_LEASE("adding object %d\n", object);
0669             ret = put_user(object, object_ids + count);
0670             if (ret)
0671                 break;
0672         }
0673         count++;
0674     }
0675 
0676     DRM_DEBUG("lease holds %d objects\n", count);
0677     if (ret == 0)
0678         arg->count_objects = count;
0679 
0680     mutex_unlock(&dev->mode_config.idr_mutex);
0681     drm_master_put(&lessee);
0682 
0683     return ret;
0684 }
0685 
0686 /*
0687  * This removes all of the objects from the lease without
0688  * actually getting rid of the lease itself; that way all
0689  * references to it still work correctly
0690  */
0691 int drm_mode_revoke_lease_ioctl(struct drm_device *dev,
0692                 void *data, struct drm_file *lessor_priv)
0693 {
0694     struct drm_mode_revoke_lease *arg = data;
0695     struct drm_master *lessor;
0696     struct drm_master *lessee;
0697     int ret = 0;
0698 
0699     DRM_DEBUG_LEASE("revoke lease for %d\n", arg->lessee_id);
0700 
0701     /* Can't lease without MODESET */
0702     if (!drm_core_check_feature(dev, DRIVER_MODESET))
0703         return -EOPNOTSUPP;
0704 
0705     lessor = drm_file_get_master(lessor_priv);
0706     mutex_lock(&dev->mode_config.idr_mutex);
0707 
0708     lessee = _drm_find_lessee(lessor, arg->lessee_id);
0709 
0710     /* No such lessee */
0711     if (!lessee) {
0712         ret = -ENOENT;
0713         goto fail;
0714     }
0715 
0716     /* Lease is not held by lessor */
0717     if (lessee->lessor != lessor) {
0718         ret = -EACCES;
0719         goto fail;
0720     }
0721 
0722     _drm_lease_revoke(lessee);
0723 
0724 fail:
0725     mutex_unlock(&dev->mode_config.idr_mutex);
0726     drm_master_put(&lessor);
0727 
0728     return ret;
0729 }