// SPDX-License-Identifier: GPL-2.0
/*
 * fprobe - Simple ftrace probe wrapper for function entry.
 */
#define pr_fmt(fmt) "fprobe: " fmt

#include <linux/cleanup.h>
#include <linux/err.h>
#include <linux/fprobe.h>
#include <linux/kallsyms.h>
#include <linux/kprobes.h>
#include <linux/list.h>
#include <linux/mutex.h>
#include <linux/rhashtable.h>
#include <linux/slab.h>
#include <linux/sort.h>

#include <asm/fprobe.h>

#include "trace.h"

#define FPROBE_IP_HASH_BITS 8
#define FPROBE_IP_TABLE_SIZE (1 << FPROBE_IP_HASH_BITS)

#define FPROBE_HASH_BITS 6
#define FPROBE_TABLE_SIZE (1 << FPROBE_HASH_BITS)

#define SIZE_IN_LONG(x) ((x + sizeof(long) - 1) >> (sizeof(long) == 8 ? 3 : 2))

/*
 * fprobe_table: hold 'fprobe_hlist::hlist' for checking the fprobe still
 *   exists. The key is the address of fprobe instance.
 * fprobe_ip_table: hold 'fprobe_hlist::array[*]' for searching the fprobe
 *   instance related to the function address. The key is the ftrace IP
 *   address.
 *
 * When unregistering the fprobe, fprobe_hlist::fp and fprobe_hlist::array[*].fp
 * are set NULL and delete those from both hash tables (by hlist_del_rcu).
 * After an RCU grace period, the fprobe_hlist itself will be released.
 *
 * fprobe_table and fprobe_ip_table can be accessed from either
 *  - Normal hlist traversal and RCU add/del under 'fprobe_mutex' is held.
 *  - RCU hlist traversal under disabling preempt
 */
static struct hlist_head fprobe_table[FPROBE_TABLE_SIZE];
static struct rhltable fprobe_ip_table;
static DEFINE_MUTEX(fprobe_mutex);
static struct fgraph_ops fprobe_graph_ops;

static u32 fprobe_node_hashfn(const void *data, u32 len, u32 seed)
{
	return hash_ptr(*(unsigned long **)data, 32);
}

static int fprobe_node_cmp(struct rhashtable_compare_arg *arg,
			   const void *ptr)
{
	unsigned long key = *(unsigned long *)arg->key;
	const struct fprobe_hlist_node *n = ptr;

	return n->addr != key;
}

static u32 fprobe_node_obj_hashfn(const void *data, u32 len, u32 seed)
{
	const struct fprobe_hlist_node *n = data;

	return hash_ptr((void *)n->addr, 32);
}

static const struct rhashtable_params fprobe_rht_params = {
	.head_offset		= offsetof(struct fprobe_hlist_node, hlist),
	.key_offset		= offsetof(struct fprobe_hlist_node, addr),
	.key_len		= sizeof_field(struct fprobe_hlist_node, addr),
	.hashfn			= fprobe_node_hashfn,
	.obj_hashfn		= fprobe_node_obj_hashfn,
	.obj_cmpfn		= fprobe_node_cmp,
	.automatic_shrinking	= true,
};

/* Node insertion and deletion requires the fprobe_mutex */
static int __insert_fprobe_node(struct fprobe_hlist_node *node, struct fprobe *fp)
{
	int ret;

	lockdep_assert_held(&fprobe_mutex);

	ret = rhltable_insert(&fprobe_ip_table, &node->hlist, fprobe_rht_params);
	/* Set the fprobe pointer if insertion was successful. */
	if (!ret)
		WRITE_ONCE(node->fp, fp);
	return ret;
}

static void __delete_fprobe_node(struct fprobe_hlist_node *node)
{
	lockdep_assert_held(&fprobe_mutex);

	/* Avoid double deleting and non-inserted nodes */
	if (READ_ONCE(node->fp) != NULL) {
		WRITE_ONCE(node->fp, NULL);
		rhltable_remove(&fprobe_ip_table, &node->hlist,
				fprobe_rht_params);
	}
}

/* Check existence of the fprobe */
static bool fprobe_registered(struct fprobe *fp)
{
	struct hlist_head *head;
	struct fprobe_hlist *fph;

	head = &fprobe_table[hash_ptr(fp, FPROBE_HASH_BITS)];
	hlist_for_each_entry_rcu(fph, head, hlist,
				 lockdep_is_held(&fprobe_mutex)) {
		if (fph->fp == fp)
			return true;
	}
	return false;
}
NOKPROBE_SYMBOL(fprobe_registered);

