// SPDX-License-Identifier: GPL-2.0+
// Copyright 2017 IBM Corp.
#include <linux/fs.h>
#include <linux/poll.h>
#include <linux/sched/signal.h>
#include <linux/eventfd.h>
#include <linux/uaccess.h>
#include <uapi/misc/ocxl.h>
#include <asm/reg.h>
#include <asm/switch_to.h>
#include "ocxl_internal.h"


#define OCXL_NUM_MINORS 256 /* Total to reserve */

static dev_t ocxl_dev;
static struct class *ocxl_class;
static DEFINE_MUTEX(minors_idr_lock);
static struct idr minors_idr;

static struct ocxl_file_info *find_and_get_file_info(dev_t devno)
{
	struct ocxl_file_info *info;

	mutex_lock(&minors_idr_lock);
	info = idr_find(&minors_idr, MINOR(devno));
	if (info)
		get_device(&info->dev);
	mutex_unlock(&minors_idr_lock);
	return info;
}

static int allocate_minor(struct ocxl_file_info *info)
{
	int minor;

	mutex_lock(&minors_idr_lock);
	minor = idr_alloc(&minors_idr, info, 0, OCXL_NUM_MINORS, GFP_KERNEL);
	mutex_unlock(&minors_idr_lock);
	return minor;
}

static void free_minor(struct ocxl_file_info *info)
{
	mutex_lock(&minors_idr_lock);
	idr_remove(&minors_idr, MINOR(info->dev.devt));
	mutex_unlock(&minors_idr_lock);
}

static int afu_open(struct inode *inode, struct file *file)
{
	struct ocxl_file_info *info;
	struct ocxl_context *ctx;
	int rc;

	pr_debug("%s for device %x\n", __func__, inode->i_rdev);

	info = find_and_get_file_info(inode->i_rdev);
	if (!info)
		return -ENODEV;

	rc = ocxl_context_alloc(&ctx, info->afu, inode->i_mapping);
	if (rc) {
		put_device(&info->dev);
		return rc;
	}
	put_device(&info->dev);
	file->private_data = ctx;
	return 0;
}

static long afu_ioctl_attach(struct ocxl_context *ctx,
			struct ocxl_ioctl_attach __user *uarg)
{
	struct ocxl_ioctl_attach arg;
	u64 amr = 0;
	int rc;

	pr_debug("%s for context %d\n", __func__, ctx->pasid);

	if (copy_from_user(&arg, uarg, sizeof(arg)))
		return -EFAULT;

	/* Make sure reserved fields are not set for forward compatibility */
	if (arg.reserved1 || arg.reserved2 || arg.reserved3)
		return -EINVAL;

	amr = arg.amr & mfspr(SPRN_UAMOR);
	rc = ocxl_context_attach(ctx, amr, current->mm);
	return rc;
}

static long afu_ioctl_get_metadata(struct ocxl_context *ctx,
		struct ocxl_ioctl_metadata __user *uarg)
{
	struct ocxl_ioctl_metadata arg;

	memset(&arg, 0, sizeof(arg));

	arg.version = 0;

	arg.afu_version_major = ctx->afu->config.version_major;
	arg.afu_version_minor = ctx->afu->config.version_minor;
	arg.pasid = ctx->pasid;
	arg.pp_mmio_size = ctx->afu->config.pp_mmio_stride;
	arg.global_mmio_size = ctx->afu->config.global_mmio_size;

	if (copy_to_user(uarg, &arg, sizeof(arg)))
		return -EFAULT;

	return 0;
}

#ifdef CONFIG_PPC64
static long afu_ioctl_enable_p9_wait(struct ocxl_context *ctx,
		struct ocxl_ioctl_p9_wait __user *uarg)
{
	struct ocxl_ioctl_p9_wait arg;

	memset(&arg, 0, sizeof(arg));

	if (cpu_has_feature(CPU_FTR_P9_TIDR)) {
		enum ocxl_context_status status;

		// Locks both status & tidr
		mutex_lock(&ctx->status_mutex);
		if (!ctx->tidr) {
			if (set_thread_tidr(current)) {
				mutex_unlock(&ctx->status_mutex);
				return -ENOENT;
			}

			ctx->tidr = current->thread.tidr;
		}

		status = ctx->status;
		mutex_unlock(&ctx->status_mutex);

		if (status == ATTACHED) {
			int rc = ocxl_link_update_pe(ctx->afu->fn->link,
				ctx->pasid, ctx->tidr);

			if (rc)
				return rc;
		}

		arg.thread_id = ctx->tidr;
	} else
		return -ENOENT;

	if (copy_to_user(uarg, &arg, sizeof(arg)))
		return -EFAULT;

	return 0;
}
#endif


