// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
/*
 * Copyright (c) 2017, Mellanox Technologies inc.  All rights reserved.
 */
#include <rdma/uverbs_ioctl.h>
#include <rdma/rdma_user_ioctl.h>
#include <linux/bitops.h>
#include "rdma_core.h"
#include "uverbs.h"

static int ib_uverbs_notsupp(struct uverbs_attr_bundle *attrs)
{
	return -EOPNOTSUPP;
}

static void *uapi_add_elm(struct uverbs_api *uapi, u32 key, size_t alloc_size)
{
	void *elm;
	int rc;

	if (key == UVERBS_API_KEY_ERR)
		return ERR_PTR(-EOVERFLOW);

	elm = kzalloc(alloc_size, GFP_KERNEL);
	if (!elm)
		return ERR_PTR(-ENOMEM);
	rc = radix_tree_insert(&uapi->radix, key, elm);
	if (rc) {
		kfree(elm);
		return ERR_PTR(rc);
	}

	return elm;
}

static void *uapi_add_get_elm(struct uverbs_api *uapi, u32 key,
			      size_t alloc_size, bool *exists)
{
	void *elm;

	elm = uapi_add_elm(uapi, key, alloc_size);
	if (!IS_ERR(elm)) {
		*exists = false;
		return elm;
	}

	if (elm != ERR_PTR(-EEXIST))
		return elm;

	elm = radix_tree_lookup(&uapi->radix, key);
	if (WARN_ON(!elm))
		return ERR_PTR(-EINVAL);
	*exists = true;
	return elm;
}

static int uapi_create_write(struct uverbs_api *uapi,
			     struct ib_device *ibdev,
			     const struct uapi_definition *def,
			     u32 obj_key,
			     u32 *cur_method_key)
{
	struct uverbs_api_write_method *method_elm;
	u32 method_key = obj_key;
	bool exists;

	if (def->write.is_ex)
		method_key |= uapi_key_write_ex_method(def->write.command_num);
	else
		method_key |= uapi_key_write_method(def->write.command_num);

	method_elm = uapi_add_get_elm(uapi, method_key, sizeof(*method_elm),
				      &exists);
	if (IS_ERR(method_elm))
		return PTR_ERR(method_elm);

	if (WARN_ON(exists && (def->write.is_ex != method_elm->is_ex)))
		return -EINVAL;

	method_elm->is_ex = def->write.is_ex;
	method_elm->handler = def->func_write;
	if (def->write.is_ex)
		method_elm->disabled = !(ibdev->uverbs_ex_cmd_mask &
					 BIT_ULL(def->write.command_num));
	else
		method_elm->disabled = !(ibdev->uverbs_cmd_mask &
					 BIT_ULL(def->write.command_num));

	if (!def->write.is_ex && def->func_write) {
		method_elm->has_udata = def->write.has_udata;
		method_elm->has_resp = def->write.has_resp;
		method_elm->req_size = def->write.req_size;
		method_elm->resp_size = def->write.resp_size;
	}

	*cur_method_key = method_key;
	return 0;
}

