// SPDX-License-Identifier: GPL-2.0
/*
 * Generic dynamic event control interface
 *
 * Copyright (C) 2018 Masami Hiramatsu <mhiramat@kernel.org>
 */

#include <linux/debugfs.h>
#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/mm.h>
#include <linux/mutex.h>
#include <linux/tracefs.h>

#include "trace.h"
#include "trace_dynevent.h"

static DEFINE_MUTEX(dyn_event_ops_mutex);
static LIST_HEAD(dyn_event_ops_list);

int dyn_event_register(struct dyn_event_operations *ops)
{
	if (!ops || !ops->create || !ops->show || !ops->is_busy ||
	    !ops->free || !ops->match)
		return -EINVAL;

	INIT_LIST_HEAD(&ops->list);
	mutex_lock(&dyn_event_ops_mutex);
	list_add_tail(&ops->list, &dyn_event_ops_list);
	mutex_unlock(&dyn_event_ops_mutex);
	return 0;
}

int dyn_event_release(int argc, char **argv, struct dyn_event_operations *type)
{
	struct dyn_event *pos, *n;
	char *system = NULL, *event, *p;
	int ret = -ENOENT;

	if (argv[0][0] == '-') {
		if (argv[0][1] != ':')
			return -EINVAL;
		event = &argv[0][2];
	} else {
		event = strchr(argv[0], ':');
		if (!event)
			return -EINVAL;
		event++;
	}
	argc--; argv++;

	p = strchr(event, '/');
	if (p) {
		system = event;
		event = p + 1;
		*p = '\0';
	}
	if (event[0] == '\0')
		return -EINVAL;

	mutex_lock(&event_mutex);
	for_each_dyn_event_safe(pos, n) {
		if (type && type != pos->ops)
			continue;
		if (!pos->ops->match(system, event,
				argc, (const char **)argv, pos))
			continue;

		ret = pos->ops->free(pos);
		if (ret)
			break;
	}
	mutex_unlock(&event_mutex);

	return ret;
}

static int create_dyn_event(int argc, char **argv)
{
	struct dyn_event_operations *ops;
	int ret = -ENODEV;

	if (argv[0][0] == '-' || argv[0][0] == '!')
		return dyn_event_release(argc, argv, NULL);

	mutex_lock(&dyn_event_ops_mutex);
	list_for_each_entry(ops, &dyn_event_ops_list, list) {
		ret = ops->create(argc, (const char **)argv);
		if (!ret || ret != -ECANCELED)
			break;
	}
	mutex_unlock(&dyn_event_ops_mutex);
	if (ret == -ECANCELED)
		ret = -EINVAL;

	return ret;
}

/* Protected by event_mutex */
LIST_HEAD(dyn_event_list);

void *dyn_event_seq_start(struct seq_file *m, loff_t *pos)
{
	mutex_lock(&event_mutex);
	return seq_list_start(&dyn_event_list, *pos);
}

void *dyn_event_seq_next(struct seq_file *m, void *v, loff_t *pos)
{
	return seq_list_next(v, &dyn_event_list, pos);
}

void dyn_event_seq_stop(struct seq_file *m, void *v)
{
	mutex_unlock(&event_mutex);
}

static int dyn_event_seq_show(struct seq_file *m, void *v)
{
	struct dyn_event *ev = v;

	if (ev && ev->ops)
		return ev->ops->show(m, ev);

	return 0;
}

static const struct seq_operations dyn_event_seq_op = {
	.start	= dyn_event_seq_start,
	.next	= dyn_event_seq_next,
	.stop	= dyn_event_seq_stop,
	.show	= dyn_event_seq_show
};

/*
 * dyn_events_release_all - Release all specific events
 * @type:	the dyn_event_operations * which filters releasing events
 *
 * This releases all events which ->ops matches @type. If @type is NULL,
 * all events are released.
 * Return -EBUSY if any of them are in use, and return other errors when
 * it failed to free the given event. Except for -EBUSY, event releasing
 * process will be aborted at that point and there may be some other
 * releasable events on the list.
 */
int dyn_events_release_all(struct dyn_event_operations *type)
{
	struct dyn_event *ev, *tmp;
	int ret = 0;

	mutex_lock(&event_mutex);
	for_each_dyn_event(ev) {
		if (type && ev->ops != type)
			continue;
		if (ev->ops->is_busy(ev)) {
			ret = -EBUSY;
			goto out;
		}
	}
	for_each_dyn_event_safe(ev, tmp) {
		if (type && ev->ops != type)
			continue;
		ret = ev->ops->free(ev);
		if (ret)
			break;
	}
out:
	mutex_unlock(&event_mutex);

	return ret;
}

