// SPDX-License-Identifier: BSD-2-Clause
/*
 * Copyright (c) 2018, Linaro Limited
 */

#include <assert.h>
#include <kernel/lockdep.h>
#include <kernel/unwind.h>
#include <stdlib.h>
#include <string.h>
#include <sys/queue.h>
#include <util.h>

/* lockdep_node::flags values */
/* Flags used for depth-first topological sorting */
#define LOCKDEP_NODE_TEMP_MARK		BIT(0)
#define LOCKDEP_NODE_PERM_MARK		BIT(1)
/* Flag used during breadth-first search (print shortest cycle) */
#define LOCKDEP_NODE_BFS_VISITED	BIT(2)

/* Find node in graph or add it */
static struct lockdep_node *lockdep_add_to_graph(
				struct lockdep_node_head *graph,
				uintptr_t lock_id)
{
	struct lockdep_node *node = NULL;

	assert(graph);
	TAILQ_FOREACH(node, graph, link)
		if (node->lock_id == lock_id)
			return node;

	node = calloc(1, sizeof(*node));
	if (!node)
		return NULL;

	node->lock_id = lock_id;
	STAILQ_INIT(&node->edges);
	TAILQ_INSERT_TAIL(graph, node, link);

	return node;
}

static vaddr_t *dup_call_stack(vaddr_t *stack)
{
	vaddr_t *nstack = NULL;
	int n = 0;

	if (!stack)
		return NULL;

	while (stack[n])
		n++;

	nstack = malloc((n + 1) * sizeof(vaddr_t));
	if (!nstack)
		return NULL;

	memcpy(nstack, stack, (n + 1) * sizeof(vaddr_t));

	return nstack;
}

static void lockdep_print_call_stack(vaddr_t *stack)
{
	vaddr_t *p = NULL;

	EMSG_RAW("Call stack:");
	for (p = stack; p && *p; p++)
		EMSG_RAW(" %#" PRIxPTR, *p);
}

static TEE_Result lockdep_add_edge(struct lockdep_node *from,
				   struct lockdep_node *to,
				   vaddr_t *call_stack_from,
				   vaddr_t *call_stack_to,
				   uintptr_t thread_id)
{
	struct lockdep_edge *edge = NULL;

	STAILQ_FOREACH(edge, &from->edges, link)
		if (edge->to == to)
			return TEE_SUCCESS;

	edge = calloc(1, sizeof(*edge));
	if (!edge)
		return TEE_ERROR_OUT_OF_MEMORY;
	edge->to = to;
	edge->call_stack_from = dup_call_stack(call_stack_from);
	edge->call_stack_to = dup_call_stack(call_stack_to);
	edge->thread_id = thread_id;
	STAILQ_INSERT_TAIL(&from->edges, edge, link);

	return TEE_SUCCESS;
}

struct lockdep_bfs {
	struct lockdep_node *node;
	uintptr_t *path;
	int pathlen;
	TAILQ_ENTRY(lockdep_bfs) link;
};

TAILQ_HEAD(lockdep_bfs_head, lockdep_bfs);

static void lockdep_bfs_queue_delete(struct lockdep_bfs_head *queue)
{
	struct lockdep_bfs *cur = NULL;
	struct lockdep_bfs *next = NULL;

	TAILQ_FOREACH_SAFE(cur, queue, link, next) {
		TAILQ_REMOVE(queue, cur, link);
		free(cur->path);
		free(cur);
	}
}

/*
 * Print shortest cycle in @graph that contains @node.
 * This function performs an iterative breadth-first search starting from @node,
 * and stops when it reaches @node again. In each node we're tracking the path
 * from the start node.
 */
static uintptr_t *lockdep_graph_get_shortest_cycle(struct lockdep_node *node)
{
	struct lockdep_bfs_head queue;
	struct lockdep_bfs *qe = NULL;
	uintptr_t *ret = NULL;

	TAILQ_INIT(&queue);
	node->flags |= LOCKDEP_NODE_BFS_VISITED;

	qe = calloc(1, sizeof(*qe));
	if (!qe)
		goto out;
	qe->node = node;
	qe->path = malloc(sizeof(uintptr_t));
	if (!qe->path)
		goto out;
	qe->path[0] = node->lock_id;
	qe->pathlen = 1;
	TAILQ_INSERT_TAIL(&queue, qe, link);

	while (!TAILQ_EMPTY(&queue)) {
		qe = TAILQ_FIRST(&queue);

		struct lockdep_node *n = qe->node;

		TAILQ_REMOVE(&queue, qe, link);

		struct lockdep_edge *e = NULL;

		STAILQ_FOREACH(e, &n->edges, link) {
			if (e->to->lock_id == node->lock_id) {
				uintptr_t *tmp = NULL;
				size_t nlen = qe->pathlen + 1;

				/*
				 * Cycle found. Terminate cycle path with NULL
				 * and return it.
				 */
				tmp = realloc(qe->path,
					      nlen * sizeof(uintptr_t));
				if (!tmp) {
					EMSG("Out of memory");
					free(qe->path);
					ret = NULL;
					goto out;
				}
				qe->path = tmp;
				qe->path[nlen - 1] = 0;
				ret = qe->path;
				goto out;
			}

			if (!(e->to->flags & LOCKDEP_NODE_BFS_VISITED)) {
				e->to->flags |= LOCKDEP_NODE_BFS_VISITED;

				size_t nlen = qe->pathlen + 1;
				struct lockdep_bfs *nqe = calloc(1,
								 sizeof(*nqe));

				if (!nqe)
					goto out;
				nqe->node = e->to;
				nqe->path = malloc(nlen * sizeof(uintptr_t));
				if (!nqe->path)
					goto out;
				nqe->pathlen = nlen;
				memcpy(nqe->path, qe->path,
				       qe->pathlen * sizeof(uintptr_t));
				nqe->path[nlen - 1] = e->to->lock_id;
				TAILQ_INSERT_TAIL(&queue, nqe, link);
			}
		}
		free(qe->path);
		free(qe);
		qe = NULL;
	}

out:
	free(qe);
	lockdep_bfs_queue_delete(&queue);
	return ret;
}