static int add_fprobe_hash(struct fprobe *fp)
{
	struct fprobe_hlist *fph = fp->hlist_array;
	struct hlist_head *head;

	lockdep_assert_held(&fprobe_mutex);

	if (WARN_ON_ONCE(!fph))
		return -EINVAL;

	head = &fprobe_table[hash_ptr(fp, FPROBE_HASH_BITS)];
	hlist_add_head_rcu(&fp->hlist_array->hlist, head);
	return 0;
}

static int del_fprobe_hash(struct fprobe *fp)
{
	struct fprobe_hlist *fph = fp->hlist_array;

	lockdep_assert_held(&fprobe_mutex);

	if (WARN_ON_ONCE(!fph))
		return -EINVAL;

	if (!fprobe_registered(fp))
		return -ENOENT;

	fph->fp = NULL;
	hlist_del_rcu(&fph->hlist);
	return 0;
}

#ifdef ARCH_DEFINE_ENCODE_FPROBE_HEADER

/* The arch should encode fprobe_header info into one unsigned long */
#define FPROBE_HEADER_SIZE_IN_LONG	1

static inline bool write_fprobe_header(unsigned long *stack,
					struct fprobe *fp, unsigned int size_words)
{
	if (WARN_ON_ONCE(size_words > MAX_FPROBE_DATA_SIZE_WORD ||
			 !arch_fprobe_header_encodable(fp)))
		return false;

	*stack = arch_encode_fprobe_header(fp, size_words);
	return true;
}

static inline void read_fprobe_header(unsigned long *stack,
					struct fprobe **fp, unsigned int *size_words)
{
	*fp = arch_decode_fprobe_header_fp(*stack);
	*size_words = arch_decode_fprobe_header_size(*stack);
}

#else

/* Generic fprobe_header */
struct __fprobe_header {
	struct fprobe *fp;
	unsigned long size_words;
};

#define FPROBE_HEADER_SIZE_IN_LONG	SIZE_IN_LONG(sizeof(struct __fprobe_header))

static inline bool write_fprobe_header(unsigned long *stack,
					struct fprobe *fp, unsigned int size_words)
{
	struct __fprobe_header *fph = (struct __fprobe_header *)stack;

	if (WARN_ON_ONCE(size_words > MAX_FPROBE_DATA_SIZE_WORD))
		return false;

	fph->fp = fp;
	fph->size_words = size_words;
	return true;
}

static inline void read_fprobe_header(unsigned long *stack,
					struct fprobe **fp, unsigned int *size_words)
{
	struct __fprobe_header *fph = (struct __fprobe_header *)stack;

	*fp = fph->fp;
	*size_words = fph->size_words;
}

#endif

/*
 * fprobe shadow stack management:
 * Since fprobe shares a single fgraph_ops, it needs to share the stack entry
 * among the probes on the same function exit. Note that a new probe can be
 * registered before a target function is returning, we can not use the hash
 * table to find the corresponding probes. Thus the probe address is stored on
 * the shadow stack with its entry data size.
 *
 */
static inline int __fprobe_handler(unsigned long ip, unsigned long parent_ip,
				   struct fprobe *fp, struct ftrace_regs *fregs,
				   void *data)
{
	if (!fp->entry_handler)
		return 0;

	return fp->entry_handler(fp, ip, parent_ip, fregs, data);
}

static inline int __fprobe_kprobe_handler(unsigned long ip, unsigned long parent_ip,
					  struct fprobe *fp, struct ftrace_regs *fregs,
					  void *data)
{
	int ret;
	/*
	 * This user handler is shared with other kprobes and is not expected to be
	 * called recursively. So if any other kprobe handler is running, this will
	 * exit as kprobe does. See the section 'Share the callbacks with kprobes'
	 * in Documentation/trace/fprobe.rst for more information.
	 */
	if (unlikely(kprobe_running())) {
		fp->nmissed++;
		return 0;
	}

	kprobe_busy_begin();
	ret = __fprobe_handler(ip, parent_ip, fp, fregs, data);
	kprobe_busy_end();
	return ret;
}

static int fprobe_fgraph_entry(struct ftrace_graph_ent *trace, struct fgraph_ops *gops,
			       struct ftrace_regs *fregs);
static void fprobe_return(struct ftrace_graph_ret *trace,
			  struct fgraph_ops *gops,
			  struct ftrace_regs *fregs);

static struct fgraph_ops fprobe_graph_ops = {
	.entryfunc	= fprobe_fgraph_entry,
	.retfunc	= fprobe_return,
};
/* Number of fgraph fprobe nodes */
static int nr_fgraph_fprobes;
/* Is fprobe_graph_ops registered? */
static bool fprobe_graph_registered;

