// SPDX-License-Identifier: GPL-2.0
/*
 * Thunderbolt XDomain property support
 *
 * Copyright (C) 2017, Intel Corporation
 * Authors: Michael Jamet <michael.jamet@intel.com>
 *          Mika Westerberg <mika.westerberg@linux.intel.com>
 */

#include <linux/err.h>
#include <linux/overflow.h>
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/uuid.h>
#include <linux/thunderbolt.h>

struct tb_property_entry {
	u32 key_hi;
	u32 key_lo;
	u16 length;
	u8 reserved;
	u8 type;
	u32 value;
};

struct tb_property_rootdir_entry {
	u32 magic;
	u32 length;
	struct tb_property_entry entries[];
};

struct tb_property_dir_entry {
	u32 uuid[4];
	struct tb_property_entry entries[];
};

#define TB_PROPERTY_ROOTDIR_MAGIC	0x55584401
#define TB_PROPERTY_MAX_DEPTH		8

static struct tb_property_dir *__tb_property_parse_dir(const u32 *block,
	size_t block_len, unsigned int dir_offset, size_t dir_len,
	bool is_root, unsigned int depth);
static struct tb_property *tb_property_copy(const struct tb_property *property);

static inline void parse_dwdata(void *dst, const void *src, size_t dwords)
{
	be32_to_cpu_array(dst, src, dwords);
}

static inline void format_dwdata(void *dst, const void *src, size_t dwords)
{
	cpu_to_be32_array(dst, src, dwords);
}

static bool tb_property_entry_valid(const struct tb_property_entry *entry,
				  size_t block_len)
{
	u32 end;

	switch (entry->type) {
	case TB_PROPERTY_TYPE_DIRECTORY:
	case TB_PROPERTY_TYPE_DATA:
	case TB_PROPERTY_TYPE_TEXT:
		if (!entry->length)
			return false;
		if (entry->length > block_len)
			return false;
		if (check_add_overflow(entry->value, entry->length, &end) ||
		    end > block_len)
			return false;
		break;

	case TB_PROPERTY_TYPE_VALUE:
		if (entry->length != 1)
			return false;
		break;
	}

	return true;
}

static bool tb_property_key_valid(const char *key)
{
	return key && strlen(key) <= TB_PROPERTY_KEY_SIZE;
}

static struct tb_property *
tb_property_alloc(const char *key, enum tb_property_type type)
{
	struct tb_property *property;

	property = kzalloc_obj(*property);
	if (!property)
		return NULL;

	strcpy(property->key, key);
	property->type = type;
	INIT_LIST_HEAD(&property->list);

	return property;
}

static struct tb_property *tb_property_parse(const u32 *block, size_t block_len,
					const struct tb_property_entry *entry,
					unsigned int depth)
{
	char key[TB_PROPERTY_KEY_SIZE + 1];
	struct tb_property *property;
	struct tb_property_dir *dir;

	if (!tb_property_entry_valid(entry, block_len))
		return NULL;

	parse_dwdata(key, entry, 2);
	key[TB_PROPERTY_KEY_SIZE] = '\0';

	property = tb_property_alloc(key, entry->type);
	if (!property)
		return NULL;

	property->length = entry->length;

	switch (property->type) {
	case TB_PROPERTY_TYPE_DIRECTORY:
		dir = __tb_property_parse_dir(block, block_len, entry->value,
					      entry->length, false, depth + 1);
		if (!dir) {
			kfree(property);
			return NULL;
		}
		property->value.dir = dir;
		break;

	case TB_PROPERTY_TYPE_DATA:
		property->value.data = kcalloc(property->length, sizeof(u32),
					       GFP_KERNEL);
		if (!property->value.data) {
			kfree(property);
			return NULL;
		}
		parse_dwdata(property->value.data, block + entry->value,
			     entry->length);
		break;

	case TB_PROPERTY_TYPE_TEXT:
		property->value.text = kcalloc(property->length, sizeof(u32),
					       GFP_KERNEL);
		if (!property->value.text) {
			kfree(property);
			return NULL;
		}
		parse_dwdata(property->value.text, block + entry->value,
			     entry->length);
		/* Force null termination */
		property->value.text[property->length * 4 - 1] = '\0';
		break;

	case TB_PROPERTY_TYPE_VALUE:
		property->value.immediate = entry->value;
		break;

	default:
		property->type = TB_PROPERTY_TYPE_UNKNOWN;
		break;
	}

	return property;
}

