// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Copyright © 2017 Keith Packard <keithp@keithp.com>
 */
#include <linux/file.h>
#include <linux/uaccess.h>

#include <drm/drm_auth.h>
#include <drm/drm_crtc.h>
#include <drm/drm_drv.h>
#include <drm/drm_file.h>
#include <drm/drm_lease.h>
#include <drm/drm_print.h>

#include "drm_crtc_internal.h"
#include "drm_internal.h"

/**
 * DOC: drm leasing
 *
 * DRM leases provide information about whether a DRM master may control a DRM
 * mode setting object. This enables the creation of multiple DRM masters that
 * manage subsets of display resources.
 *
 * The original DRM master of a device 'owns' the available drm resources. It
 * may create additional DRM masters and 'lease' resources which it controls
 * to the new DRM master. This gives the new DRM master control over the
 * leased resources until the owner revokes the lease, or the new DRM master
 * is closed. Some helpful terminology:
 *
 * - An 'owner' is a &struct drm_master that is not leasing objects from
 *   another &struct drm_master, and hence 'owns' the objects. The owner can be
 *   identified as the &struct drm_master for which &drm_master.lessor is NULL.
 *
 * - A 'lessor' is a &struct drm_master which is leasing objects to one or more
 *   other &struct drm_master. Currently, lessees are not allowed to
 *   create sub-leases, hence the lessor is the same as the owner.
 *
 * - A 'lessee' is a &struct drm_master which is leasing objects from some
 *   other &struct drm_master. Each lessee only leases resources from a single
 *   lessor recorded in &drm_master.lessor, and holds the set of objects that
 *   it is leasing in &drm_master.leases.
 *
 * - A 'lease' is a contract between the lessor and lessee that identifies
 *   which resources may be controlled by the lessee. All of the resources
 *   that are leased must be owned by or leased to the lessor, and lessors are
 *   not permitted to lease the same object to multiple lessees.
 *
 * The set of objects any &struct drm_master 'controls' is limited to the set
 * of objects it leases (for lessees) or all objects (for owners).
 *
 * Objects not controlled by a &struct drm_master cannot be modified through
 * the various state manipulating ioctls, and any state reported back to user
 * space will be edited to make them appear idle and/or unusable. For
 * instance, connectors always report 'disconnected', while encoders
 * report no possible crtcs or clones.
 *
 * Since each lessee may lease objects from a single lessor, display resource
 * leases form a tree of &struct drm_master. As lessees are currently not
 * allowed to create sub-leases, the tree depth is limited to 1. All of
 * these get activated simultaneously when the top level device owner changes
 * through the SETMASTER or DROPMASTER IOCTL, so &drm_device.master points to
 * the owner at the top of the lease tree (i.e. the &struct drm_master for which
 * &drm_master.lessor is NULL). The full list of lessees that are leasing
 * objects from the owner can be searched via the owner's
 * &drm_master.lessee_idr.
 */

#define drm_for_each_lessee(lessee, lessor) \
	list_for_each_entry((lessee), &(lessor)->lessees, lessee_list)

static uint64_t drm_lease_idr_object;

struct drm_master *drm_lease_owner(struct drm_master *master)
{
	while (master->lessor != NULL)
		master = master->lessor;
	return master;
}

static struct drm_master*
_drm_find_lessee(struct drm_master *master, int lessee_id)
{
	lockdep_assert_held(&master->dev->mode_config.idr_mutex);
	return idr_find(&drm_lease_owner(master)->lessee_idr, lessee_id);
}

static int _drm_lease_held_master(struct drm_master *master, int id)
{
	lockdep_assert_held(&master->dev->mode_config.idr_mutex);
	if (master->lessor)
		return idr_find(&master->leases, id) != NULL;
	return true;
}

/* Checks if the given object has been leased to some lessee of drm_master */
static bool _drm_has_leased(struct drm_master *master, int id)
{
	struct drm_master *lessee;

	lockdep_assert_held(&master->dev->mode_config.idr_mutex);
	drm_for_each_lessee(lessee, master)
		if (_drm_lease_held_master(lessee, id))
			return true;
	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;
	bool ret;

	if (!file_priv)
		return true;

	master = drm_file_get_master(file_priv);
	if (!master)
		return true;
	if (!master->lessor) {
		ret = true;
		goto out;
	}
	mutex_lock(&master->dev->mode_config.idr_mutex);
	ret = _drm_lease_held_master(master, id);
	mutex_unlock(&master->dev->mode_config.idr_mutex);

out:
	drm_master_put(&master);
	return ret;
}