static long afu_ioctl_get_features(struct ocxl_context *ctx,
		struct ocxl_ioctl_features __user *uarg)
{
	struct ocxl_ioctl_features arg;

	memset(&arg, 0, sizeof(arg));

#ifdef CONFIG_PPC64
	if (cpu_has_feature(CPU_FTR_P9_TIDR))
		arg.flags[0] |= OCXL_IOCTL_FEATURES_FLAGS0_P9_WAIT;
#endif

	if (copy_to_user(uarg, &arg, sizeof(arg)))
		return -EFAULT;

	return 0;
}

#define CMD_STR(x) (x == OCXL_IOCTL_ATTACH ? "ATTACH" :			\
			x == OCXL_IOCTL_IRQ_ALLOC ? "IRQ_ALLOC" :	\
			x == OCXL_IOCTL_IRQ_FREE ? "IRQ_FREE" :		\
			x == OCXL_IOCTL_IRQ_SET_FD ? "IRQ_SET_FD" :	\
			x == OCXL_IOCTL_GET_METADATA ? "GET_METADATA" :	\
			x == OCXL_IOCTL_ENABLE_P9_WAIT ? "ENABLE_P9_WAIT" :	\
			x == OCXL_IOCTL_GET_FEATURES ? "GET_FEATURES" :	\
			"UNKNOWN")

static irqreturn_t irq_handler(void *private)
{
	struct eventfd_ctx *ev_ctx = private;

	eventfd_signal(ev_ctx, 1);
	return IRQ_HANDLED;
}

static void irq_free(void *private)
{
	struct eventfd_ctx *ev_ctx = private;

	eventfd_ctx_put(ev_ctx);
}

static long afu_ioctl(struct file *file, unsigned int cmd,
		unsigned long args)
{
	struct ocxl_context *ctx = file->private_data;
	struct ocxl_ioctl_irq_fd irq_fd;
	struct eventfd_ctx *ev_ctx;
	int irq_id;
	u64 irq_offset;
	long rc;
	bool closed;

	pr_debug("%s for context %d, command %s\n", __func__, ctx->pasid,
		CMD_STR(cmd));

	mutex_lock(&ctx->status_mutex);
	closed = (ctx->status == CLOSED);
	mutex_unlock(&ctx->status_mutex);

	if (closed)
		return -EIO;

	switch (cmd) {
	case OCXL_IOCTL_ATTACH:
		rc = afu_ioctl_attach(ctx,
				(struct ocxl_ioctl_attach __user *) args);
		break;

	case OCXL_IOCTL_IRQ_ALLOC:
		rc = ocxl_afu_irq_alloc(ctx, &irq_id);
		if (!rc) {
			irq_offset = ocxl_irq_id_to_offset(ctx, irq_id);
			rc = copy_to_user((u64 __user *) args, &irq_offset,
					sizeof(irq_offset));
			if (rc) {
				ocxl_afu_irq_free(ctx, irq_id);
				return -EFAULT;
			}
		}
		break;

	case OCXL_IOCTL_IRQ_FREE:
		rc = copy_from_user(&irq_offset, (u64 __user *) args,
				sizeof(irq_offset));
		if (rc)
			return -EFAULT;
		irq_id = ocxl_irq_offset_to_id(ctx, irq_offset);
		rc = ocxl_afu_irq_free(ctx, irq_id);
		break;

	case OCXL_IOCTL_IRQ_SET_FD:
		rc = copy_from_user(&irq_fd, (u64 __user *) args,
				sizeof(irq_fd));
		if (rc)
			return -EFAULT;
		if (irq_fd.reserved)
			return -EINVAL;
		irq_id = ocxl_irq_offset_to_id(ctx, irq_fd.irq_offset);
		ev_ctx = eventfd_ctx_fdget(irq_fd.eventfd);
		if (IS_ERR(ev_ctx))
			return PTR_ERR(ev_ctx);
		rc = ocxl_irq_set_handler(ctx, irq_id, irq_handler, irq_free, ev_ctx);
		if (rc)
			eventfd_ctx_put(ev_ctx);
		break;

	case OCXL_IOCTL_GET_METADATA:
		rc = afu_ioctl_get_metadata(ctx,
				(struct ocxl_ioctl_metadata __user *) args);
		break;

#ifdef CONFIG_PPC64
	case OCXL_IOCTL_ENABLE_P9_WAIT:
		rc = afu_ioctl_enable_p9_wait(ctx,
				(struct ocxl_ioctl_p9_wait __user *) args);
		break;
#endif

	case OCXL_IOCTL_GET_FEATURES:
		rc = afu_ioctl_get_features(ctx,
				(struct ocxl_ioctl_features __user *) args);
		break;

	default:
		rc = -EINVAL;
	}
	return rc;
}

