// SPDX-License-Identifier: GPL-2.0

/*
 * Copyright (c) 2025, Google LLC.
 * Pasha Tatashin <pasha.tatashin@soleen.com>
 */

/**
 * DOC: LUO Sessions
 *
 * LUO Sessions provide the core mechanism for grouping and managing `struct
 * file *` instances that need to be preserved across a kexec-based live
 * update. Each session acts as a named container for a set of file objects,
 * allowing a userspace agent to manage the lifecycle of resources critical to a
 * workload.
 *
 * Core Concepts:
 *
 * - Named Containers: Sessions are identified by a unique, user-provided name,
 *   which is used for both creation in the current kernel and retrieval in the
 *   next kernel.
 *
 * - Userspace Interface: Session management is driven from userspace via
 *   ioctls on /dev/liveupdate.
 *
 * - Serialization: Session metadata is preserved using the KHO framework. When
 *   a live update is triggered via kexec, session metadata is serialized into
 *   a chain of linked-blocks and placed in a preserved memory region. The
 *   physical address of the first block header is stored in the centralized
 *   `struct luo_ser` structure.
 *
 * Session Lifecycle:
 *
 * 1.  Creation: A userspace agent calls `luo_session_create()` to create a
 *     new, empty session and receives a file descriptor for it.
 *
 * 2.  Serialization: When the `reboot(LINUX_REBOOT_CMD_KEXEC)` syscall is
 *     made, `luo_session_serialize()` is called. It iterates through all
 *     active sessions and writes their metadata into a memory area preserved
 *     by KHO.
 *
 * 3.  Deserialization (in new kernel): After kexec, `luo_session_deserialize()`
 *     runs, reading the serialized data and creating a list of `struct
 *     luo_session` objects representing the preserved sessions.
 *
 * 4.  Retrieval: A userspace agent in the new kernel can then call
 *     `luo_session_retrieve()` with a session name to get a new file
 *     descriptor and access the preserved state.
 *
 * Locking:
 *
 * The LUO session subsystem uses a three-tier locking hierarchy to ensure thread
 * safety and prevent deadlocks during concurrent session mutations and kexec
 * serialization:
 *
 * 1. `luo_session_serialize_rwsem` (global rwsem):
 *    Protects session mutations (creation, retrieval, release, and ioctls)
 *    against the serialization process during reboot.
 *
 *    - Readers: Taken by any path modifying or accessing session state (e.g.,
 *      `luo_session_create()`, `luo_session_retrieve()`, `luo_session_release()`,
 *      and `luo_session_ioctl()`).
 *    - Writer: Taken by the serialization process (`luo_session_serialize()`)
 *      during reboot. On success, the write lock is held indefinitely to freeze
 *      the subsystem. On failure, it is released to allow recovery.
 *
 * 2. `luo_session_header->rwsem` (per-list rwsem):
 *    Synchronizes list-level operations for the incoming and outgoing session headers.
 *
 *    - Writer: Taken during list mutation operations (inserting or removing a
 *      session from the list).
 *    - Reader: Taken when traversing the list (e.g., retrieving a session by name).
 *
 * 3. `luo_session->mutex` (per-session mutex):
 *    Protects the internal state and file sets of an individual session. It is
 *    acquired during per-session operations such as preserving, retrieving,
 *    or freezing files.
 *
 * Lock Hierarchy:
 *   `luo_session_serialize_rwsem` -> `luo_session_header->rwsem` -> `luo_session->mutex`
 */

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include <linux/anon_inodes.h>
#include <linux/cleanup.h>
#include <linux/err.h>
#include <linux/errno.h>
#include <linux/file.h>
#include <linux/fs.h>
#include <linux/io.h>
#include <linux/kexec_handover.h>
#include <linux/kho_block.h>
#include <linux/kho/abi/luo.h>
#include <linux/list.h>
#include <linux/liveupdate.h>
#include <linux/mutex.h>
#include <linux/rwsem.h>
#include <linux/slab.h>
#include <uapi/linux/liveupdate.h>
#include "luo_internal.h"

static DECLARE_RWSEM(luo_session_serialize_rwsem);
/**
 * struct luo_session_header - Header struct for managing LUO sessions.
 * @count:       The number of sessions currently tracked in the @list.
 * @list:        The head of the linked list of `struct luo_session` instances.
 * @rwsem:       A read-write semaphore providing synchronized access to the
 *               session list and other fields in this structure.
 * @block_set:   The set of serialization blocks.
 * @sessions_pa: Points to the location of sessions_pa within struct luo_ser.
 * @active:      Set to true when first initialized. If previous kernel did not
 *               send session data, active stays false for incoming.
 */