static int uapi_merge_method(struct uverbs_api *uapi,
			     struct uverbs_api_object *obj_elm, u32 obj_key,
			     const struct uverbs_method_def *method,
			     bool is_driver)
{
	u32 method_key = obj_key | uapi_key_ioctl_method(method->id);
	struct uverbs_api_ioctl_method *method_elm;
	unsigned int i;
	bool exists;

	if (!method->attrs)
		return 0;

	method_elm = uapi_add_get_elm(uapi, method_key, sizeof(*method_elm),
				      &exists);
	if (IS_ERR(method_elm))
		return PTR_ERR(method_elm);
	if (exists) {
		/*
		 * This occurs when a driver uses ADD_UVERBS_ATTRIBUTES_SIMPLE
		 */
		if (WARN_ON(method->handler))
			return -EINVAL;
	} else {
		WARN_ON(!method->handler);
		rcu_assign_pointer(method_elm->handler, method->handler);
		if (method->handler != uverbs_destroy_def_handler)
			method_elm->driver_method = is_driver;
	}

	for (i = 0; i != method->num_attrs; i++) {
		const struct uverbs_attr_def *attr = (*method->attrs)[i];
		struct uverbs_api_attr *attr_slot;

		if (!attr)
			continue;

		/*
		 * ENUM_IN contains the 'ids' pointer to the driver's .rodata,
		 * so if it is specified by a driver then it always makes this
		 * into a driver method.
		 */
		if (attr->attr.type == UVERBS_ATTR_TYPE_ENUM_IN)
			method_elm->driver_method |= is_driver;

		/*
		 * Like other uobject based things we only support a single
		 * uobject being NEW'd or DESTROY'd
		 */
		if (attr->attr.type == UVERBS_ATTR_TYPE_IDRS_ARRAY) {
			u8 access = attr->attr.u2.objs_arr.access;

			if (WARN_ON(access == UVERBS_ACCESS_NEW ||
				    access == UVERBS_ACCESS_DESTROY))
				return -EINVAL;
		}

		attr_slot =
			uapi_add_elm(uapi, method_key | uapi_key_attr(attr->id),
				     sizeof(*attr_slot));
		/* Attributes are not allowed to be modified by drivers */
		if (IS_ERR(attr_slot))
			return PTR_ERR(attr_slot);

		attr_slot->spec = attr->attr;
	}

	return 0;
}

static int uapi_merge_obj_tree(struct uverbs_api *uapi,
			       const struct uverbs_object_def *obj,
			       bool is_driver)
{
	struct uverbs_api_object *obj_elm;
	unsigned int i;
	u32 obj_key;
	bool exists;
	int rc;

	obj_key = uapi_key_obj(obj->id);
	obj_elm = uapi_add_get_elm(uapi, obj_key, sizeof(*obj_elm), &exists);
	if (IS_ERR(obj_elm))
		return PTR_ERR(obj_elm);

	if (obj->type_attrs) {
		if (WARN_ON(obj_elm->type_attrs))
			return -EINVAL;

		obj_elm->id = obj->id;
		obj_elm->type_attrs = obj->type_attrs;
		obj_elm->type_class = obj->type_attrs->type_class;
		/*
		 * Today drivers are only permitted to use idr_class and
		 * fd_class types. We can revoke the IDR types during
		 * disassociation, and the FD types require the driver to use
		 * struct file_operations.owner to prevent the driver module
		 * code from unloading while the file is open. This provides
		 * enough safety that uverbs_close_fd() will continue to work.
		 * Drivers using FD are responsible to handle disassociation of
		 * the device on their own.
		 */
		if (WARN_ON(is_driver &&
			    obj->type_attrs->type_class != &uverbs_idr_class &&
			    obj->type_attrs->type_class != &uverbs_fd_class))
			return -EINVAL;
	}

	if (!obj->methods)
		return 0;

	for (i = 0; i != obj->num_methods; i++) {
		const struct uverbs_method_def *method = (*obj->methods)[i];

		if (!method)
			continue;

		rc = uapi_merge_method(uapi, obj_elm, obj_key, method,
				       is_driver);
		if (rc)
			return rc;
	}

	return 0;
}

static int uapi_disable_elm(struct uverbs_api *uapi,
			    const struct uapi_definition *def,
			    u32 obj_key,
			    u32 method_key)
{
	bool exists;

	if (def->scope == UAPI_SCOPE_OBJECT) {
		struct uverbs_api_object *obj_elm;

		obj_elm = uapi_add_get_elm(
			uapi, obj_key, sizeof(*obj_elm), &exists);
		if (IS_ERR(obj_elm))
			return PTR_ERR(obj_elm);
		obj_elm->disabled = 1;
		return 0;
	}

	if (def->scope == UAPI_SCOPE_METHOD &&
	    uapi_key_is_ioctl_method(method_key)) {
		struct uverbs_api_ioctl_method *method_elm;

		method_elm = uapi_add_get_elm(uapi, method_key,
					      sizeof(*method_elm), &exists);
		if (IS_ERR(method_elm))
			return PTR_ERR(method_elm);
		method_elm->disabled = 1;
		return 0;
	}

	if (def->scope == UAPI_SCOPE_METHOD &&
	    (uapi_key_is_write_method(method_key) ||
	     uapi_key_is_write_ex_method(method_key))) {
		struct uverbs_api_write_method *write_elm;

		write_elm = uapi_add_get_elm(uapi, method_key,
					     sizeof(*write_elm), &exists);
		if (IS_ERR(write_elm))
			return PTR_ERR(write_elm);
		write_elm->disabled = 1;
		return 0;
	}

	WARN_ON(true);
	return -EINVAL;
}

