/*
 * Copyright (c) 2017, Mellanox Technologies inc.  All rights reserved.
 *
 * This software is available to you under a choice of one of two
 * licenses.  You may choose to be licensed under the terms of the GNU
 * General Public License (GPL) Version 2, available from the file
 * COPYING in the main directory of this source tree, or the
 * OpenIB.org BSD license below:
 *
 *     Redistribution and use in source and binary forms, with or
 *     without modification, are permitted provided that the following
 *     conditions are met:
 *
 *      - Redistributions of source code must retain the above
 *        copyright notice, this list of conditions and the following
 *        disclaimer.
 *
 *      - Redistributions in binary form must reproduce the above
 *        copyright notice, this list of conditions and the following
 *        disclaimer in the documentation and/or other materials
 *        provided with the distribution.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

#include <rdma/uverbs_ioctl.h>
#include <rdma/rdma_user_ioctl.h>
#include <linux/bitops.h>
#include "uverbs.h"

#define UVERBS_NUM_NS (UVERBS_ID_NS_MASK >> UVERBS_ID_NS_SHIFT)
#define GET_NS_ID(idx) (((idx) & UVERBS_ID_NS_MASK) >> UVERBS_ID_NS_SHIFT)
#define GET_ID(idx) ((idx) & ~UVERBS_ID_NS_MASK)

#define _for_each_element(elem, tmpi, tmpj, hashes, num_buckets_offset,	       \
			  buckets_offset)				       \
	for (tmpj = 0,							       \
	     elem = (*(const void ***)((hashes)[tmpi] +			       \
				       (buckets_offset)))[0];	               \
	     tmpj < *(size_t *)((hashes)[tmpi] + (num_buckets_offset));        \
	     tmpj++)						               \
		if ((elem = ((*(const void ***)(hashes[tmpi] +		       \
						(buckets_offset)))[tmpj])))

/*
 * Iterate all elements of a few @hashes. The number of given hashes is
 * indicated by @num_hashes. The offset of the number of buckets in the hash is
 * represented by @num_buckets_offset, while the offset of the buckets array in
 * the hash structure is represented by @buckets_offset. tmpi and tmpj are two
 * short (or int) based indices that are given by the user. tmpi iterates over
 * the different hashes. @elem points the current element in the hashes[tmpi]
 * bucket we are looping on. To be honest, @hashes representation isn't exactly
 * a hash, but more a collection of elements. These elements' ids are treated
 * in a hash like manner, where the first upper bits are the bucket number.
 * These elements are later mapped into a perfect-hash.
 */
#define for_each_element(elem, tmpi, tmpj, hashes, num_hashes,                 \
			 num_buckets_offset, buckets_offset)		       \
	for (tmpi = 0; tmpi < (num_hashes); tmpi++)		               \
		_for_each_element(elem, tmpi, tmpj, hashes, num_buckets_offset,\
				  buckets_offset)

#define get_elements_iterators_entry_above(iters, num_elements, elements,     \
					  num_objects_fld, objects_fld, bucket,\
					  min_id)			       \
	get_elements_above_id((const void **)iters, num_elements,       \
				     (const void **)(elements),		       \
				     offsetof(typeof(**elements),	       \
					      num_objects_fld),		       \
				     offsetof(typeof(**elements), objects_fld),\
				     offsetof(typeof(***(*elements)->objects_fld), id),\
				     bucket, min_id)

#define get_objects_above_id(iters, num_trees, trees, bucket, min_id)	       \
	get_elements_iterators_entry_above(iters, num_trees, trees,	       \
					   num_objects, objects, bucket, min_id)

#define get_methods_above_id(method_iters, num_iters, iters, bucket, min_id)\
	get_elements_iterators_entry_above(method_iters, num_iters, iters,     \
					   num_methods, methods, bucket, min_id)

#define get_attrs_above_id(attrs_iters, num_iters, iters, bucket, min_id)\
	get_elements_iterators_entry_above(attrs_iters, num_iters, iters,      \
					   num_attrs, attrs, bucket, min_id)

/*
 * get_elements_above_id get a few hashes represented by @elements and
 * @num_elements. The hashes fields are described by @num_offset, @data_offset
 * and @id_offset in the same way as required by for_each_element. The function
 * returns an array of @iters, represents an array of elements in the hashes
 * buckets, which their ids are the smallest ids in all hashes but are all
 * larger than the id given by min_id. Elements are only added to the iters
 * array if their id belongs to the bucket @bucket. The number of elements in
 * the returned array is returned by the function. @min_id is also updated to
 * reflect the new min_id of all elements in iters.
 */
