// SPDX-License-Identifier: GPL-2.0
/*
 * System Trace Module (STM) master/channel allocation policy management
 * Copyright (c) 2014, Intel Corporation.
 *
 * A master/channel allocation policy allows mapping string identifiers to
 * master and channel ranges, where allocation can be done.
 */

#define pr_fmt(fmt)	KBUILD_MODNAME ": " fmt

#include <linux/types.h>
#include <linux/module.h>
#include <linux/device.h>
#include <linux/configfs.h>
#include <linux/slab.h>
#include <linux/stm.h>
#include "stm.h"

/*
 * STP Master/Channel allocation policy configfs layout.
 */

struct stp_policy {
	struct config_group	group;
	struct stm_device	*stm;
};

struct stp_policy_node {
	struct config_group	group;
	struct stp_policy	*policy;
	unsigned int		first_master;
	unsigned int		last_master;
	unsigned int		first_channel;
	unsigned int		last_channel;
	/* this is the one that's exposed to the attributes */
	unsigned char		priv[];
};

void *stp_policy_node_priv(struct stp_policy_node *pn)
{
	if (!pn)
		return NULL;

	return pn->priv;
}

static struct configfs_subsystem stp_policy_subsys;

void stp_policy_node_get_ranges(struct stp_policy_node *policy_node,
				unsigned int *mstart, unsigned int *mend,
				unsigned int *cstart, unsigned int *cend)
{
	*mstart	= policy_node->first_master;
	*mend	= policy_node->last_master;
	*cstart	= policy_node->first_channel;
	*cend	= policy_node->last_channel;
}

static inline struct stp_policy *to_stp_policy(struct config_item *item)
{
	return item ?
		container_of(to_config_group(item), struct stp_policy, group) :
		NULL;
}

static inline struct stp_policy_node *
to_stp_policy_node(struct config_item *item)
{
	return item ?
		container_of(to_config_group(item), struct stp_policy_node,
			     group) :
		NULL;
}

void *to_pdrv_policy_node(struct config_item *item)
{
	struct stp_policy_node *node = to_stp_policy_node(item);

	return stp_policy_node_priv(node);
}
EXPORT_SYMBOL_GPL(to_pdrv_policy_node);

static ssize_t
stp_policy_node_masters_show(struct config_item *item, char *page)
{
	struct stp_policy_node *policy_node = to_stp_policy_node(item);
	ssize_t count;

	count = sprintf(page, "%u %u\n", policy_node->first_master,
			policy_node->last_master);

	return count;
}

static ssize_t
stp_policy_node_masters_store(struct config_item *item, const char *page,
			      size_t count)
{
	struct stp_policy_node *policy_node = to_stp_policy_node(item);
	unsigned int first, last;
	struct stm_device *stm;
	char *p = (char *)page;
	ssize_t ret = -ENODEV;

	if (sscanf(p, "%u %u", &first, &last) != 2)
		return -EINVAL;

	mutex_lock(&stp_policy_subsys.su_mutex);
	stm = policy_node->policy->stm;
	if (!stm)
		goto unlock;

	/* must be within [sw_start..sw_end], which is an inclusive range */
	if (first > last || first < stm->data->sw_start ||
	    last > stm->data->sw_end) {
		ret = -ERANGE;
		goto unlock;
	}

	ret = count;
	policy_node->first_master = first;
	policy_node->last_master = last;

unlock:
	mutex_unlock(&stp_policy_subsys.su_mutex);

	return ret;
}

static ssize_t
stp_policy_node_channels_show(struct config_item *item, char *page)
{
	struct stp_policy_node *policy_node = to_stp_policy_node(item);
	ssize_t count;

	count = sprintf(page, "%u %u\n", policy_node->first_channel,
			policy_node->last_channel);

	return count;
}

static ssize_t
stp_policy_node_channels_store(struct config_item *item, const char *page,
			       size_t count)
{
	struct stp_policy_node *policy_node = to_stp_policy_node(item);
	unsigned int first, last;
	struct stm_device *stm;
	char *p = (char *)page;
	ssize_t ret = -ENODEV;

	if (sscanf(p, "%u %u", &first, &last) != 2)
		return -EINVAL;

	mutex_lock(&stp_policy_subsys.su_mutex);
	stm = policy_node->policy->stm;
	if (!stm)
		goto unlock;

	if (first > INT_MAX || last > INT_MAX || first > last ||
	    last >= stm->data->sw_nchannels) {
		ret = -ERANGE;
		goto unlock;
	}

	ret = count;
	policy_node->first_channel = first;
	policy_node->last_channel = last;

unlock:
	mutex_unlock(&stp_policy_subsys.su_mutex);

	return ret;
}

static void stp_policy_node_release(struct config_item *item)
{
	struct stp_policy_node *node = to_stp_policy_node(item);

	kfree(node);
}

static struct configfs_item_operations stp_policy_node_item_ops = {
	.release		= stp_policy_node_release,
};

CONFIGFS_ATTR(stp_policy_node_, masters);
CONFIGFS_ATTR(stp_policy_node_, channels);