/* Add @addrs to the ftrace filter and register fgraph if needed. */
static int fprobe_graph_add_ips(unsigned long *addrs, int num)
{
	int ret;

	lockdep_assert_held(&fprobe_mutex);

	ret = ftrace_set_filter_ips(&fprobe_graph_ops.ops, addrs, num, 0, 0);
	if (ret)
		return ret;

	if (!fprobe_graph_registered) {
		ret = register_ftrace_graph(&fprobe_graph_ops);
		if (WARN_ON_ONCE(ret)) {
			ftrace_free_filter(&fprobe_graph_ops.ops);
			return ret;
		}
		fprobe_graph_registered = true;
	}
	return 0;
}

static void __fprobe_graph_unregister(void)
{
	if (fprobe_graph_registered) {
		unregister_ftrace_graph(&fprobe_graph_ops);
		ftrace_free_filter(&fprobe_graph_ops.ops);
		fprobe_graph_registered = false;
	}
}

/* Remove @addrs from the ftrace filter and unregister fgraph if possible. */
static void fprobe_graph_remove_ips(unsigned long *addrs, int num)
{
	lockdep_assert_held(&fprobe_mutex);

	if (!nr_fgraph_fprobes)
		__fprobe_graph_unregister();
	else if (num)
		ftrace_set_filter_ips(&fprobe_graph_ops.ops, addrs, num, 1, 0);
}

#if defined(CONFIG_DYNAMIC_FTRACE_WITH_ARGS) || defined(CONFIG_DYNAMIC_FTRACE_WITH_REGS)

/* ftrace_ops callback, this processes fprobes which have only entry_handler. */
static void fprobe_ftrace_entry(unsigned long ip, unsigned long parent_ip,
	struct ftrace_ops *ops, struct ftrace_regs *fregs)
{
	struct fprobe_hlist_node *node;
	struct rhlist_head *head, *pos;
	struct fprobe *fp;
	int bit;

	bit = ftrace_test_recursion_trylock(ip, parent_ip);
	if (bit < 0)
		return;

	/*
	 * ftrace_test_recursion_trylock() disables preemption, but
	 * rhltable_lookup() checks whether rcu_read_lcok is held.
	 * So we take rcu_read_lock() here.
	 */
	rcu_read_lock();
	head = rhltable_lookup(&fprobe_ip_table, &ip, fprobe_rht_params);

	rhl_for_each_entry_rcu(node, pos, head, hlist) {
		if (node->addr != ip)
			break;
		fp = READ_ONCE(node->fp);
		if (unlikely(!fp || fprobe_disabled(fp) || fp->exit_handler))
			continue;

		if (fprobe_shared_with_kprobes(fp))
			__fprobe_kprobe_handler(ip, parent_ip, fp, fregs, NULL);
		else
			__fprobe_handler(ip, parent_ip, fp, fregs, NULL);
	}
	rcu_read_unlock();
	ftrace_test_recursion_unlock(bit);
}
NOKPROBE_SYMBOL(fprobe_ftrace_entry);

static struct ftrace_ops fprobe_ftrace_ops = {
	.func	= fprobe_ftrace_entry,
	.flags	= FTRACE_OPS_FL_SAVE_ARGS,
};
/* Number of ftrace fprobe nodes */
static int nr_ftrace_fprobes;
/* Is fprobe_ftrace_ops registered? */
static bool fprobe_ftrace_registered;

static int fprobe_ftrace_add_ips(unsigned long *addrs, int num)
{
	int ret;

	lockdep_assert_held(&fprobe_mutex);

	ret = ftrace_set_filter_ips(&fprobe_ftrace_ops, addrs, num, 0, 0);
	if (ret)
		return ret;

	if (!fprobe_ftrace_registered) {
		ret = register_ftrace_function(&fprobe_ftrace_ops);
		if (ret) {
			ftrace_free_filter(&fprobe_ftrace_ops);
			return ret;
		}
		fprobe_ftrace_registered = true;
	}
	return 0;
}

static void __fprobe_ftrace_unregister(void)
{
	if (fprobe_ftrace_registered) {
		unregister_ftrace_function(&fprobe_ftrace_ops);
		ftrace_free_filter(&fprobe_ftrace_ops);
		fprobe_ftrace_registered = false;
	}
}

static void fprobe_ftrace_remove_ips(unsigned long *addrs, int num)
{
	lockdep_assert_held(&fprobe_mutex);

	if (!nr_ftrace_fprobes)
		__fprobe_ftrace_unregister();
	else if (num)
		ftrace_set_filter_ips(&fprobe_ftrace_ops, addrs, num, 1, 0);
}