static size_t get_elements_above_id(const void **iters,
				    unsigned int num_elements,
				    const void **elements,
				    size_t num_offset,
				    size_t data_offset,
				    size_t id_offset,
				    u16 bucket,
				    short *min_id)
{
	size_t num_iters = 0;
	short min = SHRT_MAX;
	const void *elem;
	int i, j, last_stored = -1;
	unsigned int equal_min = 0;

	for_each_element(elem, i, j, elements, num_elements, num_offset,
			 data_offset) {
		u16 id = *(u16 *)(elem + id_offset);

		if (GET_NS_ID(id) != bucket)
			continue;

		if (GET_ID(id) < *min_id ||
		    (min != SHRT_MAX && GET_ID(id) > min))
			continue;

		/*
		 * We first iterate all hashes represented by @elements. When
		 * we do, we try to find an element @elem in the bucket @bucket
		 * which its id is min. Since we can't ensure the user sorted
		 * the elements in increasing order, we override this hash's
		 * minimal id element we found, if a new element with a smaller
		 * id was just found.
		 */
		iters[last_stored == i ? num_iters - 1 : num_iters++] = elem;
		last_stored = i;
		if (min == GET_ID(id))
			equal_min++;
		else
			equal_min = 1;
		min = GET_ID(id);
	}

	/*
	 * We only insert to our iters array an element, if its id is smaller
	 * than all previous ids. Therefore, the final iters array is sorted so
	 * that smaller ids are in the end of the array.
	 * Therefore, we need to clean the beginning of the array to make sure
	 * all ids of final elements are equal to min.
	 */
	memmove(iters, iters + num_iters - equal_min, sizeof(*iters) * equal_min);

	*min_id = min;
	return equal_min;
}

#define find_max_element_entry_id(num_elements, elements, num_objects_fld, \
				  objects_fld, bucket)			   \
	find_max_element_id(num_elements, (const void **)(elements),	   \
			    offsetof(typeof(**elements), num_objects_fld),    \
			    offsetof(typeof(**elements), objects_fld),	      \
			    offsetof(typeof(***(*elements)->objects_fld), id),\
			    bucket)

static short find_max_element_ns_id(unsigned int num_elements,
				    const void **elements,
				    size_t num_offset,
				    size_t data_offset,
				    size_t id_offset)
{
	short max_ns = SHRT_MIN;
	const void *elem;
	int i, j;

	for_each_element(elem, i, j, elements, num_elements, num_offset,
			 data_offset) {
		u16 id = *(u16 *)(elem + id_offset);

		if (GET_NS_ID(id) > max_ns)
			max_ns = GET_NS_ID(id);
	}

	return max_ns;
}

static short find_max_element_id(unsigned int num_elements,
				 const void **elements,
				 size_t num_offset,
				 size_t data_offset,
				 size_t id_offset,
				 u16 bucket)
{
	short max_id = SHRT_MIN;
	const void *elem;
	int i, j;

	for_each_element(elem, i, j, elements, num_elements, num_offset,
			 data_offset) {
		u16 id = *(u16 *)(elem + id_offset);

		if (GET_NS_ID(id) == bucket &&
		    GET_ID(id) > max_id)
			max_id = GET_ID(id);
	}
	return max_id;
}

#define find_max_element_entry_id(num_elements, elements, num_objects_fld,   \
				  objects_fld, bucket)			      \
	find_max_element_id(num_elements, (const void **)(elements),	      \
			    offsetof(typeof(**elements), num_objects_fld),    \
			    offsetof(typeof(**elements), objects_fld),	      \
			    offsetof(typeof(***(*elements)->objects_fld), id),\
			    bucket)

#define find_max_element_ns_entry_id(num_elements, elements,		    \
				     num_objects_fld, objects_fld)	    \
	find_max_element_ns_id(num_elements, (const void **)(elements),	    \
			      offsetof(typeof(**elements), num_objects_fld),\
			      offsetof(typeof(**elements), objects_fld),    \
			      offsetof(typeof(***(*elements)->objects_fld), id))

/*
 * find_max_xxxx_ns_id gets a few elements. Each element is described by an id
 * which its upper bits represents a namespace. It finds the max namespace. This
 * could be used in order to know how many buckets do we need to allocate. If no
 * elements exist, SHRT_MIN is returned. Namespace represents here different
 * buckets. The common example is "common bucket" and "driver bucket".
 *
 * find_max_xxxx_id gets a few elements and a bucket. Each element is described
 * by an id which its upper bits represent a namespace. It returns the max id
 * which is contained in the same namespace defined in @bucket. This could be
 * used in order to know how many elements do we need to allocate in the bucket.
 * If no elements exist, SHRT_MIN is returned.
 */