static long afu_compat_ioctl(struct file *file, unsigned int cmd,
			unsigned long args)
{
	return afu_ioctl(file, cmd, args);
}

static int afu_mmap(struct file *file, struct vm_area_struct *vma)
{
	struct ocxl_context *ctx = file->private_data;

	pr_debug("%s for context %d\n", __func__, ctx->pasid);
	return ocxl_context_mmap(ctx, vma);
}

static bool has_xsl_error(struct ocxl_context *ctx)
{
	bool ret;

	mutex_lock(&ctx->xsl_error_lock);
	ret = !!ctx->xsl_error.addr;
	mutex_unlock(&ctx->xsl_error_lock);

	return ret;
}

/*
 * Are there any events pending on the AFU
 * ctx: The AFU context
 * Returns: true if there are events pending
 */
static bool afu_events_pending(struct ocxl_context *ctx)
{
	if (has_xsl_error(ctx))
		return true;
	return false;
}

static unsigned int afu_poll(struct file *file, struct poll_table_struct *wait)
{
	struct ocxl_context *ctx = file->private_data;
	unsigned int mask = 0;
	bool closed;

	pr_debug("%s for context %d\n", __func__, ctx->pasid);

	poll_wait(file, &ctx->events_wq, wait);

	mutex_lock(&ctx->status_mutex);
	closed = (ctx->status == CLOSED);
	mutex_unlock(&ctx->status_mutex);

	if (afu_events_pending(ctx))
		mask = EPOLLIN | EPOLLRDNORM;
	else if (closed)
		mask = EPOLLERR;

	return mask;
}

/*
 * Populate the supplied buffer with a single XSL error
 * ctx:	The AFU context to report the error from
 * header: the event header to populate
 * buf: The buffer to write the body into (should be at least
 *      AFU_EVENT_BODY_XSL_ERROR_SIZE)
 * Return: the amount of buffer that was populated
 */
static ssize_t append_xsl_error(struct ocxl_context *ctx,
				struct ocxl_kernel_event_header *header,
				char __user *buf)
{
	struct ocxl_kernel_event_xsl_fault_error body;

	memset(&body, 0, sizeof(body));

	mutex_lock(&ctx->xsl_error_lock);
	if (!ctx->xsl_error.addr) {
		mutex_unlock(&ctx->xsl_error_lock);
		return 0;
	}

	body.addr = ctx->xsl_error.addr;
	body.dsisr = ctx->xsl_error.dsisr;
	body.count = ctx->xsl_error.count;

	ctx->xsl_error.addr = 0;
	ctx->xsl_error.dsisr = 0;
	ctx->xsl_error.count = 0;

	mutex_unlock(&ctx->xsl_error_lock);

	header->type = OCXL_AFU_EVENT_XSL_FAULT_ERROR;

	if (copy_to_user(buf, &body, sizeof(body)))
		return -EFAULT;

	return sizeof(body);
}

#define AFU_EVENT_BODY_MAX_SIZE sizeof(struct ocxl_kernel_event_xsl_fault_error)

/*
 * Reports events on the AFU
 * Format:
 *	Header (struct ocxl_kernel_event_header)
 *	Body (struct ocxl_kernel_event_*)
 *	Header...
 */
static ssize_t afu_read(struct file *file, char __user *buf, size_t count,
			loff_t *off)
{
	struct ocxl_context *ctx = file->private_data;
	struct ocxl_kernel_event_header header;
	ssize_t rc;
	ssize_t used = 0;
	DEFINE_WAIT(event_wait);

	memset(&header, 0, sizeof(header));

	/* Require offset to be 0 */
	if (*off != 0)
		return -EINVAL;

	if (count < (sizeof(struct ocxl_kernel_event_header) +
			AFU_EVENT_BODY_MAX_SIZE))
		return -EINVAL;

	for (;;) {
		prepare_to_wait(&ctx->events_wq, &event_wait,
				TASK_INTERRUPTIBLE);

		if (afu_events_pending(ctx))
			break;

		if (ctx->status == CLOSED)
			break;

		if (file->f_flags & O_NONBLOCK) {
			finish_wait(&ctx->events_wq, &event_wait);
			return -EAGAIN;
		}

		if (signal_pending(current)) {
			finish_wait(&ctx->events_wq, &event_wait);
			return -ERESTARTSYS;
		}

		schedule();
	}

	finish_wait(&ctx->events_wq, &event_wait);

	if (has_xsl_error(ctx)) {
		used = append_xsl_error(ctx, &header, buf + sizeof(header));
		if (used < 0)
			return used;
	}

	if (!afu_events_pending(ctx))
		header.flags |= OCXL_KERNEL_EVENT_FLAG_LAST;

	if (copy_to_user(buf, &header, sizeof(header)))
		return -EFAULT;

	used += sizeof(header);

	rc = used;
	return rc;
}