static TEE_Result lockdep_visit(struct lockdep_node *node)
{
	if (node->flags & LOCKDEP_NODE_PERM_MARK)
		return TEE_SUCCESS;

	if (node->flags & LOCKDEP_NODE_TEMP_MARK)
		return TEE_ERROR_BAD_STATE;	/* Not a DAG! */

	node->flags |= LOCKDEP_NODE_TEMP_MARK;

	struct lockdep_edge *e;

	STAILQ_FOREACH(e, &node->edges, link) {
		TEE_Result res = lockdep_visit(e->to);

		if (res)
			return res;
	}

	node->flags |= LOCKDEP_NODE_PERM_MARK;
	return TEE_SUCCESS;
}

static TEE_Result lockdep_graph_sort(struct lockdep_node_head *graph)
{
	struct lockdep_node *node = NULL;

	TAILQ_FOREACH(node, graph, link) {
		if (!node->flags) {
			/* Unmarked node */
			TEE_Result res = lockdep_visit(node);

			if (res)
				return res;
		}
	}

	TAILQ_FOREACH(node, graph, link)
		node->flags = 0;

	return TEE_SUCCESS;
}

static struct lockdep_edge *lockdep_find_edge(struct lockdep_node_head *graph,
					      uintptr_t from, uintptr_t to)
{
	struct lockdep_node *node = NULL;
	struct lockdep_edge *edge = NULL;

	TAILQ_FOREACH(node, graph, link)
		if (node->lock_id == from)
			STAILQ_FOREACH(edge, &node->edges, link)
				if (edge->to->lock_id == to)
					return edge;
	return NULL;
}

static void lockdep_print_edge_info(uintptr_t from __maybe_unused,
				    struct lockdep_edge *edge)
{
	uintptr_t __maybe_unused to = edge->to->lock_id;

	EMSG_RAW("-> Thread %#" PRIxPTR " acquired lock %#" PRIxPTR " at:",
		 edge->thread_id, to);
	lockdep_print_call_stack(edge->call_stack_to);
	EMSG_RAW("...while holding lock %#" PRIxPTR " acquired at:",
		 from);
	lockdep_print_call_stack(edge->call_stack_from);
}

/*
 * Find cycle containing @node in the lock graph, then print full debug
 * information about each edge (thread that acquired the locks and call stacks)
 */
static void lockdep_print_cycle_info(struct lockdep_node_head *graph,
				     struct lockdep_node *node)
{
	struct lockdep_edge *edge = NULL;
	uintptr_t *cycle = NULL;
	uintptr_t *p = NULL;
	uintptr_t from = 0;
	uintptr_t to = 0;

	cycle = lockdep_graph_get_shortest_cycle(node);
	assert(cycle && cycle[0]);
	EMSG_RAW("-> Shortest cycle:");
	for (p = cycle; *p; p++)
		EMSG_RAW(" Lock %#" PRIxPTR, *p);
	for (p = cycle; ; p++) {
		if (!*p) {
			assert(p != cycle);
			from = to;
			to = cycle[0];
			edge = lockdep_find_edge(graph, from, to);
			lockdep_print_edge_info(from, edge);
			break;
		}
		if (p != cycle)
			from = to;
		to = *p;
		if (p != cycle) {
			edge = lockdep_find_edge(graph, from, to);
			lockdep_print_edge_info(from, edge);
		}
	}
	free(cycle);
}