static struct tb_property_dir *__tb_property_parse_dir(const u32 *block,
	size_t block_len, unsigned int dir_offset, size_t dir_len, bool is_root,
	unsigned int depth)
{
	const struct tb_property_entry *entries;
	size_t i, content_len, nentries;
	unsigned int content_offset;
	struct tb_property_dir *dir;

	if (depth > TB_PROPERTY_MAX_DEPTH)
		return NULL;

	dir = kzalloc_obj(*dir);
	if (!dir)
		return NULL;

	INIT_LIST_HEAD(&dir->properties);

	if (is_root) {
		content_offset = dir_offset + 2;
		content_len = dir_len;
		if (content_offset + content_len > block_len) {
			tb_property_free_dir(dir);
			return NULL;
		}
	} else {
		if (dir_len < 4) {
			tb_property_free_dir(dir);
			return NULL;
		}
		dir->uuid = kmemdup(&block[dir_offset], sizeof(*dir->uuid),
				    GFP_KERNEL);
		if (!dir->uuid) {
			tb_property_free_dir(dir);
			return NULL;
		}
		content_offset = dir_offset + 4;
		content_len = dir_len - 4; /* Length includes UUID */
	}

	entries = (const struct tb_property_entry *)&block[content_offset];
	nentries = content_len / (sizeof(*entries) / 4);

	for (i = 0; i < nentries; i++) {
		struct tb_property *property;

		property = tb_property_parse(block, block_len, &entries[i], depth);
		if (!property) {
			tb_property_free_dir(dir);
			return NULL;
		}

		list_add_tail(&property->list, &dir->properties);
	}

	return dir;
}

/**
 * tb_property_parse_dir() - Parses properties from given property block
 * @block: Property block to parse
 * @block_len: Number of dword elements in the property block
 *
 * This function parses the XDomain properties data block into format that
 * can be traversed using the helper functions provided by this module.
 *
 * The resulting &struct tb_property_dir needs to be released by
 * calling tb_property_free_dir() when not needed anymore.
 *
 * The @block is expected to be root directory.
 *
 * Return: Pointer to &struct tb_property_dir, %NULL in case of failure.
 */
struct tb_property_dir *tb_property_parse_dir(const u32 *block,
					      size_t block_len)
{
	const struct tb_property_rootdir_entry *rootdir =
		(const struct tb_property_rootdir_entry *)block;

	if (rootdir->magic != TB_PROPERTY_ROOTDIR_MAGIC)
		return NULL;
	if (rootdir->length > block_len)
		return NULL;

	return __tb_property_parse_dir(block, block_len, 0, rootdir->length,
				       true, 0);
}

/**
 * tb_property_create_dir() - Creates new property directory
 * @uuid: UUID used to identify the particular directory
 *
 * Creates new, empty property directory. If @uuid is %NULL then the
 * directory is assumed to be root directory.
 *
 * Return: Pointer to &struct tb_property_dir, %NULL in case of failure.
 */
struct tb_property_dir *tb_property_create_dir(const uuid_t *uuid)
{
	struct tb_property_dir *dir;

	dir = kzalloc_obj(*dir);
	if (!dir)
		return NULL;

	INIT_LIST_HEAD(&dir->properties);
	if (uuid) {
		dir->uuid = kmemdup(uuid, sizeof(*dir->uuid), GFP_KERNEL);
		if (!dir->uuid) {
			kfree(dir);
			return NULL;
		}
	}

	return dir;
}
EXPORT_SYMBOL_GPL(tb_property_create_dir);