/*
 * Given a bitmask of crtcs to check, reconstructs a crtc mask based on the
 * crtcs which are visible through the specified file.
 */
uint32_t drm_lease_filter_crtcs(struct drm_file *file_priv, uint32_t crtcs_in)
{
	struct drm_master *master;
	struct drm_device *dev;
	struct drm_crtc *crtc;
	int count_in, count_out;
	uint32_t crtcs_out = 0;

	if (!file_priv)
		return crtcs_in;

	master = drm_file_get_master(file_priv);
	if (!master)
		return crtcs_in;
	if (!master->lessor) {
		crtcs_out = crtcs_in;
		goto out;
	}
	dev = master->dev;

	count_in = count_out = 0;
	mutex_lock(&master->dev->mode_config.idr_mutex);
	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
		if (_drm_lease_held_master(master, crtc->base.id)) {
			uint32_t mask_in = 1ul << count_in;

			if ((crtcs_in & mask_in) != 0) {
				uint32_t mask_out = 1ul << count_out;

				crtcs_out |= mask_out;
			}
			count_out++;
		}
		count_in++;
	}
	mutex_unlock(&master->dev->mode_config.idr_mutex);

out:
	drm_master_put(&master);
	return crtcs_out;
}

/*
 * Uses drm_master_create to allocate a new drm_master, then checks to
 * make sure all of the desired objects can be leased, atomically
 * leasing them to the new drmmaster.
 *
 * 	ERR_PTR(-EACCES)	some other master holds the title to any object
 * 	ERR_PTR(-ENOENT)	some object is not a valid DRM object for this device
 * 	ERR_PTR(-EBUSY)		some other lessee holds title to this object
 *	ERR_PTR(-EEXIST)	same object specified more than once in the provided list
 *	ERR_PTR(-ENOMEM)	allocation failed
 */
static struct drm_master *drm_lease_create(struct drm_master *lessor, struct idr *leases)
{
	struct drm_device *dev = lessor->dev;
	int error;
	struct drm_master *lessee;
	int object;
	int id;
	void *entry;

	drm_dbg_lease(dev, "lessor %d\n", lessor->lessee_id);

	lessee = drm_master_create(lessor->dev);
	if (!lessee) {
		drm_dbg_lease(dev, "drm_master_create failed\n");
		return ERR_PTR(-ENOMEM);
	}

	mutex_lock(&dev->mode_config.idr_mutex);

	idr_for_each_entry(leases, entry, object) {
		error = 0;
		if (!idr_find(&dev->mode_config.object_idr, object))
			error = -ENOENT;
		else if (_drm_has_leased(lessor, object))
			error = -EBUSY;

		if (error != 0) {
			drm_dbg_lease(dev, "object %d failed %d\n", object, error);
			goto out_lessee;
		}
	}

	/* Insert the new lessee into the tree */
	id = idr_alloc(&(drm_lease_owner(lessor)->lessee_idr), lessee, 1, 0, GFP_KERNEL);
	if (id < 0) {
		error = id;
		goto out_lessee;
	}

	lessee->lessee_id = id;
	lessee->lessor = drm_master_get(lessor);
	list_add_tail(&lessee->lessee_list, &lessor->lessees);

	/* Move the leases over */
	lessee->leases = *leases;
	drm_dbg_lease(dev, "new lessee %d %p, lessor %d %p\n",
		      lessee->lessee_id, lessee, lessor->lessee_id, lessor);

	mutex_unlock(&dev->mode_config.idr_mutex);
	return lessee;

out_lessee:
	mutex_unlock(&dev->mode_config.idr_mutex);

	drm_master_put(&lessee);

	return ERR_PTR(error);
}

void drm_lease_destroy(struct drm_master *master)
{
	struct drm_device *dev = master->dev;

	mutex_lock(&dev->mode_config.idr_mutex);

	drm_dbg_lease(dev, "drm_lease_destroy %d\n", master->lessee_id);

	/* This master is referenced by all lessees, hence it cannot be destroyed
	 * until all of them have been
	 */
	WARN_ON(!list_empty(&master->lessees));

	/* Remove this master from the lessee idr in the owner */
	if (master->lessee_id != 0) {
		drm_dbg_lease(dev, "remove master %d from device list of lessees\n",
			      master->lessee_id);
		idr_remove(&(drm_lease_owner(master)->lessee_idr), master->lessee_id);
	}

	/* Remove this master from any lessee list it may be on */
	list_del(&master->lessee_list);

	mutex_unlock(&dev->mode_config.idr_mutex);

	if (master->lessor) {
		/* Tell the master to check the lessee list */
		drm_sysfs_lease_event(dev);
		drm_master_put(&master->lessor);
	}

	drm_dbg_lease(dev, "drm_lease_destroy done %d\n", master->lessee_id);
}