static bool fprobe_is_ftrace(struct fprobe *fp)
{
	return !fp->exit_handler;
}

/* Node insertion and deletion requires the fprobe_mutex */
static int insert_fprobe_node(struct fprobe_hlist_node *node, struct fprobe *fp)
{
	int ret;

	lockdep_assert_held(&fprobe_mutex);

	ret = __insert_fprobe_node(node, fp);
	if (!ret) {
		if (fprobe_is_ftrace(fp))
			nr_ftrace_fprobes++;
		else
			nr_fgraph_fprobes++;
	}

	return ret;
}

static void delete_fprobe_node(struct fprobe_hlist_node *node)
{
	struct fprobe *fp;

	lockdep_assert_held(&fprobe_mutex);

	fp = READ_ONCE(node->fp);
	if (fp) {
		if (fprobe_is_ftrace(fp))
			nr_ftrace_fprobes--;
		else
			nr_fgraph_fprobes--;
	}
	__delete_fprobe_node(node);
}

static bool fprobe_exists_on_hash(unsigned long ip, bool ftrace)
{
	struct rhlist_head *head, *pos;
	struct fprobe_hlist_node *node;
	struct fprobe *fp;

	guard(rcu)();
	head = rhltable_lookup(&fprobe_ip_table, &ip,
				fprobe_rht_params);
	if (!head)
		return false;
	/* We have to check the same type on the list. */
	rhl_for_each_entry_rcu(node, pos, head, hlist) {
		if (node->addr != ip)
			break;
		fp = READ_ONCE(node->fp);
		if (likely(fp)) {
			if ((!ftrace && fp->exit_handler) ||
			    (ftrace && !fp->exit_handler))
				return true;
		}
	}

	return false;
}

#ifdef CONFIG_MODULES
static void fprobe_remove_ips(unsigned long *ips, unsigned int cnt)
{
	fprobe_graph_remove_ips(ips, cnt);
	fprobe_ftrace_remove_ips(ips, cnt);
}
#endif
#else
static int fprobe_ftrace_add_ips(unsigned long *addrs, int num)
{
	return -ENOENT;
}

static void fprobe_ftrace_remove_ips(unsigned long *addrs, int num)
{
}

static bool fprobe_is_ftrace(struct fprobe *fp)
{
	return false;
}

/* Node insertion and deletion requires the fprobe_mutex */
static int insert_fprobe_node(struct fprobe_hlist_node *node, struct fprobe *fp)
{
	int ret;

	lockdep_assert_held(&fprobe_mutex);

	ret = __insert_fprobe_node(node, fp);
	if (!ret)
		nr_fgraph_fprobes++;

	return ret;
}

static void delete_fprobe_node(struct fprobe_hlist_node *node)
{
	struct fprobe *fp;

	lockdep_assert_held(&fprobe_mutex);

	fp = READ_ONCE(node->fp);
	if (fp)
		nr_fgraph_fprobes--;
	__delete_fprobe_node(node);
}

static bool fprobe_exists_on_hash(unsigned long ip, bool ftrace __maybe_unused)
{
	struct rhlist_head *head, *pos;
	struct fprobe_hlist_node *node;
	struct fprobe *fp;

	guard(rcu)();
	head = rhltable_lookup(&fprobe_ip_table, &ip,
				fprobe_rht_params);
	if (!head)
		return false;
	/* We only need to check fp is there. */
	rhl_for_each_entry_rcu(node, pos, head, hlist) {
		if (node->addr != ip)
			break;
		fp = READ_ONCE(node->fp);
		if (likely(fp))
			return true;
	}

	return false;
}

#ifdef CONFIG_MODULES
static void fprobe_remove_ips(unsigned long *ips, unsigned int cnt)
{
	if (!nr_fgraph_fprobes)
		__fprobe_graph_unregister();
	else if (cnt)
		ftrace_set_filter_ips(&fprobe_graph_ops.ops, ips, cnt, 1, 0);
}
#endif
#endif /* !CONFIG_DYNAMIC_FTRACE_WITH_ARGS && !CONFIG_DYNAMIC_FTRACE_WITH_REGS */

/* fgraph_ops callback, this processes fprobes which have exit_handler. */
static int fprobe_fgraph_entry(struct ftrace_graph_ent *trace, struct fgraph_ops *gops,
			       struct ftrace_regs *fregs)
{
	unsigned long *fgraph_data = NULL;
	unsigned long func = trace->func;
	struct fprobe_hlist_node *node;
	struct rhlist_head *head, *pos;
	unsigned long ret_ip;
	int reserved_words;
	struct fprobe *fp;
	int used, ret;