static int uapi_merge_def(struct uverbs_api *uapi, struct ib_device *ibdev,
			  const struct uapi_definition *def_list,
			  bool is_driver)
{
	const struct uapi_definition *def = def_list;
	u32 cur_obj_key = UVERBS_API_KEY_ERR;
	u32 cur_method_key = UVERBS_API_KEY_ERR;
	bool exists;
	int rc;

	if (!def_list)
		return 0;

	for (;; def++) {
		switch ((enum uapi_definition_kind)def->kind) {
		case UAPI_DEF_CHAIN:
			rc = uapi_merge_def(uapi, ibdev, def->chain, is_driver);
			if (rc)
				return rc;
			continue;

		case UAPI_DEF_CHAIN_OBJ_TREE:
			if (WARN_ON(def->object_start.object_id !=
				    def->chain_obj_tree->id))
				return -EINVAL;

			cur_obj_key = uapi_key_obj(def->object_start.object_id);
			rc = uapi_merge_obj_tree(uapi, def->chain_obj_tree,
						 is_driver);
			if (rc)
				return rc;
			continue;

		case UAPI_DEF_END:
			return 0;

		case UAPI_DEF_IS_SUPPORTED_DEV_FN: {
			void **ibdev_fn =
				(void *)(&ibdev->ops) + def->needs_fn_offset;

			if (*ibdev_fn)
				continue;
			rc = uapi_disable_elm(
				uapi, def, cur_obj_key, cur_method_key);
			if (rc)
				return rc;
			continue;
		}

		case UAPI_DEF_IS_SUPPORTED_FUNC:
			if (def->func_is_supported(ibdev))
				continue;
			rc = uapi_disable_elm(
				uapi, def, cur_obj_key, cur_method_key);
			if (rc)
				return rc;
			continue;

		case UAPI_DEF_OBJECT_START: {
			struct uverbs_api_object *obj_elm;

			cur_obj_key = uapi_key_obj(def->object_start.object_id);
			obj_elm = uapi_add_get_elm(uapi, cur_obj_key,
						   sizeof(*obj_elm), &exists);
			if (IS_ERR(obj_elm))
				return PTR_ERR(obj_elm);
			continue;
		}

		case UAPI_DEF_WRITE:
			rc = uapi_create_write(
				uapi, ibdev, def, cur_obj_key, &cur_method_key);
			if (rc)
				return rc;
			continue;
		}
		WARN_ON(true);
		return -EINVAL;
	}
}