struct luo_session_header {
	long count;
	struct list_head list;
	struct rw_semaphore rwsem;
	struct kho_block_set block_set;
	u64 *sessions_pa;
	bool active;
};

/**
 * struct luo_session_global - Global container for managing LUO sessions.
 * @incoming:     The sessions passed from the previous kernel.
 * @outgoing:     The sessions that are going to be passed to the next kernel.
 */
struct luo_session_global {
	struct luo_session_header incoming;
	struct luo_session_header outgoing;
};

static struct luo_session_global luo_session_global = {
	.incoming = {
		.list = LIST_HEAD_INIT(luo_session_global.incoming.list),
		.rwsem = __RWSEM_INITIALIZER(luo_session_global.incoming.rwsem),
		.block_set = KHO_BLOCK_SET_INIT(luo_session_global.incoming.block_set,
						sizeof(struct luo_session_ser)),
	},
	.outgoing = {
		.list = LIST_HEAD_INIT(luo_session_global.outgoing.list),
		.rwsem = __RWSEM_INITIALIZER(luo_session_global.outgoing.rwsem),
		.block_set = KHO_BLOCK_SET_INIT(luo_session_global.outgoing.block_set,
						sizeof(struct luo_session_ser)),
	},
};

static struct luo_session *luo_session_alloc(const char *name)
{
	struct luo_session *session = kzalloc_obj(*session);

	if (!session)
		return ERR_PTR(-ENOMEM);

	strscpy(session->name, name, sizeof(session->name));
	INIT_LIST_HEAD(&session->file_set.files_list);
	luo_file_set_init(&session->file_set);
	INIT_LIST_HEAD(&session->list);
	mutex_init(&session->mutex);

	return session;
}

static void luo_session_free(struct luo_session *session)
{
	luo_file_set_destroy(&session->file_set);
	mutex_destroy(&session->mutex);
	kfree(session);
}

static int luo_session_insert(struct luo_session_header *sh,
			      struct luo_session *session)
{
	struct luo_session *it;
	int err;

	guard(rwsem_write)(&sh->rwsem);

	/*
	 * For outgoing we should make sure there is room in serialization array
	 * for new session.
	 */
	if (sh == &luo_session_global.outgoing) {
		err = kho_block_set_grow(&sh->block_set, sh->count + 1);
		if (err)
			return err;
	}

	/*
	 * For small number of sessions this loop won't hurt performance
	 * but if we ever start using a lot of sessions, this might
	 * become a bottle neck during deserialization time, as it would
	 * cause O(n*n) complexity.
	 */
	list_for_each_entry(it, &sh->list, list) {
		if (!strncmp(it->name, session->name, sizeof(it->name)))
			return -EEXIST;
	}
	list_add_tail(&session->list, &sh->list);
	sh->count++;

	return 0;
}

static void luo_session_remove(struct luo_session_header *sh,
			       struct luo_session *session)
{
	guard(rwsem_write)(&sh->rwsem);
	list_del(&session->list);
	sh->count--;
	if (sh == &luo_session_global.outgoing)
		kho_block_set_shrink(&sh->block_set, sh->count);
}

static int luo_session_finish_one(struct luo_session *session)
{
	guard(mutex)(&session->mutex);
	return luo_file_finish(&session->file_set);
}

static void luo_session_unfreeze_one(struct luo_session *session,
				     struct luo_session_ser *ser)
{
	guard(mutex)(&session->mutex);
	luo_file_unfreeze(&session->file_set, &ser->file_set_ser);
}

static int luo_session_freeze_one(struct luo_session *session,
				  struct luo_session_ser *ser)
{
	guard(mutex)(&session->mutex);
	return luo_file_freeze(&session->file_set, &ser->file_set_ser);
}

static int luo_session_release(struct inode *inodep, struct file *filep)
{
	struct luo_session *session = filep->private_data;
	struct luo_session_header *sh;

	guard(rwsem_read)(&luo_session_serialize_rwsem);
	/* If retrieved is set, it means this session is from incoming list */
	if (session->retrieved) {
		int err = luo_session_finish_one(session);

		if (err) {
			pr_warn("Unable to finish session [%s] on release\n",
				session->name);
			return err;
		}
		sh = &luo_session_global.incoming;
	} else {
		scoped_guard(mutex, &session->mutex)
			luo_file_unpreserve_files(&session->file_set);
		sh = &luo_session_global.outgoing;
	}

	luo_session_remove(sh, session);
	luo_session_free(session);

	return 0;
}