static struct configfs_attribute *stp_policy_node_attrs[] = {
	&stp_policy_node_attr_masters,
	&stp_policy_node_attr_channels,
	NULL,
};

static const struct config_item_type stp_policy_type;
static const struct config_item_type stp_policy_node_type;

const struct config_item_type *
get_policy_node_type(struct configfs_attribute **attrs)
{
	struct config_item_type *type;
	struct configfs_attribute **merged;

	type = kmemdup(&stp_policy_node_type, sizeof(stp_policy_node_type),
		       GFP_KERNEL);
	if (!type)
		return NULL;

	merged = memcat_p(stp_policy_node_attrs, attrs);
	if (!merged) {
		kfree(type);
		return NULL;
	}

	type->ct_attrs = merged;

	return type;
}

static struct config_group *
stp_policy_node_make(struct config_group *group, const char *name)
{
	const struct config_item_type *type = &stp_policy_node_type;
	struct stp_policy_node *policy_node, *parent_node;
	const struct stm_protocol_driver *pdrv;
	struct stp_policy *policy;

	if (group->cg_item.ci_type == &stp_policy_type) {
		policy = container_of(group, struct stp_policy, group);
	} else {
		parent_node = container_of(group, struct stp_policy_node,
					   group);
		policy = parent_node->policy;
	}

	if (!policy->stm)
		return ERR_PTR(-ENODEV);

	pdrv = policy->stm->pdrv;
	policy_node =
		kzalloc(offsetof(struct stp_policy_node, priv[pdrv->priv_sz]),
			GFP_KERNEL);
	if (!policy_node)
		return ERR_PTR(-ENOMEM);

	if (pdrv->policy_node_init)
		pdrv->policy_node_init((void *)policy_node->priv);

	if (policy->stm->pdrv_node_type)
		type = policy->stm->pdrv_node_type;

	config_group_init_type_name(&policy_node->group, name, type);

	policy_node->policy = policy;

	/* default values for the attributes */
	policy_node->first_master = policy->stm->data->sw_start;
	policy_node->last_master = policy->stm->data->sw_end;
	policy_node->first_channel = 0;
	policy_node->last_channel = policy->stm->data->sw_nchannels - 1;

	return &policy_node->group;
}

static void
stp_policy_node_drop(struct config_group *group, struct config_item *item)
{
	config_item_put(item);
}

static struct configfs_group_operations stp_policy_node_group_ops = {
	.make_group	= stp_policy_node_make,
	.drop_item	= stp_policy_node_drop,
};

static const struct config_item_type stp_policy_node_type = {
	.ct_item_ops	= &stp_policy_node_item_ops,
	.ct_group_ops	= &stp_policy_node_group_ops,
	.ct_attrs	= stp_policy_node_attrs,
	.ct_owner	= THIS_MODULE,
};

/*
 * Root group: policies.
 */
static ssize_t stp_policy_device_show(struct config_item *item,
				      char *page)
{
	struct stp_policy *policy = to_stp_policy(item);
	ssize_t count;

	count = sprintf(page, "%s\n",
			(policy && policy->stm) ?
			policy->stm->data->name :
			"<none>");

	return count;
}

CONFIGFS_ATTR_RO(stp_policy_, device);

static ssize_t stp_policy_protocol_show(struct config_item *item,
					char *page)
{
	struct stp_policy *policy = to_stp_policy(item);
	ssize_t count;

	count = sprintf(page, "%s\n",
			(policy && policy->stm) ?
			policy->stm->pdrv->name :
			"<none>");

	return count;
}

CONFIGFS_ATTR_RO(stp_policy_, protocol);

static struct configfs_attribute *stp_policy_attrs[] = {
	&stp_policy_attr_device,
	&stp_policy_attr_protocol,
	NULL,
};

void stp_policy_unbind(struct stp_policy *policy)
{
	struct stm_device *stm = policy->stm;

	/*
	 * stp_policy_release() will not call here if the policy is already
	 * unbound; other users should not either, as no link exists between
	 * this policy and anything else in that case
	 */
	if (WARN_ON_ONCE(!policy->stm))
		return;

	lockdep_assert_held(&stm->policy_mutex);

	stm->policy = NULL;
	policy->stm = NULL;

	/*
	 * Drop the reference on the protocol driver and lose the link.
	 */
	stm_put_protocol(stm->pdrv);
	stm->pdrv = NULL;
	stm_put_device(stm);
}

static void stp_policy_release(struct config_item *item)
{
	struct stp_policy *policy = to_stp_policy(item);
	struct stm_device *stm = policy->stm;

	/* a policy *can* be unbound and still exist in configfs tree */
	if (!stm)
		return;

	mutex_lock(&stm->policy_mutex);
	stp_policy_unbind(policy);
	mutex_unlock(&stm->policy_mutex);

	kfree(policy);
}

static struct configfs_item_operations stp_policy_item_ops = {
	.release		= stp_policy_release,
};

static struct configfs_group_operations stp_policy_group_ops = {
	.make_group	= stp_policy_node_make,
};