static void _drm_lease_revoke(struct drm_master *top)
{
	int object;
	void *entry;
	struct drm_master *master = top;

	lockdep_assert_held(&top->dev->mode_config.idr_mutex);

	/*
	 * Walk the tree starting at 'top' emptying all leases. Because
	 * the tree is fully connected, we can do this without recursing
	 */
	for (;;) {
		drm_dbg_lease(master->dev, "revoke leases for %p %d\n",
			      master, master->lessee_id);

		/* Evacuate the lease */
		idr_for_each_entry(&master->leases, entry, object)
			idr_remove(&master->leases, object);

		/* Depth-first list walk */

		/* Down */
		if (!list_empty(&master->lessees)) {
			master = list_first_entry(&master->lessees, struct drm_master, lessee_list);
		} else {
			/* Up */
			while (master != top && master == list_last_entry(&master->lessor->lessees, struct drm_master, lessee_list))
				master = master->lessor;

			if (master == top)
				break;

			/* Over */
			master = list_next_entry(master, lessee_list);
		}
	}
}

void drm_lease_revoke(struct drm_master *top)
{
	mutex_lock(&top->dev->mode_config.idr_mutex);
	_drm_lease_revoke(top);
	mutex_unlock(&top->dev->mode_config.idr_mutex);
}

static int validate_lease(struct drm_device *dev,
			  int object_count,
			  struct drm_mode_object **objects,
			  bool universal_planes)
{
	int o;
	int has_crtc = -1;
	int has_connector = -1;
	int has_plane = -1;

	/* we want to confirm that there is at least one crtc, plane
	   connector object. */

	for (o = 0; o < object_count; o++) {
		if (objects[o]->type == DRM_MODE_OBJECT_CRTC && has_crtc == -1) {
			has_crtc = o;
		}
		if (objects[o]->type == DRM_MODE_OBJECT_CONNECTOR && has_connector == -1)
			has_connector = o;

		if (universal_planes) {
			if (objects[o]->type == DRM_MODE_OBJECT_PLANE && has_plane == -1)
				has_plane = o;
		}
	}
	if (has_crtc == -1 || has_connector == -1)
		return -EINVAL;
	if (universal_planes && has_plane == -1)
		return -EINVAL;
	return 0;
}

static int fill_object_idr(struct drm_device *dev,
			   struct drm_file *lessor_priv,
			   struct idr *leases,
			   int object_count,
			   u32 *object_ids)
{
	struct drm_mode_object **objects;
	u32 o;
	int ret;
	bool universal_planes = READ_ONCE(lessor_priv->universal_planes);

	objects = kcalloc(object_count, sizeof(struct drm_mode_object *),
			  GFP_KERNEL);
	if (!objects)
		return -ENOMEM;

	/* step one - get references to all the mode objects
	   and check for validity. */
	for (o = 0; o < object_count; o++) {
		objects[o] = drm_mode_object_find(dev, lessor_priv,
						  object_ids[o],
						  DRM_MODE_OBJECT_ANY);
		if (!objects[o]) {
			ret = -ENOENT;
			goto out_free_objects;
		}

		if (!drm_mode_object_lease_required(objects[o]->type)) {
			DRM_DEBUG_KMS("invalid object for lease\n");
			ret = -EINVAL;
			goto out_free_objects;
		}
	}

	ret = validate_lease(dev, object_count, objects, universal_planes);
	if (ret) {
		drm_dbg_lease(dev, "lease validation failed\n");
		goto out_free_objects;
	}

	/* add their IDs to the lease request - taking into account
	   universal planes */
	for (o = 0; o < object_count; o++) {
		struct drm_mode_object *obj = objects[o];
		u32 object_id = objects[o]->id;

		drm_dbg_lease(dev, "Adding object %d to lease\n", object_id);

		/*
		 * We're using an IDR to hold the set of leased
		 * objects, but we don't need to point at the object's
		 * data structure from the lease as the main object_idr
		 * will be used to actually find that. Instead, all we
		 * really want is a 'leased/not-leased' result, for
		 * which any non-NULL pointer will work fine.
		 */
		ret = idr_alloc(leases, &drm_lease_idr_object , object_id, object_id + 1, GFP_KERNEL);
		if (ret < 0) {
			drm_dbg_lease(dev, "Object %d cannot be inserted into leases (%d)\n",
				      object_id, ret);
			goto out_free_objects;
		}
		if (obj->type == DRM_MODE_OBJECT_CRTC && !universal_planes) {
			struct drm_crtc *crtc = obj_to_crtc(obj);

			ret = idr_alloc(leases, &drm_lease_idr_object, crtc->primary->base.id, crtc->primary->base.id + 1, GFP_KERNEL);
			if (ret < 0) {
				drm_dbg_lease(dev, "Object primary plane %d cannot be inserted into leases (%d)\n",
					      object_id, ret);
				goto out_free_objects;
			}
			if (crtc->cursor) {
				ret = idr_alloc(leases, &drm_lease_idr_object, crtc->cursor->base.id, crtc->cursor->base.id + 1, GFP_KERNEL);
				if (ret < 0) {
					drm_dbg_lease(dev, "Object cursor plane %d cannot be inserted into leases (%d)\n",
						      object_id, ret);
					goto out_free_objects;
				}
			}
		}
	}

	ret = 0;
out_free_objects:
	for (o = 0; o < object_count; o++) {
		if (objects[o])
			drm_mode_object_put(objects[o]);
	}
	kfree(objects);
	return ret;
}