#define find_max_object_id(num_trees, trees, bucket)			\
		find_max_element_entry_id(num_trees, trees, num_objects,\
					  objects, bucket)
#define find_max_object_ns_id(num_trees, trees)			\
		find_max_element_ns_entry_id(num_trees, trees,		\
					     num_objects, objects)

#define find_max_method_id(num_iters, iters, bucket)			\
		find_max_element_entry_id(num_iters, iters, num_methods,\
					  methods, bucket)
#define find_max_method_ns_id(num_iters, iters)			\
		find_max_element_ns_entry_id(num_iters, iters,		\
					     num_methods, methods)

#define find_max_attr_id(num_iters, iters, bucket)			\
		find_max_element_entry_id(num_iters, iters, num_attrs,  \
					  attrs, bucket)
#define find_max_attr_ns_id(num_iters, iters)				\
		find_max_element_ns_entry_id(num_iters, iters,		\
					     num_attrs, attrs)

static void free_method(struct uverbs_method_spec *method)
{
	unsigned int i;

	if (!method)
		return;

	for (i = 0; i < method->num_buckets; i++)
		kfree(method->attr_buckets[i]);

	kfree(method);
}

#define IS_ATTR_OBJECT(attr) ((attr)->type == UVERBS_ATTR_TYPE_IDR || \
			      (attr)->type == UVERBS_ATTR_TYPE_FD)

/*
 * This function gets array of size @num_method_defs which contains pointers to
 * method definitions @method_defs. The function allocates an
 * uverbs_method_spec structure and initializes its number of buckets and the
 * elements in buckets to the correct attributes. While doing that, it
 * validates that there aren't conflicts between attributes of different
 * method_defs.
 */
static struct uverbs_method_spec *build_method_with_attrs(const struct uverbs_method_def **method_defs,
							  size_t num_method_defs)
{
	int bucket_idx;
	int max_attr_buckets = 0;
	size_t num_attr_buckets = 0;
	int res = 0;
	struct uverbs_method_spec *method = NULL;
	const struct uverbs_attr_def **attr_defs;
	unsigned int num_of_singularities = 0;

	max_attr_buckets = find_max_attr_ns_id(num_method_defs, method_defs);
	if (max_attr_buckets >= 0)
		num_attr_buckets = max_attr_buckets + 1;

	method = kzalloc(sizeof(*method) +
			 num_attr_buckets * sizeof(*method->attr_buckets),
			 GFP_KERNEL);
	if (!method)
		return ERR_PTR(-ENOMEM);

	method->num_buckets = num_attr_buckets;
	attr_defs = kcalloc(num_method_defs, sizeof(*attr_defs), GFP_KERNEL);
	if (!attr_defs) {
		res = -ENOMEM;
		goto free_method;
	}
	for (bucket_idx = 0; bucket_idx < method->num_buckets; bucket_idx++) {
		short min_id = SHRT_MIN;
		int attr_max_bucket = 0;
		struct uverbs_attr_spec_hash *hash = NULL;

		attr_max_bucket = find_max_attr_id(num_method_defs, method_defs,
						   bucket_idx);
		if (attr_max_bucket < 0)
			continue;

		hash = kzalloc(sizeof(*hash) +
			       ALIGN(sizeof(*hash->attrs) * (attr_max_bucket + 1),
				     sizeof(long)) +
			       BITS_TO_LONGS(attr_max_bucket + 1) * sizeof(long),
			       GFP_KERNEL);
		if (!hash) {
			res = -ENOMEM;
			goto free;
		}
		hash->num_attrs = attr_max_bucket + 1;
		method->num_child_attrs += hash->num_attrs;
		hash->mandatory_attrs_bitmask = (void *)(hash + 1) +
						 ALIGN(sizeof(*hash->attrs) *
						       (attr_max_bucket + 1),
						       sizeof(long));

		method->attr_buckets[bucket_idx] = hash;

		do {
			size_t			 num_attr_defs;
			struct uverbs_attr_spec	*attr;
			bool attr_obj_with_special_access;

			num_attr_defs =
				get_attrs_above_id(attr_defs,
						   num_method_defs,
						   method_defs,
						   bucket_idx,
						   &min_id);
			/* Last attr in bucket */
			if (!num_attr_defs)
				break;

			if (num_attr_defs > 1) {
				/*
				 * We don't allow two attribute definitions for
				 * the same attribute. This is usually a
				 * programmer error. If required, it's better to
				 * just add a new attribute to capture the new
				 * semantics.
				 */
				res = -EEXIST;
				goto free;
			}

			attr = &hash->attrs[min_id];
			memcpy(attr, &attr_defs[0]->attr, sizeof(*attr));

			attr_obj_with_special_access = IS_ATTR_OBJECT(attr) &&
				   (attr->obj.access == UVERBS_ACCESS_NEW ||
				    attr->obj.access == UVERBS_ACCESS_DESTROY);
			num_of_singularities +=  !!attr_obj_with_special_access;
			if (WARN(num_of_singularities > 1,
				 "ib_uverbs: Method contains more than one object attr (%d) with new/destroy access\n",
				 min_id) ||
			    WARN(attr_obj_with_special_access &&
				 !(attr->flags & UVERBS_ATTR_SPEC_F_MANDATORY),
				 "ib_uverbs: Tried to merge attr (%d) but it's an object with new/destroy aceess but isn't mandatory\n",
				 min_id) ||
			    WARN(IS_ATTR_OBJECT(attr) &&
				 attr->flags & UVERBS_ATTR_SPEC_F_MIN_SZ,
				 "ib_uverbs: Tried to merge attr (%d) but it's an object with min_sz flag\n",
				 min_id)) {
				res = -EINVAL;
				goto free;
			}

			if (attr->flags & UVERBS_ATTR_SPEC_F_MANDATORY)
				set_bit(min_id, hash->mandatory_attrs_bitmask);
			min_id++;

		} while (1);
	}
	kfree(attr_defs);
	return method;

free:
	kfree(attr_defs);
free_method:
	free_method(method);
	return ERR_PTR(res);
}