static int
uapi_finalize_ioctl_method(struct uverbs_api *uapi,
			   struct uverbs_api_ioctl_method *method_elm,
			   u32 method_key)
{
	struct radix_tree_iter iter;
	unsigned int num_attrs = 0;
	unsigned int max_bkey = 0;
	bool single_uobj = false;
	void __rcu **slot;

	method_elm->destroy_bkey = UVERBS_API_ATTR_BKEY_LEN;
	radix_tree_for_each_slot (slot, &uapi->radix, &iter,
				  uapi_key_attrs_start(method_key)) {
		struct uverbs_api_attr *elm =
			rcu_dereference_protected(*slot, true);
		u32 attr_key = iter.index & UVERBS_API_ATTR_KEY_MASK;
		u32 attr_bkey = uapi_bkey_attr(attr_key);
		u8 type = elm->spec.type;

		if (uapi_key_attr_to_ioctl_method(iter.index) !=
		    uapi_key_attr_to_ioctl_method(method_key))
			break;

		if (elm->spec.mandatory)
			__set_bit(attr_bkey, method_elm->attr_mandatory);

		if (elm->spec.is_udata)
			method_elm->has_udata = true;

		if (type == UVERBS_ATTR_TYPE_IDR ||
		    type == UVERBS_ATTR_TYPE_FD) {
			u8 access = elm->spec.u.obj.access;

			/*
			 * Verbs specs may only have one NEW/DESTROY, we don't
			 * have the infrastructure to abort multiple NEW's or
			 * cope with multiple DESTROY failure.
			 */
			if (access == UVERBS_ACCESS_NEW ||
			    access == UVERBS_ACCESS_DESTROY) {
				if (WARN_ON(single_uobj))
					return -EINVAL;

				single_uobj = true;
				if (WARN_ON(!elm->spec.mandatory))
					return -EINVAL;
			}

			if (access == UVERBS_ACCESS_DESTROY)
				method_elm->destroy_bkey = attr_bkey;
		}

		max_bkey = max(max_bkey, attr_bkey);
		num_attrs++;
	}

	method_elm->key_bitmap_len = max_bkey + 1;
	WARN_ON(method_elm->key_bitmap_len > UVERBS_API_ATTR_BKEY_LEN);

	uapi_compute_bundle_size(method_elm, num_attrs);
	return 0;
}

static int uapi_finalize(struct uverbs_api *uapi)
{
	const struct uverbs_api_write_method **data;
	unsigned long max_write_ex = 0;
	unsigned long max_write = 0;
	struct radix_tree_iter iter;
	void __rcu **slot;
	int rc;
	int i;

	radix_tree_for_each_slot (slot, &uapi->radix, &iter, 0) {
		struct uverbs_api_ioctl_method *method_elm =
			rcu_dereference_protected(*slot, true);

		if (uapi_key_is_ioctl_method(iter.index)) {
			rc = uapi_finalize_ioctl_method(uapi, method_elm,
							iter.index);
			if (rc)
				return rc;
		}

		if (uapi_key_is_write_method(iter.index))
			max_write = max(max_write,
					iter.index & UVERBS_API_ATTR_KEY_MASK);
		if (uapi_key_is_write_ex_method(iter.index))
			max_write_ex =
				max(max_write_ex,
				    iter.index & UVERBS_API_ATTR_KEY_MASK);
	}

	uapi->notsupp_method.handler = ib_uverbs_notsupp;
	uapi->num_write = max_write + 1;
	uapi->num_write_ex = max_write_ex + 1;
	data = kmalloc_array(uapi->num_write + uapi->num_write_ex,
			     sizeof(*uapi->write_methods), GFP_KERNEL);
	for (i = 0; i != uapi->num_write + uapi->num_write_ex; i++)
		data[i] = &uapi->notsupp_method;
	uapi->write_methods = data;
	uapi->write_ex_methods = data + uapi->num_write;

	radix_tree_for_each_slot (slot, &uapi->radix, &iter, 0) {
		if (uapi_key_is_write_method(iter.index))
			uapi->write_methods[iter.index &
					    UVERBS_API_ATTR_KEY_MASK] =
				rcu_dereference_protected(*slot, true);
		if (uapi_key_is_write_ex_method(iter.index))
			uapi->write_ex_methods[iter.index &
					       UVERBS_API_ATTR_KEY_MASK] =
				rcu_dereference_protected(*slot, true);
	}

	return 0;
}

static void uapi_remove_range(struct uverbs_api *uapi, u32 start, u32 last)
{
	struct radix_tree_iter iter;
	void __rcu **slot;

	radix_tree_for_each_slot (slot, &uapi->radix, &iter, start) {
		if (iter.index > last)
			return;
		kfree(rcu_dereference_protected(*slot, true));
		radix_tree_iter_delete(&uapi->radix, &iter, slot);
	}
}