static int afu_release(struct inode *inode, struct file *file)
{
	struct ocxl_context *ctx = file->private_data;
	int rc;

	pr_debug("%s for device %x\n", __func__, inode->i_rdev);
	rc = ocxl_context_detach(ctx);
	mutex_lock(&ctx->mapping_lock);
	ctx->mapping = NULL;
	mutex_unlock(&ctx->mapping_lock);
	wake_up_all(&ctx->events_wq);
	if (rc != -EBUSY)
		ocxl_context_free(ctx);
	return 0;
}

static const struct file_operations ocxl_afu_fops = {
	.owner		= THIS_MODULE,
	.open           = afu_open,
	.unlocked_ioctl = afu_ioctl,
	.compat_ioctl   = afu_compat_ioctl,
	.mmap           = afu_mmap,
	.poll           = afu_poll,
	.read           = afu_read,
	.release        = afu_release,
};

// Free the info struct
static void info_release(struct device *dev)
{
	struct ocxl_file_info *info = container_of(dev, struct ocxl_file_info, dev);

	ocxl_afu_put(info->afu);
	kfree(info);
}

static int ocxl_file_make_visible(struct ocxl_file_info *info)
{
	int rc;

	cdev_init(&info->cdev, &ocxl_afu_fops);
	rc = cdev_add(&info->cdev, info->dev.devt, 1);
	if (rc) {
		dev_err(&info->dev, "Unable to add afu char device: %d\n", rc);
		return rc;
	}

	return 0;
}

static void ocxl_file_make_invisible(struct ocxl_file_info *info)
{
	cdev_del(&info->cdev);
}

int ocxl_file_register_afu(struct ocxl_afu *afu)
{
	int minor;
	int rc;
	struct ocxl_file_info *info;
	struct ocxl_fn *fn = afu->fn;
	struct pci_dev *pci_dev = to_pci_dev(fn->dev.parent);

	info = kzalloc(sizeof(*info), GFP_KERNEL);
	if (info == NULL)
		return -ENOMEM;

	minor = allocate_minor(info);
	if (minor < 0) {
		kfree(info);
		return minor;
	}

	info->dev.parent = &fn->dev;
	info->dev.devt = MKDEV(MAJOR(ocxl_dev), minor);
	info->dev.class = ocxl_class;
	info->dev.release = info_release;

	info->afu = afu;
	ocxl_afu_get(afu);

	rc = dev_set_name(&info->dev, "%s.%s.%hhu",
		afu->config.name, dev_name(&pci_dev->dev), afu->config.idx);
	if (rc)
		goto err_put;

	rc = device_register(&info->dev);
	if (rc)
		goto err_put;

	rc = ocxl_sysfs_register_afu(info);
	if (rc)
		goto err_unregister;

	rc = ocxl_file_make_visible(info);
	if (rc)
		goto err_unregister;

	ocxl_afu_set_private(afu, info);

	return 0;

err_unregister:
	ocxl_sysfs_unregister_afu(info); // safe to call even if register failed
	free_minor(info);
	device_unregister(&info->dev);
	return rc;
err_put:
	ocxl_afu_put(afu);
	free_minor(info);
	kfree(info);
	return rc;
}

void ocxl_file_unregister_afu(struct ocxl_afu *afu)
{
	struct ocxl_file_info *info = ocxl_afu_get_private(afu);

	if (!info)
		return;

	ocxl_file_make_invisible(info);
	ocxl_sysfs_unregister_afu(info);
	free_minor(info);
	device_unregister(&info->dev);
}

static char *ocxl_devnode(struct device *dev, umode_t *mode)
{
	return kasprintf(GFP_KERNEL, "ocxl/%s", dev_name(dev));
}

int ocxl_file_init(void)
{
	int rc;

	idr_init(&minors_idr);

	rc = alloc_chrdev_region(&ocxl_dev, 0, OCXL_NUM_MINORS, "ocxl");
	if (rc) {
		pr_err("Unable to allocate ocxl major number: %d\n", rc);
		return rc;
	}

	ocxl_class = class_create(THIS_MODULE, "ocxl");
	if (IS_ERR(ocxl_class)) {
		pr_err("Unable to create ocxl class\n");
		unregister_chrdev_region(ocxl_dev, OCXL_NUM_MINORS);
		return PTR_ERR(ocxl_class);
	}

	ocxl_class->devnode = ocxl_devnode;
	return 0;
}

void ocxl_file_exit(void)
{
	class_destroy(ocxl_class);
	unregister_chrdev_region(ocxl_dev, OCXL_NUM_MINORS);
	idr_destroy(&minors_idr);
}