/*
 * The master associated with the specified file will have a lease
 * created containing the objects specified in the ioctl structure.
 * A file descriptor will be allocated for that and returned to the
 * application.
 */
int drm_mode_create_lease_ioctl(struct drm_device *dev,
				void *data, struct drm_file *lessor_priv)
{
	struct drm_mode_create_lease *cl = data;
	size_t object_count;
	int ret = 0;
	struct idr leases;
	struct drm_master *lessor;
	struct drm_master *lessee = NULL;
	struct file *lessee_file = NULL;
	struct file *lessor_file = lessor_priv->filp;
	struct drm_file *lessee_priv;
	int fd = -1;
	uint32_t *object_ids;

	/* Can't lease without MODESET */
	if (!drm_core_check_feature(dev, DRIVER_MODESET))
		return -EOPNOTSUPP;

	if (cl->flags && (cl->flags & ~(O_CLOEXEC | O_NONBLOCK))) {
		drm_dbg_lease(dev, "invalid flags\n");
		return -EINVAL;
	}

	lessor = drm_file_get_master(lessor_priv);
	/* Do not allow sub-leases */
	if (lessor->lessor) {
		drm_dbg_lease(dev, "recursive leasing not allowed\n");
		ret = -EINVAL;
		goto out_lessor;
	}

	object_count = cl->object_count;

	/* Handle leased objects, if any */
	idr_init(&leases);
	if (object_count != 0) {
		object_ids = memdup_array_user(u64_to_user_ptr(cl->object_ids),
					       object_count, sizeof(__u32));
		if (IS_ERR(object_ids)) {
			ret = PTR_ERR(object_ids);
			idr_destroy(&leases);
			goto out_lessor;
		}

		/* fill and validate the object idr */
		ret = fill_object_idr(dev, lessor_priv, &leases,
				      object_count, object_ids);
		kfree(object_ids);
		if (ret) {
			drm_dbg_lease(dev, "lease object lookup failed: %i\n", ret);
			idr_destroy(&leases);
			goto out_lessor;
		}
	}

	/* Allocate a file descriptor for the lease */
	fd = get_unused_fd_flags(cl->flags & (O_CLOEXEC | O_NONBLOCK));
	if (fd < 0) {
		idr_destroy(&leases);
		ret = fd;
		goto out_lessor;
	}

	drm_dbg_lease(dev, "Creating lease\n");
	/* lessee will take the ownership of leases */
	lessee = drm_lease_create(lessor, &leases);

	if (IS_ERR(lessee)) {
		ret = PTR_ERR(lessee);
		idr_destroy(&leases);
		goto out_leases;
	}

	/* Clone the lessor file to create a new file for us */
	drm_dbg_lease(dev, "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);
	lessee_priv->master = lessee;
	lessee_priv->is_master = 1;
	lessee_priv->authenticated = 1;

	/* Pass fd back to userspace */
	drm_dbg_lease(dev, "Returning fd %d id %d\n", fd, lessee->lessee_id);
	cl->fd = fd;
	cl->lessee_id = lessee->lessee_id;

	/* Hook up the fd */
	fd_install(fd, lessee_file);

	drm_master_put(&lessor);
	drm_dbg_lease(dev, "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);
	drm_dbg_lease(dev, "drm_mode_create_lease_ioctl failed: %d\n", ret);
	return ret;
}

int drm_mode_list_lessees_ioctl(struct drm_device *dev,
			       void *data, struct drm_file *lessor_priv)
{
	struct drm_mode_list_lessees *arg = data;
	__u32 __user *lessee_ids = (__u32 __user *) (uintptr_t) (arg->lessees_ptr);
	__u32 count_lessees = arg->count_lessees;
	struct drm_master *lessor, *lessee;
	int count;
	int ret = 0;

	if (arg->pad)
		return -EINVAL;

	/* Can't lease without MODESET */
	if (!drm_core_check_feature(dev, DRIVER_MODESET))
		return -EOPNOTSUPP;

	lessor = drm_file_get_master(lessor_priv);
	drm_dbg_lease(dev, "List lessees for %d\n", lessor->lessee_id);

	mutex_lock(&dev->mode_config.idr_mutex);

	count = 0;
	drm_for_each_lessee(lessee, lessor) {
		/* Only list un-revoked leases */
		if (!idr_is_empty(&lessee->leases)) {
			if (count_lessees > count) {
				drm_dbg_lease(dev, "Add lessee %d\n",
					      lessee->lessee_id);
				ret = put_user(lessee->lessee_id, lessee_ids + count);
				if (ret)
					break;
			}
			count++;
		}
	}

	drm_dbg_lease(dev, "Lessor leases to %d\n", count);
	if (ret == 0)
		arg->count_lessees = count;

	mutex_unlock(&dev->mode_config.idr_mutex);
	drm_master_put(&lessor);

	return ret;
}

/* Return the list of leased objects for the specified lessee */
int drm_mode_get_lease_ioctl(struct drm_device *dev,
			     void *data, struct drm_file *lessee_priv)
{
	struct drm_mode_get_lease *arg = data;
	__u32 __user *object_ids = (__u32 __user *) (uintptr_t) (arg->objects_ptr);
	__u32 count_objects = arg->count_objects;
	struct drm_master *lessee;
	struct idr *object_idr;
	int count;
	void *entry;
	int object;
	int ret = 0;

	if (arg->pad)
		return -EINVAL;

	/* Can't lease without MODESET */
	if (!drm_core_check_feature(dev, DRIVER_MODESET))
		return -EOPNOTSUPP;

	lessee = drm_file_get_master(lessee_priv);
	drm_dbg_lease(dev, "get lease for %d\n", lessee->lessee_id);

	mutex_lock(&dev->mode_config.idr_mutex);

	if (lessee->lessor == NULL)
		/* owner can use all objects */
		object_idr = &lessee->dev->mode_config.object_idr;
	else
		/* lessee can only use allowed object */
		object_idr = &lessee->leases;

	count = 0;
	idr_for_each_entry(object_idr, entry, object) {
		if (count_objects > count) {
			drm_dbg_lease(dev, "adding object %d\n", object);
			ret = put_user(object, object_ids + count);
			if (ret)
				break;
		}
		count++;
	}

	DRM_DEBUG("lease holds %d objects\n", count);
	if (ret == 0)
		arg->count_objects = count;

	mutex_unlock(&dev->mode_config.idr_mutex);
	drm_master_put(&lessee);

	return ret;
}

/*
 * This removes all of the objects from the lease without
 * actually getting rid of the lease itself; that way all
 * references to it still work correctly
 */
int drm_mode_revoke_lease_ioctl(struct drm_device *dev,
				void *data, struct drm_file *lessor_priv)
{
	struct drm_mode_revoke_lease *arg = data;
	struct drm_master *lessor;
	struct drm_master *lessee;
	int ret = 0;

	drm_dbg_lease(dev, "revoke lease for %d\n", arg->lessee_id);

	/* Can't lease without MODESET */
	if (!drm_core_check_feature(dev, DRIVER_MODESET))
		return -EOPNOTSUPP;

	lessor = drm_file_get_master(lessor_priv);
	mutex_lock(&dev->mode_config.idr_mutex);

	lessee = _drm_find_lessee(lessor, arg->lessee_id);

	/* No such lessee */
	if (!lessee) {
		ret = -ENOENT;
		goto fail;
	}

	/* Lease is not held by lessor */
	if (lessee->lessor != lessor) {
		ret = -EACCES;
		goto fail;
	}

	_drm_lease_revoke(lessee);

fail:
	mutex_unlock(&dev->mode_config.idr_mutex);
	drm_master_put(&lessor);

	return ret;
}