static void tb_property_free(struct tb_property *property)
{
	switch (property->type) {
	case TB_PROPERTY_TYPE_DIRECTORY:
		tb_property_free_dir(property->value.dir);
		break;

	case TB_PROPERTY_TYPE_DATA:
		kfree(property->value.data);
		break;

	case TB_PROPERTY_TYPE_TEXT:
		kfree(property->value.text);
		break;

	default:
		break;
	}

	kfree(property);
}

/**
 * tb_property_free_dir() - Release memory allocated for property directory
 * @dir: Directory to release
 *
 * This will release all the memory the directory occupies including all
 * descendants. It is OK to pass %NULL @dir, then the function does
 * nothing.
 */
void tb_property_free_dir(struct tb_property_dir *dir)
{
	struct tb_property *property, *tmp;

	if (!dir)
		return;

	list_for_each_entry_safe(property, tmp, &dir->properties, list) {
		list_del(&property->list);
		tb_property_free(property);
	}
	kfree(dir->uuid);
	kfree(dir);
}
EXPORT_SYMBOL_GPL(tb_property_free_dir);

static size_t tb_property_dir_length(const struct tb_property_dir *dir,
				     bool recurse, size_t *data_len)
{
	const struct tb_property *property;
	size_t len = 0;

	if (dir->uuid)
		len += sizeof(*dir->uuid) / 4;
	else
		len += sizeof(struct tb_property_rootdir_entry) / 4;

	list_for_each_entry(property, &dir->properties, list) {
		len += sizeof(struct tb_property_entry) / 4;

		switch (property->type) {
		case TB_PROPERTY_TYPE_DIRECTORY:
			if (recurse) {
				len += tb_property_dir_length(
					property->value.dir, recurse, data_len);
			}
			/* Reserve dword padding after each directory */
			if (data_len)
				*data_len += 1;
			break;

		case TB_PROPERTY_TYPE_DATA:
		case TB_PROPERTY_TYPE_TEXT:
			if (data_len)
				*data_len += property->length;
			break;

		default:
			break;
		}
	}

	return len;
}