	if (WARN_ON_ONCE(!fregs))
		return 0;

	guard(rcu)();
	head = rhltable_lookup(&fprobe_ip_table, &func, fprobe_rht_params);
	reserved_words = 0;
	rhl_for_each_entry_rcu(node, pos, head, hlist) {
		if (node->addr != func)
			continue;
		fp = READ_ONCE(node->fp);
		if (!fp || !fp->exit_handler)
			continue;
		/*
		 * Since fprobe can be enabled until the next loop, we ignore the
		 * fprobe's disabled flag in this loop.
		 */
		reserved_words +=
			FPROBE_HEADER_SIZE_IN_LONG + SIZE_IN_LONG(fp->entry_data_size);
	}
	if (reserved_words) {
		fgraph_data = fgraph_reserve_data(gops->idx, reserved_words * sizeof(long));
		if (unlikely(!fgraph_data)) {
			rhl_for_each_entry_rcu(node, pos, head, hlist) {
				if (node->addr != func)
					continue;
				fp = READ_ONCE(node->fp);
				if (fp && !fprobe_disabled(fp) && !fprobe_is_ftrace(fp))
					fp->nmissed++;
			}
			return 0;
		}
	}

	/*
	 * TODO: recursion detection has been done in the fgraph. Thus we need
	 * to add a callback to increment missed counter.
	 */
	ret_ip = ftrace_regs_get_return_address(fregs);
	used = 0;
	rhl_for_each_entry_rcu(node, pos, head, hlist) {
		int data_size;
		void *data;

		if (node->addr != func)
			continue;
		fp = READ_ONCE(node->fp);
		if (unlikely(!fp || fprobe_disabled(fp) || fprobe_is_ftrace(fp)))
			continue;

		data_size = fp->entry_data_size;
		/*
		 * The list may have grown since it was sized, so this node
		 * may not fit. Skip it as missed rather than overrun the
		 * reservation.
		 */
		if (fp->exit_handler &&
		    used + FPROBE_HEADER_SIZE_IN_LONG + SIZE_IN_LONG(data_size) > reserved_words) {
			fp->nmissed++;
			continue;
		}
		if (data_size && fp->exit_handler)
			data = fgraph_data + used + FPROBE_HEADER_SIZE_IN_LONG;
		else
			data = NULL;

		if (fprobe_shared_with_kprobes(fp))
			ret = __fprobe_kprobe_handler(func, ret_ip, fp, fregs, data);
		else
			ret = __fprobe_handler(func, ret_ip, fp, fregs, data);

		/* If entry_handler returns !0, nmissed is not counted but skips exit_handler. */
		if (!ret && fp->exit_handler) {
			int size_words = SIZE_IN_LONG(data_size);

			if (write_fprobe_header(&fgraph_data[used], fp, size_words))
				used += FPROBE_HEADER_SIZE_IN_LONG + size_words;
		}
	}

	/* If any exit_handler is set, data must be used. */
	return used != 0;
}
NOKPROBE_SYMBOL(fprobe_fgraph_entry);

static void fprobe_return(struct ftrace_graph_ret *trace,
			  struct fgraph_ops *gops,
			  struct ftrace_regs *fregs)
{
	unsigned long *fgraph_data = NULL;
	unsigned long ret_ip;
	struct fprobe *fp;
	int size, curr;
	int size_words;

	fgraph_data = (unsigned long *)fgraph_retrieve_data(gops->idx, &size);
	if (WARN_ON_ONCE(!fgraph_data))
		return;
	size_words = SIZE_IN_LONG(size);
	ret_ip = ftrace_regs_get_instruction_pointer(fregs);

	preempt_disable_notrace();

	curr = 0;
	while (size_words > curr) {
		read_fprobe_header(&fgraph_data[curr], &fp, &size);
		if (!fp)
			break;
		curr += FPROBE_HEADER_SIZE_IN_LONG;
		if (fprobe_registered(fp) && !fprobe_disabled(fp)) {
			if (WARN_ON_ONCE(curr + size > size_words))
				break;
			fp->exit_handler(fp, trace->func, ret_ip, fregs,
					 size ? fgraph_data + curr : NULL);
		}
		curr += size;
	}
	preempt_enable_notrace();
}
NOKPROBE_SYMBOL(fprobe_return);

#ifdef CONFIG_MODULES

#define FPROBE_IPS_BATCH_INIT 128
/* instruction pointer address list */
struct fprobe_addr_list {
	int index;
	int size;
	unsigned long *addrs;
};

static int fprobe_remove_node_in_module(struct module *mod, struct fprobe_hlist_node *node,
					 struct fprobe_addr_list *alist)
{
	lockdep_assert_in_rcu_read_lock();