static const struct config_item_type stp_policy_type = {
	.ct_item_ops	= &stp_policy_item_ops,
	.ct_group_ops	= &stp_policy_group_ops,
	.ct_attrs	= stp_policy_attrs,
	.ct_owner	= THIS_MODULE,
};

static struct config_group *
stp_policy_make(struct config_group *group, const char *name)
{
	const struct config_item_type *pdrv_node_type;
	const struct stm_protocol_driver *pdrv;
	char *devname, *proto, *p;
	struct config_group *ret;
	struct stm_device *stm;
	int err;

	devname = kasprintf(GFP_KERNEL, "%s", name);
	if (!devname)
		return ERR_PTR(-ENOMEM);

	/*
	 * node must look like <device_name>.<policy_name>, where
	 * <device_name> is the name of an existing stm device; may
	 *               contain dots;
	 * <policy_name> is an arbitrary string; may not contain dots
	 * <device_name>:<protocol_name>.<policy_name>
	 */
	p = strrchr(devname, '.');
	if (!p) {
		kfree(devname);
		return ERR_PTR(-EINVAL);
	}

	*p = '\0';

	/*
	 * look for ":<protocol_name>":
	 *  + no protocol suffix: fall back to whatever is available;
	 *  + unknown protocol: fail the whole thing
	 */
	proto = strrchr(devname, ':');
	if (proto)
		*proto++ = '\0';

	stm = stm_find_device(devname);
	if (!stm) {
		kfree(devname);
		return ERR_PTR(-ENODEV);
	}

	err = stm_lookup_protocol(proto, &pdrv, &pdrv_node_type);
	kfree(devname);

	if (err) {
		stm_put_device(stm);
		return ERR_PTR(-ENODEV);
	}

	mutex_lock(&stm->policy_mutex);
	if (stm->policy) {
		ret = ERR_PTR(-EBUSY);
		goto unlock_policy;
	}

	stm->policy = kzalloc_obj(*stm->policy);
	if (!stm->policy) {
		ret = ERR_PTR(-ENOMEM);
		goto unlock_policy;
	}

	config_group_init_type_name(&stm->policy->group, name,
				    &stp_policy_type);

	stm->pdrv = pdrv;
	stm->pdrv_node_type = pdrv_node_type;
	stm->policy->stm = stm;
	ret = &stm->policy->group;

unlock_policy:
	mutex_unlock(&stm->policy_mutex);

	if (IS_ERR(ret)) {
		/*
		 * pdrv and stm->pdrv at this point can be quite different,
		 * and only one of them needs to be 'put'
		 */
		stm_put_protocol(pdrv);
		stm_put_device(stm);
	}

	return ret;
}

static struct configfs_group_operations stp_policy_root_group_ops = {
	.make_group	= stp_policy_make,
};

static const struct config_item_type stp_policy_root_type = {
	.ct_group_ops	= &stp_policy_root_group_ops,
	.ct_owner	= THIS_MODULE,
};

static struct configfs_subsystem stp_policy_subsys = {
	.su_group = {
		.cg_item = {
			.ci_namebuf	= "stp-policy",
			.ci_type	= &stp_policy_root_type,
		},
	},
};

/*
 * Lock the policy mutex from the outside
 */
static struct stp_policy_node *
__stp_policy_node_lookup(struct stp_policy *policy, char *s)
{
	struct stp_policy_node *policy_node, *ret = NULL;
	struct list_head *head = &policy->group.cg_children;
	struct config_item *item;
	char *start, *end = s;

	if (list_empty(head))
		return NULL;

next:
	for (;;) {
		start = strsep(&end, "/");
		if (!start)
			break;

		if (!*start)
			continue;

		list_for_each_entry(item, head, ci_entry) {
			policy_node = to_stp_policy_node(item);

			if (!strcmp(start,
				    policy_node->group.cg_item.ci_name)) {
				ret = policy_node;

				if (!end)
					goto out;

				head = &policy_node->group.cg_children;
				goto next;
			}
		}
		break;
	}

out:
	return ret;
}


struct stp_policy_node *
stp_policy_node_lookup(struct stm_device *stm, char *s)
{
	struct stp_policy_node *policy_node = NULL;

	mutex_lock(&stp_policy_subsys.su_mutex);

	mutex_lock(&stm->policy_mutex);
	if (stm->policy)
		policy_node = __stp_policy_node_lookup(stm->policy, s);
	mutex_unlock(&stm->policy_mutex);

	if (policy_node)
		config_item_get(&policy_node->group.cg_item);
	else
		mutex_unlock(&stp_policy_subsys.su_mutex);

	return policy_node;
}

void stp_policy_node_put(struct stp_policy_node *policy_node)
{
	lockdep_assert_held(&stp_policy_subsys.su_mutex);

	mutex_unlock(&stp_policy_subsys.su_mutex);
	config_item_put(&policy_node->group.cg_item);
}

int __init stp_configfs_init(void)
{
	config_group_init(&stp_policy_subsys.su_group);
	mutex_init(&stp_policy_subsys.su_mutex);
	return configfs_register_subsystem(&stp_policy_subsys);
}

void __exit stp_configfs_exit(void)
{
	configfs_unregister_subsystem(&stp_policy_subsys);
}