static ssize_t __tb_property_format_dir(const struct tb_property_dir *dir,
	u32 *block, unsigned int start_offset, size_t block_len)
{
	unsigned int data_offset, dir_end;
	const struct tb_property *property;
	struct tb_property_entry *entry;
	size_t dir_len, data_len = 0;
	int ret;

	/*
	 * The structure of property block looks like following. Leaf
	 * data/text is included right after the directory and each
	 * directory follows each other (even nested ones).
	 *
	 * +----------+ <-- start_offset
	 * |  header  | <-- root directory header
	 * +----------+ ---
	 * |  entry 0 | -^--------------------.
	 * +----------+  |                    |
	 * |  entry 1 | -|--------------------|--.
	 * +----------+  |                    |  |
	 * |  entry 2 | -|-----------------.  |  |
	 * +----------+  |                 |  |  |
	 * :          :  |  dir_len        |  |  |
	 * .          .  |                 |  |  |
	 * :          :  |                 |  |  |
	 * +----------+  |                 |  |  |
	 * |  entry n |  v                 |  |  |
	 * +----------+ <-- data_offset    |  |  |
	 * |  data 0  | <------------------|--'  |
	 * +----------+                    |     |
	 * |  data 1  | <------------------|-----'
	 * +----------+                    |
	 * | 00000000 | padding            |
	 * +----------+ <-- dir_end <------'
	 * |   UUID   | <-- directory UUID (child directory)
	 * +----------+
	 * |  entry 0 |
	 * +----------+
	 * |  entry 1 |
	 * +----------+
	 * :          :
	 * .          .
	 * :          :
	 * +----------+
	 * |  entry n |
	 * +----------+
	 * |  data 0  |
	 * +----------+
	 *
	 * We use dir_end to hold pointer to the end of the directory. It
	 * will increase as we add directories and each directory should be
	 * added starting from previous dir_end.
	 */
	dir_len = tb_property_dir_length(dir, false, &data_len);
	data_offset = start_offset + dir_len;
	dir_end = start_offset + data_len + dir_len;

	if (data_offset > dir_end)
		return -EINVAL;
	if (dir_end > block_len)
		return -EINVAL;

	/* Write headers first */
	if (dir->uuid) {
		struct tb_property_dir_entry *pe;

		pe = (struct tb_property_dir_entry *)&block[start_offset];
		memcpy(pe->uuid, dir->uuid, sizeof(pe->uuid));
		entry = pe->entries;
	} else {
		struct tb_property_rootdir_entry *re;

		re = (struct tb_property_rootdir_entry *)&block[start_offset];
		re->magic = TB_PROPERTY_ROOTDIR_MAGIC;
		re->length = dir_len - sizeof(*re) / 4;
		entry = re->entries;
	}

	list_for_each_entry(property, &dir->properties, list) {
		const struct tb_property_dir *child;

		format_dwdata(entry, property->key, 2);
		entry->type = property->type;

		switch (property->type) {
		case TB_PROPERTY_TYPE_DIRECTORY:
			child = property->value.dir;
			ret = __tb_property_format_dir(child, block, dir_end,
						       block_len);
			if (ret < 0)
				return ret;
			entry->length = tb_property_dir_length(child, false,
							       NULL);
			entry->value = dir_end;
			dir_end = ret;
			break;

		case TB_PROPERTY_TYPE_DATA:
			format_dwdata(&block[data_offset], property->value.data,
				      property->length);
			entry->length = property->length;
			entry->value = data_offset;
			data_offset += entry->length;
			break;

		case TB_PROPERTY_TYPE_TEXT:
			format_dwdata(&block[data_offset], property->value.text,
				      property->length);
			entry->length = property->length;
			entry->value = data_offset;
			data_offset += entry->length;
			break;

		case TB_PROPERTY_TYPE_VALUE:
			entry->length = property->length;
			entry->value = property->value.immediate;
			break;

		default:
			break;
		}

		entry++;
	}

	return dir_end;
}

/**
 * tb_property_format_dir() - Formats directory to the packed XDomain format
 * @dir: Directory to format
 * @block: Property block where the packed data is placed
 * @block_len: Length of the property block
 *
 * This function formats the directory to the packed format that can be
 * then sent over the thunderbolt fabric to receiving host.
 *
 * Passing %NULL in @block returns number of entries the block takes.
 *
 * Return: %0 on success, negative errno otherwise.
 */
ssize_t tb_property_format_dir(const struct tb_property_dir *dir, u32 *block,
			       size_t block_len)
{
	ssize_t ret;

	if (!block) {
		size_t dir_len, data_len = 0;

		dir_len = tb_property_dir_length(dir, true, &data_len);
		return dir_len + data_len;
	}

	ret = __tb_property_format_dir(dir, block, 0, block_len);
	return ret < 0 ? ret : 0;
}

static struct tb_property_dir *copy_dir(const struct tb_property_dir *dir)
{
	struct tb_property *property, *p;
	struct tb_property_dir *d;

	if (!dir)
		return NULL;

	d = tb_property_create_dir(dir->uuid);
	if (!d)
		return NULL;

	list_for_each_entry(property, &dir->properties, list) {
		p = tb_property_copy(property);
		if (!p)
			goto err_free;
		list_add_tail(&p->list, &d->properties);
	}

	return d;

err_free:
	tb_property_free_dir(d);
	return NULL;
}

static struct tb_property *tb_property_copy(const struct tb_property *property)
{
	struct tb_property *p;

	p = tb_property_alloc(property->key, property->type);
	if (!p)
		return NULL;