static int luo_session_preserve_fd(struct luo_session *session,
				   struct luo_ucmd *ucmd)
{
	struct liveupdate_session_preserve_fd *argp = ucmd->cmd;
	int err;

	guard(mutex)(&session->mutex);
	err = luo_preserve_file(&session->file_set, argp->token, argp->fd);
	if (err)
		return err;

	err = luo_ucmd_respond(ucmd, sizeof(*argp));
	if (err)
		pr_warn("The file was successfully preserved, but response to user failed\n");

	return err;
}

static int luo_session_retrieve_fd(struct luo_session *session,
				   struct luo_ucmd *ucmd)
{
	struct liveupdate_session_retrieve_fd *argp = ucmd->cmd;
	struct file *file;
	int err;

	argp->fd = get_unused_fd_flags(O_CLOEXEC);
	if (argp->fd < 0)
		return argp->fd;

	mutex_lock(&session->mutex);
	err = luo_retrieve_file(&session->file_set, argp->token, &file);
	mutex_unlock(&session->mutex);
	if (err < 0)
		goto err_put_fd;

	err = luo_ucmd_respond(ucmd, sizeof(*argp));
	if (err)
		goto err_put_file;

	fd_install(argp->fd, file);

	return 0;

err_put_file:
	fput(file);
err_put_fd:
	put_unused_fd(argp->fd);

	return err;
}

static int luo_session_finish(struct luo_session *session,
			      struct luo_ucmd *ucmd)
{
	struct liveupdate_session_finish *argp = ucmd->cmd;
	int err = luo_session_finish_one(session);

	if (err)
		return err;

	return luo_ucmd_respond(ucmd, sizeof(*argp));
}

static int luo_session_get_name(struct luo_session *session,
				struct luo_ucmd *ucmd)
{
	struct liveupdate_session_get_name *argp = ucmd->cmd;

	if (argp->reserved != 0)
		return -EINVAL;

	strscpy((char *)argp->name, session->name, sizeof(argp->name));

	return luo_ucmd_respond(ucmd, sizeof(*argp));
}

union ucmd_buffer {
	struct liveupdate_session_finish finish;
	struct liveupdate_session_preserve_fd preserve;
	struct liveupdate_session_retrieve_fd retrieve;
	struct liveupdate_session_get_name get_name;
};

/* Type of sessions the ioctl applies to. */
enum luo_ioctl_type {
	LUO_IOCTL_INCOMING,
	LUO_IOCTL_OUTGOING,
	LUO_IOCTL_ALL,
};

struct luo_ioctl_op {
	unsigned int size;
	unsigned int min_size;
	unsigned int ioctl_num;
	enum luo_ioctl_type type;
	int (*execute)(struct luo_session *session, struct luo_ucmd *ucmd);
};

#define IOCTL_OP(_ioctl, _fn, _struct, _last, _type)                           \
	[_IOC_NR(_ioctl) - LIVEUPDATE_CMD_SESSION_BASE] = {                    \
		.size = sizeof(_struct) +                                      \
			BUILD_BUG_ON_ZERO(sizeof(union ucmd_buffer) <          \
					  sizeof(_struct)),                    \
		.min_size = offsetofend(_struct, _last),                       \
		.ioctl_num = _ioctl,                                           \
		.type = _type,                                                 \
		.execute = _fn,                                                \
	}

static const struct luo_ioctl_op luo_session_ioctl_ops[] = {
	IOCTL_OP(LIVEUPDATE_SESSION_FINISH, luo_session_finish,
		 struct liveupdate_session_finish, reserved, LUO_IOCTL_INCOMING),
	IOCTL_OP(LIVEUPDATE_SESSION_PRESERVE_FD, luo_session_preserve_fd,
		 struct liveupdate_session_preserve_fd, token, LUO_IOCTL_OUTGOING),
	IOCTL_OP(LIVEUPDATE_SESSION_RETRIEVE_FD, luo_session_retrieve_fd,
		 struct liveupdate_session_retrieve_fd, token, LUO_IOCTL_INCOMING),
	IOCTL_OP(LIVEUPDATE_SESSION_GET_NAME, luo_session_get_name,
		 struct liveupdate_session_get_name, name, LUO_IOCTL_ALL),
};