TEE_Result __lockdep_lock_acquire(struct lockdep_node_head *graph,
				  struct lockdep_lock_head *owned,
				  uintptr_t id)
{
	struct lockdep_node *node = lockdep_add_to_graph(graph, id);

	if (!node)
		return TEE_ERROR_OUT_OF_MEMORY;

	struct lockdep_lock *lock = NULL;
	vaddr_t *acq_stack = unw_get_kernel_stack();

	TAILQ_FOREACH(lock, owned, link) {
		TEE_Result res = lockdep_add_edge(lock->node, node,
						  lock->call_stack,
						  acq_stack,
						  (uintptr_t)owned);

		if (res)
			return res;
	}

	TEE_Result res = lockdep_graph_sort(graph);

	if (res) {
		EMSG_RAW("Potential deadlock detected!");
		EMSG_RAW("When trying to acquire lock %#" PRIxPTR, id);
		lockdep_print_cycle_info(graph, node);
		return res;
	}

	lock = calloc(1, sizeof(*lock));
	if (!lock)
		return TEE_ERROR_OUT_OF_MEMORY;

	lock->node = node;
	lock->call_stack = acq_stack;
	TAILQ_INSERT_TAIL(owned, lock, link);

	return TEE_SUCCESS;
}

/*
 * Call this when it is known that the thread has been able to acquire the lock.
 * Similar to __lockdep_lock_acquire(), but since the operation is non-blocking,
 * no dependency to currently owned locks are created.
 */
TEE_Result __lockdep_lock_tryacquire(struct lockdep_node_head *graph,
				     struct lockdep_lock_head *owned,
				     uintptr_t id)
{
	struct lockdep_node *node = lockdep_add_to_graph(graph, id);

	if (!node)
		return TEE_ERROR_OUT_OF_MEMORY;

	struct lockdep_lock *lock = NULL;
	vaddr_t *acq_stack = unw_get_kernel_stack();

	lock = calloc(1, sizeof(*lock));
	if (!lock)
		return TEE_ERROR_OUT_OF_MEMORY;

	lock->node = node;
	lock->call_stack = acq_stack;
	TAILQ_INSERT_TAIL(owned, lock, link);

	return TEE_SUCCESS;
}

TEE_Result __lockdep_lock_release(struct lockdep_lock_head *owned, uintptr_t id)
{
	struct lockdep_lock *lock = NULL;

	TAILQ_FOREACH_REVERSE(lock, owned, lockdep_lock_head, link) {
		if (lock->node->lock_id == id) {
			TAILQ_REMOVE(owned, lock, link);
			free(lock->call_stack);
			free(lock);
			return TEE_SUCCESS;
		}
	}

	EMSG_RAW("Thread %p does not own lock %#" PRIxPTR, (void *)owned, id);
	return TEE_ERROR_ITEM_NOT_FOUND;
}

static void lockdep_free_edge(struct lockdep_edge *edge)
{
	free(edge->call_stack_from);
	free(edge->call_stack_to);
	free(edge);
}

static void lockdep_node_delete(struct lockdep_node *node)
{
	struct lockdep_edge *edge = NULL;
	struct lockdep_edge *next = NULL;

	STAILQ_FOREACH_SAFE(edge, &node->edges, link, next)
		lockdep_free_edge(edge);

	free(node);
}

void lockdep_graph_delete(struct lockdep_node_head *graph)
{
	struct lockdep_node *node = NULL;
	struct lockdep_node *next = NULL;

	TAILQ_FOREACH_SAFE(node, graph, link, next) {
		TAILQ_REMOVE(graph, node, link);
		lockdep_node_delete(node);
	}
}

void lockdep_queue_delete(struct lockdep_lock_head *owned)
{
	struct lockdep_lock *lock = NULL;
	struct lockdep_lock *next = NULL;

	TAILQ_FOREACH_SAFE(lock, owned, link, next) {
		TAILQ_REMOVE(owned, lock, link);
		free(lock);
	}
}

static void lockdep_node_destroy(struct lockdep_node_head *graph,
				 struct lockdep_node *node)
{
	struct lockdep_edge *edge = NULL;
	struct lockdep_edge *next = NULL;
	struct lockdep_node *from = NULL;

	TAILQ_REMOVE(graph, node, link);

	/*
	 * Loop over all nodes in the graph to remove all edges with the
	 * node to remove in the "to" field.
	 */
	TAILQ_FOREACH(from, graph, link) {
		edge = STAILQ_FIRST(&from->edges);
		while (edge && edge->to == node) {
			STAILQ_REMOVE_HEAD(&from->edges, link);
			lockdep_free_edge(edge);
			edge = STAILQ_FIRST(&from->edges);
		}

		if (!edge)
			continue;

		next = STAILQ_NEXT(edge, link);
		while (next) {
			if (next->to == node) {
				STAILQ_REMOVE_AFTER(&from->edges, edge, link);
				lockdep_free_edge(next);
			} else {
				edge = next;
			}
			next = STAILQ_NEXT(edge, link);
		}
	}

	STAILQ_FOREACH_SAFE(edge, &node->edges, link, next)
		lockdep_free_edge(edge);

	free(node);
}

void lockdep_lock_destroy(struct lockdep_node_head *graph, uintptr_t lock_id)
{
	struct lockdep_node *node = NULL;

	assert(graph);
	TAILQ_FOREACH(node, graph, link) {
		if (node->lock_id == lock_id) {
			lockdep_node_destroy(graph, node);
			break;
		}
	}
}