	p->length = property->length;
	switch (property->type) {
	case TB_PROPERTY_TYPE_DIRECTORY:
		p->value.dir = copy_dir(property->value.dir);
		if (!p->value.dir)
			goto err_free;
		break;

	case TB_PROPERTY_TYPE_DATA:
		p->value.data = kmemdup(property->value.data,
					property->length * 4,
					GFP_KERNEL);
		if (!p->value.data)
			goto err_free;
		break;

	case TB_PROPERTY_TYPE_TEXT:
		p->value.text = kzalloc(p->length * 4, GFP_KERNEL);
		if (!p->value.text)
			goto err_free;
		strcpy(p->value.text, property->value.text);
		break;

	case TB_PROPERTY_TYPE_VALUE:
		p->value.immediate = property->value.immediate;
		break;

	default:
		break;
	}

	return p;

err_free:
	kfree(p);
	return NULL;
}

/**
 * tb_property_copy_dir() - Take a deep copy of directory
 * @dir: Directory to copy
 *
 * The resulting directory needs to be released by calling tb_property_free_dir().
 *
 * Return: Pointer to &struct tb_property_dir, %NULL in case of failure.
 */
struct tb_property_dir *tb_property_copy_dir(const struct tb_property_dir *dir)
{
	return copy_dir(dir);
}
EXPORT_SYMBOL_GPL(tb_property_copy_dir);

/**
 * tb_property_merge_dir() - Merges directory into parent
 * @parent: Directory to merge @dir
 * @dir: Directory that is merged
 * @replace: Replace existing entries
 *
 * This will merge @dir into @parent. Both must have same UUID. The
 * properties in @dir will overwrite overlapping properties in @parent
 * if @replace is %true. Contents of @dir is copied (so if it is not
 * needed afterwards it needs to relesed by calling tb_property_free_dir()).
 */
int tb_property_merge_dir(struct tb_property_dir *parent,
			  const struct tb_property_dir *dir,
			  bool replace)
{
	const struct tb_property *property;

	if (WARN_ON(parent == dir))
		return -EINVAL;

	if (!uuid_equal(parent->uuid, dir->uuid))
		return -EINVAL;

	list_for_each_entry(property, &dir->properties, list) {
		struct tb_property *p, *tmp;

		tmp = tb_property_copy(property);
		if (!tmp)
			return -ENOMEM;

		p = tb_property_find(parent, property->key, property->type);
		if (p) {
			if (replace) {
				/*
				 * Found existing property in parent so
				 * replace with the new one.
				 */
				list_replace(&p->list, &tmp->list);
				tb_property_free(p);
			} else {
				tb_property_free(tmp);
				continue;
			}
		} else {
			list_add_tail(&tmp->list, &parent->properties);
		}
	}

	return 0;
}
EXPORT_SYMBOL_GPL(tb_property_merge_dir);

/**
 * tb_property_add_immediate() - Add immediate property to directory
 * @parent: Directory to add the property
 * @key: Key for the property
 * @value: Immediate value to store with the property
 *
 * Return: %0 on success, negative errno otherwise.
 */
int tb_property_add_immediate(struct tb_property_dir *parent, const char *key,
			      u32 value)
{
	struct tb_property *property;

	if (!tb_property_key_valid(key))
		return -EINVAL;

	property = tb_property_alloc(key, TB_PROPERTY_TYPE_VALUE);
	if (!property)
		return -ENOMEM;

	property->length = 1;
	property->value.immediate = value;

	list_add_tail(&property->list, &parent->properties);
	return 0;
}
EXPORT_SYMBOL_GPL(tb_property_add_immediate);

/**
 * tb_property_add_data() - Adds arbitrary data property to directory
 * @parent: Directory to add the property
 * @key: Key for the property
 * @buf: Data buffer to add
 * @buflen: Number of bytes in the data buffer
 *
 * Function takes a copy of @buf and adds it to the directory.
 *
 * Return: %0 on success, negative errno otherwise.
 */