static void uapi_remove_object(struct uverbs_api *uapi, u32 obj_key)
{
	uapi_remove_range(uapi, obj_key,
			  obj_key | UVERBS_API_METHOD_KEY_MASK |
				  UVERBS_API_ATTR_KEY_MASK);
}

static void uapi_remove_method(struct uverbs_api *uapi, u32 method_key)
{
	uapi_remove_range(uapi, method_key,
			  method_key | UVERBS_API_ATTR_KEY_MASK);
}


static u32 uapi_get_obj_id(struct uverbs_attr_spec *spec)
{
	if (spec->type == UVERBS_ATTR_TYPE_IDR ||
	    spec->type == UVERBS_ATTR_TYPE_FD)
		return spec->u.obj.obj_type;
	if (spec->type == UVERBS_ATTR_TYPE_IDRS_ARRAY)
		return spec->u2.objs_arr.obj_type;
	return UVERBS_API_KEY_ERR;
}

static void uapi_key_okay(u32 key)
{
	unsigned int count = 0;

	if (uapi_key_is_object(key))
		count++;
	if (uapi_key_is_ioctl_method(key))
		count++;
	if (uapi_key_is_write_method(key))
		count++;
	if (uapi_key_is_write_ex_method(key))
		count++;
	if (uapi_key_is_attr(key))
		count++;
	WARN(count != 1, "Bad count %d key=%x", count, key);
}

static void uapi_finalize_disable(struct uverbs_api *uapi)
{
	struct radix_tree_iter iter;
	u32 starting_key = 0;
	bool scan_again = false;
	void __rcu **slot;

again:
	radix_tree_for_each_slot (slot, &uapi->radix, &iter, starting_key) {
		uapi_key_okay(iter.index);

		if (uapi_key_is_object(iter.index)) {
			struct uverbs_api_object *obj_elm =
				rcu_dereference_protected(*slot, true);

			if (obj_elm->disabled) {
				/* Have to check all the attrs again */
				scan_again = true;
				starting_key = iter.index;
				uapi_remove_object(uapi, iter.index);
				goto again;
			}
			continue;
		}

		if (uapi_key_is_ioctl_method(iter.index)) {
			struct uverbs_api_ioctl_method *method_elm =
				rcu_dereference_protected(*slot, true);

			if (method_elm->disabled) {
				starting_key = iter.index;
				uapi_remove_method(uapi, iter.index);
				goto again;
			}
			continue;
		}

		if (uapi_key_is_write_method(iter.index) ||
		    uapi_key_is_write_ex_method(iter.index)) {
			struct uverbs_api_write_method *method_elm =
				rcu_dereference_protected(*slot, true);

			if (method_elm->disabled) {
				kfree(method_elm);
				radix_tree_iter_delete(&uapi->radix, &iter, slot);
			}
			continue;
		}

		if (uapi_key_is_attr(iter.index)) {
			struct uverbs_api_attr *attr_elm =
				rcu_dereference_protected(*slot, true);
			const struct uverbs_api_object *tmp_obj;
			u32 obj_key;

			/*
			 * If the method has a mandatory object handle
			 * attribute which relies on an object which is not
			 * present then the entire method is uncallable.
			 */
			if (!attr_elm->spec.mandatory)
				continue;
			obj_key = uapi_get_obj_id(&attr_elm->spec);
			if (obj_key == UVERBS_API_KEY_ERR)
				continue;
			tmp_obj = uapi_get_object(uapi, obj_key);
			if (IS_ERR(tmp_obj)) {
				if (PTR_ERR(tmp_obj) == -ENOMSG)
					continue;
			} else {
				if (!tmp_obj->disabled)
					continue;
			}

			starting_key = iter.index;
			uapi_remove_method(
				uapi,
				iter.index & (UVERBS_API_OBJ_KEY_MASK |
					      UVERBS_API_METHOD_KEY_MASK));
			goto again;
		}

		WARN_ON(false);
	}

	if (!scan_again)
		return;
	scan_again = false;
	starting_key = 0;
	goto again;
}