static void free_object(struct uverbs_object_spec *object)
{
	unsigned int i, j;

	if (!object)
		return;

	for (i = 0; i < object->num_buckets; i++) {
		struct uverbs_method_spec_hash	*method_buckets =
			object->method_buckets[i];

		if (!method_buckets)
			continue;

		for (j = 0; j < method_buckets->num_methods; j++)
			free_method(method_buckets->methods[j]);

		kfree(method_buckets);
	}

	kfree(object);
}

/*
 * This function gets array of size @num_object_defs which contains pointers to
 * object definitions @object_defs. The function allocated an
 * uverbs_object_spec structure and initialize its number of buckets and the
 * elements in buckets to the correct methods. While doing that, it
 * sorts out the correct relationship between conflicts in the same method.
 */
static struct uverbs_object_spec *build_object_with_methods(const struct uverbs_object_def **object_defs,
							    size_t num_object_defs)
{
	u16 bucket_idx;
	int max_method_buckets = 0;
	u16 num_method_buckets = 0;
	int res = 0;
	struct uverbs_object_spec *object = NULL;
	const struct uverbs_method_def **method_defs;

	max_method_buckets = find_max_method_ns_id(num_object_defs, object_defs);
	if (max_method_buckets >= 0)
		num_method_buckets = max_method_buckets + 1;

	object = kzalloc(sizeof(*object) +
			 num_method_buckets *
			 sizeof(*object->method_buckets), GFP_KERNEL);
	if (!object)
		return ERR_PTR(-ENOMEM);

	object->num_buckets = num_method_buckets;
	method_defs = kcalloc(num_object_defs, sizeof(*method_defs), GFP_KERNEL);
	if (!method_defs) {
		res = -ENOMEM;
		goto free_object;
	}

	for (bucket_idx = 0; bucket_idx < object->num_buckets; bucket_idx++) {
		short min_id = SHRT_MIN;
		int methods_max_bucket = 0;
		struct uverbs_method_spec_hash *hash = NULL;

		methods_max_bucket = find_max_method_id(num_object_defs, object_defs,
							bucket_idx);
		if (methods_max_bucket < 0)
			continue;

		hash = kzalloc(sizeof(*hash) +
			       sizeof(*hash->methods) * (methods_max_bucket + 1),
			       GFP_KERNEL);
		if (!hash) {
			res = -ENOMEM;
			goto free;
		}

		hash->num_methods = methods_max_bucket + 1;
		object->method_buckets[bucket_idx] = hash;

		do {
			size_t				num_method_defs;
			struct uverbs_method_spec	*method;
			int i;

			num_method_defs =
				get_methods_above_id(method_defs,
						     num_object_defs,
						     object_defs,
						     bucket_idx,
						     &min_id);
			/* Last method in bucket */
			if (!num_method_defs)
				break;

			method = build_method_with_attrs(method_defs,
							 num_method_defs);
			if (IS_ERR(method)) {
				res = PTR_ERR(method);
				goto free;
			}

			/*
			 * The last tree which is given as an argument to the
			 * merge overrides previous method handler.
			 * Therefore, we iterate backwards and search for the
			 * first handler which != NULL. This also defines the
			 * set of flags used for this handler.
			 */
			for (i = num_method_defs - 1;
			     i >= 0 && !method_defs[i]->handler; i--)
				;
			hash->methods[min_id++] = method;
			/* NULL handler isn't allowed */
			if (WARN(i < 0,
				 "ib_uverbs: tried to merge function id %d, but all handlers are NULL\n",
				 min_id)) {
				res = -EINVAL;
				goto free;
			}
			method->handler = method_defs[i]->handler;
			method->flags = method_defs[i]->flags;

		} while (1);
	}
	kfree(method_defs);
	return object;

free:
	kfree(method_defs);
free_object:
	free_object(object);
	return ERR_PTR(res);
}

