// 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;

DEFINE_LOCK_GUARD_0(rcu_sched_notrace,
		    rcu_read_lock_sched_notrace(),
		    rcu_read_unlock_sched_notrace())

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)
{
	if (!*stack) {
		*fp = NULL;
		*size_words = 0;
		return;
	}
	*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;

	if (!*stack) {
		*fp = NULL;
		*size_words = 0;
		return;
	}

	*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;

	if (!rcu_is_watching())
		return;

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

	guard(rcu_sched_notrace)();
	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);
	}
	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 (!rcu_is_watching())
		return 0;

	if (WARN_ON_ONCE(!fregs))
		return 0;

	guard(rcu_sched_notrace)();
	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;
		}
	}

	/* Terminate the list, fgraph_reserve_data() does not clear it. */
	if (used && used < reserved_words)
		fgraph_data[used] = 0;

	/* 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;

	if (!rcu_is_watching())
		return;

	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);

	guard(rcu_sched_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;
	}
}
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);