	if (!within_module(node->addr, mod))
		return 0;

	delete_fprobe_node(node);
	/* If no address list is available, we can't track this address. */
	if (!alist->addrs)
		return 0;
	/*
	 * Don't care the type here, because all fprobes on the same
	 * address must be removed eventually.
	 */
	if (!rhltable_lookup(&fprobe_ip_table, &node->addr, fprobe_rht_params)) {
		alist->addrs[alist->index++] = node->addr;
		if (alist->index == alist->size)
			return -ENOSPC;
	}

	return 0;
}

/* Handle module unloading to manage fprobe_ip_table. */
static int fprobe_module_callback(struct notifier_block *nb,
				  unsigned long val, void *data)
{
	struct fprobe_addr_list alist = {.size = FPROBE_IPS_BATCH_INIT};
	struct fprobe_hlist_node *node;
	struct rhashtable_iter iter;
	struct module *mod = data;
	bool retry;

	if (val != MODULE_STATE_GOING)
		return NOTIFY_DONE;

	alist.addrs = kcalloc(alist.size, sizeof(*alist.addrs), GFP_KERNEL);
	/*
	 * If failed to alloc memory, ftrace_ops will not be able to remove ips from
	 * hash, but we can still remove nodes from fprobe_ip_table, so we can avoid
	 * the potential wrong callback. So just print a warning here and try to
	 * continue without address list.
	 */
	WARN_ONCE(!alist.addrs,
		"Failed to allocate memory for fprobe_addr_list, ftrace_ops will not be updated");

	mutex_lock(&fprobe_mutex);
again:
	retry = false;
	alist.index = 0;
	rhltable_walk_enter(&fprobe_ip_table, &iter);
	do {
		rhashtable_walk_start(&iter);

		while ((node = rhashtable_walk_next(&iter)) && !IS_ERR(node))
			if (fprobe_remove_node_in_module(mod, node, &alist) < 0) {
				retry = true;
				break;
			}

		rhashtable_walk_stop(&iter);
	} while (node == ERR_PTR(-EAGAIN) && !retry);
	rhashtable_walk_exit(&iter);
	/* Remove any ips from hash table(s) */
	fprobe_remove_ips(alist.addrs, alist.index);
	/*
	 * If we break rhashtable walk loop except for -EAGAIN, we need
	 * to restart looping from start for safety. Anyway, this is
	 * not a hotpath.
	 */
	if (retry)
		goto again;

	mutex_unlock(&fprobe_mutex);

	kfree(alist.addrs);

	return NOTIFY_DONE;
}

static struct notifier_block fprobe_module_nb = {
	.notifier_call = fprobe_module_callback,
	.priority = 0,
};

static int __init init_fprobe_module(void)
{
	return register_module_notifier(&fprobe_module_nb);
}
early_initcall(init_fprobe_module);
#endif

static int symbols_cmp(const void *a, const void *b)
{
	const char **str_a = (const char **) a;
	const char **str_b = (const char **) b;

	return strcmp(*str_a, *str_b);
}

/* Convert ftrace location address from symbols */
static unsigned long *get_ftrace_locations(const char **syms, int num)
{
	unsigned long *addrs;

	/* Convert symbols to symbol address */
	addrs = kcalloc(num, sizeof(*addrs), GFP_KERNEL);
	if (!addrs)
		return ERR_PTR(-ENOMEM);

	/* ftrace_lookup_symbols expects sorted symbols */
	sort(syms, num, sizeof(*syms), symbols_cmp, NULL);

	if (!ftrace_lookup_symbols(syms, num, addrs))
		return addrs;

	kfree(addrs);
	return ERR_PTR(-ENOENT);
}

struct filter_match_data {
	const char *filter;
	const char *notfilter;
	size_t index;
	size_t size;
	unsigned long *addrs;
	struct module **mods;
};

static int filter_match_callback(void *data, const char *name, unsigned long addr)
{
	struct filter_match_data *match = data;

	if (!glob_match(match->filter, name) ||
	    (match->notfilter && glob_match(match->notfilter, name)))
		return 0;

	if (!ftrace_location(addr))
		return 0;

	if (match->addrs) {
		struct module *mod = __module_text_address(addr);

		if (mod && !try_module_get(mod))
			return 0;

		match->mods[match->index] = mod;
		match->addrs[match->index] = addr;
	}
	match->index++;
	return match->index == match->size;
}

/*
 * Make IP list from the filter/no-filter glob patterns.
 * Return the number of matched symbols, or errno.
 * If @addrs == NULL, this just counts the number of matched symbols. If @addrs
 * is passed with an array, we need to pass the an @mods array of the same size
 * to increment the module refcount for each symbol.
 * This means we also need to call `module_put` for each element of @mods after
 * using the @addrs.
 */