static int dyn_event_open(struct inode *inode, struct file *file)
{
	int ret;

	ret = tracing_check_open_get_tr(NULL);
	if (ret)
		return ret;

	if ((file->f_mode & FMODE_WRITE) && (file->f_flags & O_TRUNC)) {
		ret = dyn_events_release_all(NULL);
		if (ret < 0)
			return ret;
	}

	return seq_open(file, &dyn_event_seq_op);
}

static ssize_t dyn_event_write(struct file *file, const char __user *buffer,
				size_t count, loff_t *ppos)
{
	return trace_parse_run_command(file, buffer, count, ppos,
				       create_dyn_event);
}

static const struct file_operations dynamic_events_ops = {
	.owner          = THIS_MODULE,
	.open           = dyn_event_open,
	.read           = seq_read,
	.llseek         = seq_lseek,
	.release        = seq_release,
	.write		= dyn_event_write,
};

/* Make a tracefs interface for controlling dynamic events */
static __init int init_dynamic_event(void)
{
	struct dentry *entry;
	int ret;

	ret = tracing_init_dentry();
	if (ret)
		return 0;

	entry = tracefs_create_file("dynamic_events", 0644, NULL,
				    NULL, &dynamic_events_ops);

	/* Event list interface */
	if (!entry)
		pr_warn("Could not create tracefs 'dynamic_events' entry\n");

	return 0;
}
fs_initcall(init_dynamic_event);

/**
 * dynevent_arg_add - Add an arg to a dynevent_cmd
 * @cmd: A pointer to the dynevent_cmd struct representing the new event cmd
 * @arg: The argument to append to the current cmd
 * @check_arg: An (optional) pointer to a function checking arg sanity
 *
 * Append an argument to a dynevent_cmd.  The argument string will be
 * appended to the current cmd string, followed by a separator, if
 * applicable.  Before the argument is added, the @check_arg function,
 * if present, will be used to check the sanity of the current arg
 * string.
 *
 * The cmd string and separator should be set using the
 * dynevent_arg_init() before any arguments are added using this
 * function.
 *
 * Return: 0 if successful, error otherwise.
 */
int dynevent_arg_add(struct dynevent_cmd *cmd,
		     struct dynevent_arg *arg,
		     dynevent_check_arg_fn_t check_arg)
{
	int ret = 0;

	if (check_arg) {
		ret = check_arg(arg);
		if (ret)
			return ret;
	}

	ret = seq_buf_printf(&cmd->seq, " %s%c", arg->str, arg->separator);
	if (ret) {
		pr_err("String is too long: %s%c\n", arg->str, arg->separator);
		return -E2BIG;
	}

	return ret;
}

/**
 * dynevent_arg_pair_add - Add an arg pair to a dynevent_cmd
 * @cmd: A pointer to the dynevent_cmd struct representing the new event cmd
 * @arg_pair: The argument pair to append to the current cmd
 * @check_arg: An (optional) pointer to a function checking arg sanity
 *
 * Append an argument pair to a dynevent_cmd.  An argument pair
 * consists of a left-hand-side argument and a right-hand-side
 * argument separated by an operator, which can be whitespace, all
 * followed by a separator, if applicable.  This can be used to add
 * arguments of the form 'type variable_name;' or 'x+y'.
 *
 * The lhs argument string will be appended to the current cmd string,
 * followed by an operator, if applicable, followd by the rhs string,
 * followed finally by a separator, if applicable.  Before the
 * argument is added, the @check_arg function, if present, will be
 * used to check the sanity of the current arg strings.
 *
 * The cmd strings, operator, and separator should be set using the
 * dynevent_arg_pair_init() before any arguments are added using this
 * function.
 *
 * Return: 0 if successful, error otherwise.
 */
int dynevent_arg_pair_add(struct dynevent_cmd *cmd,
			  struct dynevent_arg_pair *arg_pair,
			  dynevent_check_arg_fn_t check_arg)
{
	int ret = 0;

	if (check_arg) {
		ret = check_arg(arg_pair);
		if (ret)
			return ret;
	}

	ret = seq_buf_printf(&cmd->seq, " %s%c%s%c", arg_pair->lhs,
			     arg_pair->operator, arg_pair->rhs,
			     arg_pair->separator);
	if (ret) {
		pr_err("field string is too long: %s%c%s%c\n", arg_pair->lhs,
		       arg_pair->operator, arg_pair->rhs,
		       arg_pair->separator);
		return -E2BIG;
	}

	return ret;
}