void uverbs_destroy_api(struct uverbs_api *uapi)
{
	if (!uapi)
		return;

	uapi_remove_range(uapi, 0, U32_MAX);
	kfree(uapi->write_methods);
	kfree(uapi);
}

static const struct uapi_definition uverbs_core_api[] = {
	UAPI_DEF_CHAIN(uverbs_def_obj_counters),
	UAPI_DEF_CHAIN(uverbs_def_obj_cq),
	UAPI_DEF_CHAIN(uverbs_def_obj_device),
	UAPI_DEF_CHAIN(uverbs_def_obj_dm),
	UAPI_DEF_CHAIN(uverbs_def_obj_flow_action),
	UAPI_DEF_CHAIN(uverbs_def_obj_intf),
	UAPI_DEF_CHAIN(uverbs_def_obj_mr),
	UAPI_DEF_CHAIN(uverbs_def_write_intf),
	{},
};

struct uverbs_api *uverbs_alloc_api(struct ib_device *ibdev)
{
	struct uverbs_api *uapi;
	int rc;

	uapi = kzalloc(sizeof(*uapi), GFP_KERNEL);
	if (!uapi)
		return ERR_PTR(-ENOMEM);

	INIT_RADIX_TREE(&uapi->radix, GFP_KERNEL);
	uapi->driver_id = ibdev->ops.driver_id;

	rc = uapi_merge_def(uapi, ibdev, uverbs_core_api, false);
	if (rc)
		goto err;
	rc = uapi_merge_def(uapi, ibdev, ibdev->driver_def, true);
	if (rc)
		goto err;

	uapi_finalize_disable(uapi);
	rc = uapi_finalize(uapi);
	if (rc)
		goto err;

	return uapi;
err:
	if (rc != -ENOMEM)
		dev_err(&ibdev->dev,
			"Setup of uverbs_api failed, kernel parsing tree description is not valid (%d)??\n",
			rc);

	uverbs_destroy_api(uapi);
	return ERR_PTR(rc);
}

/*
 * The pre version is done before destroying the HW objects, it only blocks
 * off method access. All methods that require the ib_dev or the module data
 * must test one of these assignments prior to continuing.
 */
void uverbs_disassociate_api_pre(struct ib_uverbs_device *uverbs_dev)
{
	struct uverbs_api *uapi = uverbs_dev->uapi;
	struct radix_tree_iter iter;
	void __rcu **slot;

	rcu_assign_pointer(uverbs_dev->ib_dev, NULL);

	radix_tree_for_each_slot (slot, &uapi->radix, &iter, 0) {
		if (uapi_key_is_ioctl_method(iter.index)) {
			struct uverbs_api_ioctl_method *method_elm =
				rcu_dereference_protected(*slot, true);

			if (method_elm->driver_method)
				rcu_assign_pointer(method_elm->handler, NULL);
		}
	}

	synchronize_srcu(&uverbs_dev->disassociate_srcu);
}

/*
 * Called when a driver disassociates from the ib_uverbs_device. The
 * assumption is that the driver module will unload after. Replace everything
 * related to the driver with NULL as a safety measure.
 */
void uverbs_disassociate_api(struct uverbs_api *uapi)
{
	struct radix_tree_iter iter;
	void __rcu **slot;

	radix_tree_for_each_slot (slot, &uapi->radix, &iter, 0) {
		if (uapi_key_is_object(iter.index)) {
			struct uverbs_api_object *object_elm =
				rcu_dereference_protected(*slot, true);

			/*
			 * Some type_attrs are in the driver module. We don't
			 * bother to keep track of which since there should be
			 * no use of this after disassociate.
			 */
			object_elm->type_attrs = NULL;
		} else if (uapi_key_is_attr(iter.index)) {
			struct uverbs_api_attr *elm =
				rcu_dereference_protected(*slot, true);

			if (elm->spec.type == UVERBS_ATTR_TYPE_ENUM_IN)
				elm->spec.u2.enum_def.ids = NULL;
		}
	}
}