static bool luo_ioctl_type_valid(struct luo_session *session,
				 const struct luo_ioctl_op *op)
{
	switch (op->type) {
	case LUO_IOCTL_INCOMING:
		/* Retrieved is only set on incoming sessions */
		return session->retrieved;
	case LUO_IOCTL_OUTGOING:
		return !session->retrieved;
	case LUO_IOCTL_ALL:
		return true;
	}

	/* Catch-all. */
	return false;
}

static long luo_session_ioctl(struct file *filep, unsigned int cmd,
			      unsigned long arg)
{
	struct luo_session *session = filep->private_data;
	const struct luo_ioctl_op *op;
	struct luo_ucmd ucmd = {};
	union ucmd_buffer buf;
	unsigned int nr;
	int ret;

	nr = _IOC_NR(cmd);
	if (nr < LIVEUPDATE_CMD_SESSION_BASE || (nr - LIVEUPDATE_CMD_SESSION_BASE) >=
	    ARRAY_SIZE(luo_session_ioctl_ops)) {
		return -EINVAL;
	}

	ucmd.ubuffer = (void __user *)arg;
	ret = get_user(ucmd.user_size, (u32 __user *)ucmd.ubuffer);
	if (ret)
		return ret;

	op = &luo_session_ioctl_ops[nr - LIVEUPDATE_CMD_SESSION_BASE];
	if (op->ioctl_num != cmd)
		return -ENOIOCTLCMD;
	if (!luo_ioctl_type_valid(session, op))
		return -EINVAL;
	if (ucmd.user_size < op->min_size)
		return -EINVAL;

	ucmd.cmd = &buf;
	ret = copy_struct_from_user(ucmd.cmd, op->size, ucmd.ubuffer,
				    ucmd.user_size);
	if (ret)
		return ret;

	guard(rwsem_read)(&luo_session_serialize_rwsem);
	return op->execute(session, &ucmd);
}

static const struct file_operations luo_session_fops = {
	.owner = THIS_MODULE,
	.release = luo_session_release,
	.unlocked_ioctl = luo_session_ioctl,
};

/* Create a "struct file" for session */
static int luo_session_getfile(struct luo_session *session, struct file **filep)
{
	char name_buf[128];
	struct file *file;

	lockdep_assert_held(&session->mutex);
	snprintf(name_buf, sizeof(name_buf), "[luo_session] %s", session->name);
	file = anon_inode_getfile(name_buf, &luo_session_fops, session, O_RDWR);
	if (IS_ERR(file))
		return PTR_ERR(file);

	*filep = file;

	return 0;
}

int luo_session_create(const char *name, struct file **filep)
{
	size_t len = strnlen(name, LIVEUPDATE_SESSION_NAME_LENGTH);
	struct luo_session *session;
	int err;

	if (len == 0 || len > LIVEUPDATE_SESSION_NAME_LENGTH - 1)
		return -EINVAL;

	session = luo_session_alloc(name);
	if (IS_ERR(session))
		return PTR_ERR(session);

	down_read(&luo_session_serialize_rwsem);
	err = luo_session_insert(&luo_session_global.outgoing, session);
	if (err)
		goto err_free;

	mutex_lock(&session->mutex);
	err = luo_session_getfile(session, filep);
	mutex_unlock(&session->mutex);
	if (err)
		goto err_remove;
	up_read(&luo_session_serialize_rwsem);

	return 0;

err_remove:
	luo_session_remove(&luo_session_global.outgoing, session);
err_free:
	luo_session_free(session);
	up_read(&luo_session_serialize_rwsem);

	return err;
}

int luo_session_retrieve(const char *name, struct file **filep)
{
	struct luo_session_header *sh = &luo_session_global.incoming;
	struct luo_session *session = NULL;
	struct luo_session *it;
	int err;

	guard(rwsem_read)(&luo_session_serialize_rwsem);
	guard(rwsem_read)(&sh->rwsem);
	list_for_each_entry(it, &sh->list, list) {
		if (!strncmp(it->name, name, sizeof(it->name))) {
			session = it;
			break;
		}
	}

	if (!session)
		return -ENOENT;

	guard(mutex)(&session->mutex);
	if (session->retrieved)
		return -EINVAL;

	err = luo_session_getfile(session, filep);
	if (!err)
		session->retrieved = true;

	return err;
}