static int get_ips_from_filter(const char *filter, const char *notfilter,
			       unsigned long *addrs, struct module **mods,
			       size_t size)
{
	struct filter_match_data match = { .filter = filter, .notfilter = notfilter,
		.index = 0, .size = size, .addrs = addrs, .mods = mods};
	int ret;

	if (addrs && !mods)
		return -EINVAL;

	ret = kallsyms_on_each_symbol(filter_match_callback, &match);
	if (ret < 0)
		return ret;
	if (IS_ENABLED(CONFIG_MODULES)) {
		ret = module_kallsyms_on_each_symbol(NULL, filter_match_callback, &match);
		if (ret < 0)
			return ret;
	}

	return match.index ?: -ENOENT;
}

static void fprobe_fail_cleanup(struct fprobe *fp)
{
	kfree(fp->hlist_array);
	fp->hlist_array = NULL;
}

/* Initialize the fprobe data structure. */
static int fprobe_init(struct fprobe *fp, unsigned long *addrs, int num)
{
	struct fprobe_hlist *hlist_array;
	unsigned long addr;
	int size, i;

	if (!fp || !addrs || num <= 0)
		return -EINVAL;

	size = ALIGN(fp->entry_data_size, sizeof(long));
	if (size > MAX_FPROBE_DATA_SIZE)
		return -E2BIG;
	fp->entry_data_size = size;

	hlist_array = kzalloc_flex(*hlist_array, array, num);
	if (!hlist_array)
		return -ENOMEM;

	fp->nmissed = 0;

	hlist_array->size = num;
	fp->hlist_array = hlist_array;
	hlist_array->fp = fp;
	for (i = 0; i < num; i++) {
		addr = ftrace_location(addrs[i]);
		if (!addr) {
			fprobe_fail_cleanup(fp);
			return -ENOENT;
		}
		hlist_array->array[i].addr = addr;
	}
	return 0;
}

#define FPROBE_IPS_MAX	INT_MAX

int fprobe_count_ips_from_filter(const char *filter, const char *notfilter)
{
	return get_ips_from_filter(filter, notfilter, NULL, NULL, FPROBE_IPS_MAX);
}

/**
 * register_fprobe() - Register fprobe to ftrace by pattern.
 * @fp: A fprobe data structure to be registered.
 * @filter: A wildcard pattern of probed symbols.
 * @notfilter: A wildcard pattern of NOT probed symbols.
 *
 * Register @fp to ftrace for enabling the probe on the symbols matched to @filter.
 * If @notfilter is not NULL, the symbols matched the @notfilter are not probed.
 *
 * Return 0 if @fp is registered successfully, -errno if not.
 */
int register_fprobe(struct fprobe *fp, const char *filter, const char *notfilter)
{
	unsigned long *addrs __free(kfree) = NULL;
	struct module **mods __free(kfree) = NULL;
	int ret, num;

	if (!fp || !filter)
		return -EINVAL;

	num = get_ips_from_filter(filter, notfilter, NULL, NULL, FPROBE_IPS_MAX);
	if (num < 0)
		return num;

	addrs = kzalloc_objs(*addrs, num);
	if (!addrs)
		return -ENOMEM;

	mods = kzalloc_objs(*mods, num);
	if (!mods)
		return -ENOMEM;

	ret = get_ips_from_filter(filter, notfilter, addrs, mods, num);
	if (ret >= 0)
		ret = register_fprobe_ips(fp, addrs, ret);

	for (int i = 0; i < num; i++) {
		if (mods[i])
			module_put(mods[i]);
	}
	return ret;
}
EXPORT_SYMBOL_GPL(register_fprobe);

static int unregister_fprobe_nolock(struct fprobe *fp);

/**
 * register_fprobe_ips() - Register fprobe to ftrace by address.
 * @fp: A fprobe data structure to be registered.
 * @addrs: An array of target function address.
 * @num: The number of entries of @addrs.
 *
 * Register @fp to ftrace for enabling the probe on the address given by @addrs.
 * The @addrs must be the addresses of ftrace location address, which may be
 * the symbol address + arch-dependent offset.
 * If you unsure what this mean, please use other registration functions.
 *
 * Return 0 if @fp is registered successfully, -errno if not.
 */