/**
 * dynevent_str_add - Add a string to a dynevent_cmd
 * @cmd: A pointer to the dynevent_cmd struct representing the new event cmd
 * @str: The string to append to the current cmd
 *
 * Append a string to a dynevent_cmd.  The string will be appended to
 * the current cmd string as-is, with nothing prepended or appended.
 *
 * Return: 0 if successful, error otherwise.
 */
int dynevent_str_add(struct dynevent_cmd *cmd, const char *str)
{
	int ret = 0;

	ret = seq_buf_puts(&cmd->seq, str);
	if (ret) {
		pr_err("String is too long: %s\n", str);
		return -E2BIG;
	}

	return ret;
}

/**
 * dynevent_cmd_init - Initialize a dynevent_cmd object
 * @cmd: A pointer to the dynevent_cmd struct representing the cmd
 * @buf: A pointer to the buffer to generate the command into
 * @maxlen: The length of the buffer the command will be generated into
 * @type: The type of the cmd, checked against further operations
 * @run_command: The type-specific function that will actually run the command
 *
 * Initialize a dynevent_cmd.  A dynevent_cmd is used to build up and
 * run dynamic event creation commands, such as commands for creating
 * synthetic and kprobe events.  Before calling any of the functions
 * used to build the command, a dynevent_cmd object should be
 * instantiated and initialized using this function.
 *
 * The initialization sets things up by saving a pointer to the
 * user-supplied buffer and its length via the @buf and @maxlen
 * params, and by saving the cmd-specific @type and @run_command
 * params which are used to check subsequent dynevent_cmd operations
 * and actually run the command when complete.
 */
void dynevent_cmd_init(struct dynevent_cmd *cmd, char *buf, int maxlen,
		       enum dynevent_type type,
		       dynevent_create_fn_t run_command)
{
	memset(cmd, '\0', sizeof(*cmd));

	seq_buf_init(&cmd->seq, buf, maxlen);
	cmd->type = type;
	cmd->run_command = run_command;
}

/**
 * dynevent_arg_init - Initialize a dynevent_arg object
 * @arg: A pointer to the dynevent_arg struct representing the arg
 * @separator: An (optional) separator, appended after adding the arg
 *
 * Initialize a dynevent_arg object.  A dynevent_arg represents an
 * object used to append single arguments to the current command
 * string.  After the arg string is successfully appended to the
 * command string, the optional @separator is appended.  If no
 * separator was specified when initializing the arg, a space will be
 * appended.
 */
void dynevent_arg_init(struct dynevent_arg *arg,
		       char separator)
{
	memset(arg, '\0', sizeof(*arg));

	if (!separator)
		separator = ' ';
	arg->separator = separator;
}

/**
 * dynevent_arg_pair_init - Initialize a dynevent_arg_pair object
 * @arg_pair: A pointer to the dynevent_arg_pair struct representing the arg
 * @operator: An (optional) operator, appended after adding the first arg
 * @separator: An (optional) separator, appended after adding the second arg
 *
 * Initialize a dynevent_arg_pair object.  A dynevent_arg_pair
 * represents an object used to append argument pairs such as 'type
 * variable_name;' or 'x+y' to the current command string.  An
 * argument pair consists of a left-hand-side argument and a
 * right-hand-side argument separated by an operator, which can be
 * whitespace, all followed by a separator, if applicable.  After the
 * first arg string is successfully appended to the command string,
 * the optional @operator is appended, followed by the second arg and
 * optional @separator.  If no separator was specified when
 * initializing the arg, a space will be appended.
 */
void dynevent_arg_pair_init(struct dynevent_arg_pair *arg_pair,
			    char operator, char separator)
{
	memset(arg_pair, '\0', sizeof(*arg_pair));

	if (!operator)
		operator = ' ';
	arg_pair->operator = operator;

	if (!separator)
		separator = ' ';
	arg_pair->separator = separator;
}

/**
 * dynevent_create - Create the dynamic event contained in dynevent_cmd
 * @cmd: The dynevent_cmd object containing the dynamic event creation command
 *
 * Once a dynevent_cmd object has been successfully built up via the
 * dynevent_cmd_init(), dynevent_arg_add() and dynevent_arg_pair_add()
 * functions, this function runs the final command to actually create
 * the event.
 *
 * Return: 0 if the event was successfully created, error otherwise.
 */
int dynevent_create(struct dynevent_cmd *cmd)
{
	return cmd->run_command(cmd);
}
EXPORT_SYMBOL_GPL(dynevent_create);