void __init luo_session_setup_outgoing(u64 *sessions_pa)
{
	luo_session_global.outgoing.sessions_pa = sessions_pa;
	luo_session_global.outgoing.active = true;
}

int __init luo_session_setup_incoming(u64 sessions_pa)
{
	struct luo_session_header *sh = &luo_session_global.incoming;
	int err;

	if (!sessions_pa)
		return 0;

	err = kho_block_set_restore(&sh->block_set, sessions_pa);
	if (err)
		return err;

	sh->active = true;
	return 0;
}

static int luo_session_deserialize_one(struct luo_session_header *sh,
				       struct luo_session_ser *ser)
{
	struct luo_session *session;
	int err;

	session = luo_session_alloc(ser->name);
	if (IS_ERR(session)) {
		pr_warn("Failed to allocate session [%.*s] during deserialization %pe\n",
			(int)sizeof(ser->name), ser->name, session);
		return PTR_ERR(session);
	}

	err = luo_session_insert(sh, session);
	if (err) {
		pr_warn("Failed to insert session [%s] %pe\n",
			session->name, ERR_PTR(err));
		luo_session_free(session);
		return err;
	}

	scoped_guard(mutex, &session->mutex) {
		err = luo_file_deserialize(&session->file_set,
					   &ser->file_set_ser);
	}
	if (err) {
		pr_warn("Failed to deserialize files for session [%s] %pe\n",
			session->name, ERR_PTR(err));
		return err;
	}

	return 0;
}

int luo_session_deserialize(void)
{
	struct luo_session_header *sh = &luo_session_global.incoming;
	static bool is_deserialized;
	struct luo_session_ser *ser;
	struct kho_block_set_it it;
	static int saved_err;
	int err;

	/* If has been deserialized, always return the same error code */
	if (is_deserialized)
		return saved_err;

	is_deserialized = true;
	if (!sh->active)
		return 0;

	/*
	 * Note on error handling:
	 *
	 * If deserialization fails (e.g., allocation failure or corrupt data),
	 * we intentionally skip cleanup of sessions that were already restored.
	 *
	 * A partial failure leaves the preserved state inconsistent.
	 * Implementing a safe "undo" to unwind complex dependencies (sessions,
	 * files, hardware state) is error-prone and provides little value, as
	 * the system is effectively in a broken state.
	 *
	 * We treat these resources as leaked. The expected recovery path is for
	 * userspace to detect the failure and trigger a reboot, which will
	 * reliably reset devices and reclaim memory.
	 */
	kho_block_set_it_init(&it, &sh->block_set);
	while ((ser = kho_block_set_it_read_entry(&it))) {
		err = luo_session_deserialize_one(sh, ser);
		if (err)
			goto save_err;
	}

	kho_block_set_destroy(&sh->block_set);

	return 0;

save_err:
	kho_block_set_destroy(&sh->block_set);
	saved_err = err;
	return err;
}

int luo_session_serialize(void)
{
	struct luo_session_header *sh = &luo_session_global.outgoing;
	struct luo_session *session;
	struct kho_block_set_it it;
	int err;

	down_write(&luo_session_serialize_rwsem);
	down_write(&sh->rwsem);
	*sh->sessions_pa = 0;

	kho_block_set_it_init(&it, &sh->block_set);

	list_for_each_entry(session, &sh->list, list) {
		struct luo_session_ser *ser = kho_block_set_it_reserve_entry(&it);

		/* This should not fail normally as blocks were pre-allocated */
		if (WARN_ON_ONCE(!ser)) {
			err = -ENOSPC;
			goto err_undo;
		}

		err = luo_session_freeze_one(session, ser);
		if (err) {
			kho_block_set_it_prev(&it);
			goto err_undo;
		}

		strscpy(ser->name, session->name, sizeof(ser->name));
	}

	if (sh->count > 0)
		*sh->sessions_pa = kho_block_set_head_pa(&sh->block_set);
	up_write(&sh->rwsem);

	return 0;

err_undo:
	list_for_each_entry_continue_reverse(session, &sh->list, list) {
		struct luo_session_ser *ser = kho_block_set_it_prev(&it);

		luo_session_unfreeze_one(session, ser);
		memset(ser->name, 0, sizeof(ser->name));
	}
	up_write(&sh->rwsem);
	up_write(&luo_session_serialize_rwsem);

	return err;
}