void uverbs_free_spec_tree(struct uverbs_root_spec *root)
{
	unsigned int i, j;

	if (!root)
		return;

	for (i = 0; i < root->num_buckets; i++) {
		struct uverbs_object_spec_hash *object_hash =
			root->object_buckets[i];

		if (!object_hash)
			continue;

		for (j = 0; j < object_hash->num_objects; j++)
			free_object(object_hash->objects[j]);

		kfree(object_hash);
	}

	kfree(root);
}
EXPORT_SYMBOL(uverbs_free_spec_tree);

struct uverbs_root_spec *uverbs_alloc_spec_tree(unsigned int num_trees,
						const struct uverbs_object_tree_def **trees)
{
	u16 bucket_idx;
	short max_object_buckets = 0;
	size_t num_objects_buckets = 0;
	struct uverbs_root_spec *root_spec = NULL;
	const struct uverbs_object_def **object_defs;
	int i;
	int res = 0;

	max_object_buckets = find_max_object_ns_id(num_trees, trees);
	/*
	 * Devices which don't want to support ib_uverbs, should just allocate
	 * an empty parsing tree. Every user-space command won't hit any valid
	 * entry in the parsing tree and thus will fail.
	 */
	if (max_object_buckets >= 0)
		num_objects_buckets = max_object_buckets + 1;

	root_spec = kzalloc(sizeof(*root_spec) +
			    num_objects_buckets * sizeof(*root_spec->object_buckets),
			    GFP_KERNEL);
	if (!root_spec)
		return ERR_PTR(-ENOMEM);
	root_spec->num_buckets = num_objects_buckets;

	object_defs = kcalloc(num_trees, sizeof(*object_defs),
			      GFP_KERNEL);
	if (!object_defs) {
		res = -ENOMEM;
		goto free_root;
	}

	for (bucket_idx = 0; bucket_idx < root_spec->num_buckets; bucket_idx++) {
		short min_id = SHRT_MIN;
		short objects_max_bucket;
		struct uverbs_object_spec_hash *hash = NULL;

		objects_max_bucket = find_max_object_id(num_trees, trees,
							bucket_idx);
		if (objects_max_bucket < 0)
			continue;

		hash = kzalloc(sizeof(*hash) +
			       sizeof(*hash->objects) * (objects_max_bucket + 1),
			       GFP_KERNEL);
		if (!hash) {
			res = -ENOMEM;
			goto free;
		}
		hash->num_objects = objects_max_bucket + 1;
		root_spec->object_buckets[bucket_idx] = hash;

		do {
			size_t				num_object_defs;
			struct uverbs_object_spec	*object;

			num_object_defs = get_objects_above_id(object_defs,
							       num_trees,
							       trees,
							       bucket_idx,
							       &min_id);
			/* Last object in bucket */
			if (!num_object_defs)
				break;

			object = build_object_with_methods(object_defs,
							   num_object_defs);
			if (IS_ERR(object)) {
				res = PTR_ERR(object);
				goto free;
			}

			/*
			 * The last tree which is given as an argument to the
			 * merge overrides previous object's type_attrs.
			 * Therefore, we iterate backwards and search for the
			 * first type_attrs which != NULL.
			 */
			for (i = num_object_defs - 1;
			     i >= 0 && !object_defs[i]->type_attrs; i--)
				;
			/*
			 * NULL is a valid type_attrs. It means an object we
			 * can't instantiate (like DEVICE).
			 */
			object->type_attrs = i < 0 ? NULL :
				object_defs[i]->type_attrs;

			hash->objects[min_id++] = object;
		} while (1);
	}

	kfree(object_defs);
	return root_spec;

free:
	kfree(object_defs);
free_root:
	uverbs_free_spec_tree(root_spec);
	return ERR_PTR(res);
}
EXPORT_SYMBOL(uverbs_alloc_spec_tree);