int tb_property_add_data(struct tb_property_dir *parent, const char *key,
			 const void *buf, size_t buflen)
{
	/* Need to pad to dword boundary */
	size_t size = round_up(buflen, 4);
	struct tb_property *property;

	if (!tb_property_key_valid(key))
		return -EINVAL;

	property = tb_property_alloc(key, TB_PROPERTY_TYPE_DATA);
	if (!property)
		return -ENOMEM;

	property->length = size / 4;
	property->value.data = kzalloc(size, GFP_KERNEL);
	if (!property->value.data) {
		kfree(property);
		return -ENOMEM;
	}

	memcpy(property->value.data, buf, buflen);

	list_add_tail(&property->list, &parent->properties);
	return 0;
}
EXPORT_SYMBOL_GPL(tb_property_add_data);

/**
 * tb_property_add_text() - Adds string property to directory
 * @parent: Directory to add the property
 * @key: Key for the property
 * @text: String to add
 *
 * Function takes a copy of @text and adds it to the directory.
 *
 * Return: %0 on success, negative errno otherwise.
 */
int tb_property_add_text(struct tb_property_dir *parent, const char *key,
			 const char *text)
{
	/* Need to pad to dword boundary */
	size_t size = round_up(strlen(text) + 1, 4);
	struct tb_property *property;

	if (!tb_property_key_valid(key))
		return -EINVAL;

	property = tb_property_alloc(key, TB_PROPERTY_TYPE_TEXT);
	if (!property)
		return -ENOMEM;

	property->length = size / 4;
	property->value.text = kzalloc(size, GFP_KERNEL);
	if (!property->value.text) {
		kfree(property);
		return -ENOMEM;
	}

	strcpy(property->value.text, text);

	list_add_tail(&property->list, &parent->properties);
	return 0;
}
EXPORT_SYMBOL_GPL(tb_property_add_text);

/**
 * tb_property_add_dir() - Adds a directory to the parent directory
 * @parent: Directory to add the property
 * @key: Key for the property
 * @dir: Directory to add
 *
 * Return: %0 on success, negative errno otherwise.
 */
int tb_property_add_dir(struct tb_property_dir *parent, const char *key,
			struct tb_property_dir *dir)
{
	struct tb_property *property;

	if (!tb_property_key_valid(key))
		return -EINVAL;

	property = tb_property_alloc(key, TB_PROPERTY_TYPE_DIRECTORY);
	if (!property)
		return -ENOMEM;

	property->value.dir = dir;

	list_add_tail(&property->list, &parent->properties);
	return 0;
}
EXPORT_SYMBOL_GPL(tb_property_add_dir);

/**
 * tb_property_remove() - Removes property from a parent directory
 * @property: Property to remove
 *
 * Note memory for @property is released as well so it is not allowed to
 * touch the object after call to this function.
 */
void tb_property_remove(struct tb_property *property)
{
	list_del(&property->list);
	kfree(property);
}
EXPORT_SYMBOL_GPL(tb_property_remove);

/**
 * tb_property_find() - Find a property from a directory
 * @dir: Directory where the property is searched
 * @key: Key to look for
 * @type: Type of the property
 *
 * Finds and returns property from the given directory. Does not
 * recurse into sub-directories.
 *
 * Return: Pointer to &struct tb_property, %NULL if the property was not found.
 */
struct tb_property *tb_property_find(struct tb_property_dir *dir,
	const char *key, enum tb_property_type type)
{
	struct tb_property *property;

	list_for_each_entry(property, &dir->properties, list) {
		if (property->type == type && !strcmp(property->key, key))
			return property;
	}

	return NULL;
}
EXPORT_SYMBOL_GPL(tb_property_find);

/**
 * tb_property_get_next() - Get next property from directory
 * @dir: Directory holding properties
 * @prev: Previous property in the directory (%NULL returns the first)
 *
 * Return: Pointer to &struct tb_property, %NULL if property was not found.
 */
struct tb_property *tb_property_get_next(struct tb_property_dir *dir,
					 struct tb_property *prev)
{
	if (prev) {
		if (list_is_last(&prev->list, &dir->properties))
			return NULL;
		return list_next_entry(prev, list);
	}
	return list_first_entry_or_null(&dir->properties, struct tb_property,
					list);
}
EXPORT_SYMBOL_GPL(tb_property_get_next);