int register_fprobe_ips(struct fprobe *fp, unsigned long *addrs, int num)
{
	struct fprobe_hlist *hlist_array;
	int ret, i;

	guard(mutex)(&fprobe_mutex);
	if (fprobe_registered(fp))
		return -EEXIST;

	ret = fprobe_init(fp, addrs, num);
	if (ret)
		return ret;

	if (fprobe_is_ftrace(fp))
		ret = fprobe_ftrace_add_ips(addrs, num);
	else
		ret = fprobe_graph_add_ips(addrs, num);
	if (ret) {
		fprobe_fail_cleanup(fp);
		return ret;
	}

	hlist_array = fp->hlist_array;
	ret = add_fprobe_hash(fp);
	for (i = 0; i < hlist_array->size && !ret; i++)
		ret = insert_fprobe_node(&hlist_array->array[i], fp);

	if (ret) {
		unregister_fprobe_nolock(fp);
		/* In error case, wait for clean up safely. */
		synchronize_rcu();
	}

	return ret;
}
EXPORT_SYMBOL_GPL(register_fprobe_ips);

/**
 * register_fprobe_syms() - Register fprobe to ftrace by symbols.
 * @fp: A fprobe data structure to be registered.
 * @syms: An array of target symbols.
 * @num: The number of entries of @syms.
 *
 * Register @fp to the symbols given by @syms array. This will be useful if
 * you are sure the symbols exist in the kernel.
 *
 * Return 0 if @fp is registered successfully, -errno if not.
 */
int register_fprobe_syms(struct fprobe *fp, const char **syms, int num)
{
	unsigned long *addrs;
	int ret;

	if (!fp || !syms || num <= 0)
		return -EINVAL;

	addrs = get_ftrace_locations(syms, num);
	if (IS_ERR(addrs))
		return PTR_ERR(addrs);

	ret = register_fprobe_ips(fp, addrs, num);

	kfree(addrs);

	return ret;
}
EXPORT_SYMBOL_GPL(register_fprobe_syms);

bool fprobe_is_registered(struct fprobe *fp)
{
	if (!fp || !fp->hlist_array)
		return false;
	return true;
}

static int unregister_fprobe_nolock(struct fprobe *fp)
{
	struct fprobe_hlist *hlist_array = fp->hlist_array;
	unsigned long *addrs = NULL;
	int i, count;

	addrs = kcalloc(hlist_array->size, sizeof(unsigned long), GFP_KERNEL);
	/*
	 * This will remove fprobe_hash_node from the hash table even if
	 * memory allocation fails. However, ftrace_ops will not be updated.
	 * Anyway, when the last fprobe is unregistered, ftrace_ops is also
	 * unregistered.
	 */
	if (!addrs)
		pr_warn("Failed to allocate working array. ftrace_ops may not sync.\n");

	/* Remove non-synonim ips from table and hash */
	count = 0;
	for (i = 0; i < hlist_array->size; i++) {
		delete_fprobe_node(&hlist_array->array[i]);
		if (addrs && !fprobe_exists_on_hash(hlist_array->array[i].addr,
						    fprobe_is_ftrace(fp)))
			addrs[count++] = hlist_array->array[i].addr;
	}
	del_fprobe_hash(fp);

	if (fprobe_is_ftrace(fp))
		fprobe_ftrace_remove_ips(addrs, count);
	else
		fprobe_graph_remove_ips(addrs, count);

	kfree_rcu(hlist_array, rcu);
	fp->hlist_array = NULL;
	kfree(addrs);

	return 0;
}

/**
 * unregister_fprobe_async() - Unregister fprobe without RCU GP wait
 * @fp: A fprobe data structure to be unregistered.
 *
 * Unregister fprobe (and remove ftrace hooks from the function entries).
 * This function will NOT wait until the fprobe is no longer used.
 *
 * Return 0 if @fp is unregistered successfully, -errno if not.
 */
int unregister_fprobe_async(struct fprobe *fp)
{
	guard(mutex)(&fprobe_mutex);
	if (!fp || !fprobe_registered(fp))
		return -EINVAL;

	return unregister_fprobe_nolock(fp);
}

/**
 * unregister_fprobe() - Unregister fprobe with RCU GP wait
 * @fp: A fprobe data structure to be unregistered.
 *
 * Unregister fprobe (and remove ftrace hooks from the function entries).
 * This function will block until the fprobe is no longer used.
 *
 * Return 0 if @fp is unregistered successfully, -errno if not.
 */
int unregister_fprobe(struct fprobe *fp)
{
	int ret = unregister_fprobe_async(fp);

	if (!ret)
		synchronize_rcu();
	return ret;
}
EXPORT_SYMBOL_GPL(unregister_fprobe);

static int __init fprobe_initcall(void)
{
	rhltable_init(&fprobe_ip_table, &fprobe_rht_params);
	return 0;
}
core_initcall(fprobe_initcall);
