// SPDX-License-Identifier: GPL-2.0
/* Copyright (C) 2018 Google, Inc. */
#include "gasket.h"
#include "gasket_ioctl.h"
#include "gasket_constants.h"
#include "gasket_core.h"
#include "gasket_interrupt.h"
#include "gasket_page_table.h"
#include <linux/compiler.h>
#include <linux/device.h>
#include <linux/fs.h>
#include <linux/uaccess.h>

#ifdef GASKET_KERNEL_TRACE_SUPPORT
#define CREATE_TRACE_POINTS
#include <trace/events/gasket_ioctl.h>
#else
#define trace_gasket_ioctl_entry(x, ...)
#define trace_gasket_ioctl_exit(x)
#define trace_gasket_ioctl_integer_data(x)
#define trace_gasket_ioctl_eventfd_data(x, ...)
#define trace_gasket_ioctl_page_table_data(x, ...)
#define trace_gasket_ioctl_config_coherent_allocator(x, ...)
#endif

/* Associate an eventfd with an interrupt. */
static int gasket_set_event_fd(struct gasket_dev *gasket_dev,
			       struct gasket_interrupt_eventfd __user *argp)
{
	struct gasket_interrupt_eventfd die;

	if (copy_from_user(&die, argp, sizeof(struct gasket_interrupt_eventfd)))
		return -EFAULT;

	trace_gasket_ioctl_eventfd_data(die.interrupt, die.event_fd);

	return gasket_interrupt_set_eventfd(gasket_dev->interrupt_data,
					    die.interrupt, die.event_fd);
}

/* Read the size of the page table. */
static int gasket_read_page_table_size(struct gasket_dev *gasket_dev,
	struct gasket_page_table_ioctl __user *argp)
{
	int ret = 0;
	struct gasket_page_table_ioctl ibuf;

	if (copy_from_user(&ibuf, argp, sizeof(struct gasket_page_table_ioctl)))
		return -EFAULT;

	if (ibuf.page_table_index >= gasket_dev->num_page_tables)
		return -EFAULT;

	ibuf.size = gasket_page_table_num_entries(
		gasket_dev->page_table[ibuf.page_table_index]);

	trace_gasket_ioctl_page_table_data(ibuf.page_table_index, ibuf.size,
					   ibuf.host_address,
					   ibuf.device_address);

	if (copy_to_user(argp, &ibuf, sizeof(ibuf)))
		return -EFAULT;

	return ret;
}

/* Read the size of the simple page table. */
static int gasket_read_simple_page_table_size(struct gasket_dev *gasket_dev,
	struct gasket_page_table_ioctl __user *argp)
{
	int ret = 0;
	struct gasket_page_table_ioctl ibuf;

	if (copy_from_user(&ibuf, argp, sizeof(struct gasket_page_table_ioctl)))
		return -EFAULT;

	if (ibuf.page_table_index >= gasket_dev->num_page_tables)
		return -EFAULT;

	ibuf.size =
		gasket_page_table_num_simple_entries(gasket_dev->page_table[ibuf.page_table_index]);

	trace_gasket_ioctl_page_table_data(ibuf.page_table_index, ibuf.size,
					   ibuf.host_address,
					   ibuf.device_address);

	if (copy_to_user(argp, &ibuf, sizeof(ibuf)))
		return -EFAULT;

	return ret;
}

/* Set the boundary between the simple and extended page tables. */
static int gasket_partition_page_table(struct gasket_dev *gasket_dev,
	struct gasket_page_table_ioctl __user *argp)
{
	int ret;
	struct gasket_page_table_ioctl ibuf;
	uint max_page_table_size;

	if (copy_from_user(&ibuf, argp, sizeof(struct gasket_page_table_ioctl)))
		return -EFAULT;

	trace_gasket_ioctl_page_table_data(ibuf.page_table_index, ibuf.size,
					   ibuf.host_address,
					   ibuf.device_address);

	if (ibuf.page_table_index >= gasket_dev->num_page_tables)
		return -EFAULT;
	max_page_table_size = gasket_page_table_max_size(
		gasket_dev->page_table[ibuf.page_table_index]);

	if (ibuf.size > max_page_table_size) {
		dev_dbg(gasket_dev->dev,
			"Partition request 0x%llx too large, max is 0x%x\n",
			ibuf.size, max_page_table_size);
		return -EINVAL;
	}

	mutex_lock(&gasket_dev->mutex);

	ret = gasket_page_table_partition(
		gasket_dev->page_table[ibuf.page_table_index], ibuf.size);
	mutex_unlock(&gasket_dev->mutex);

	return ret;
}

/* Map a userspace buffer to a device virtual address. */
static int gasket_map_buffers(struct gasket_dev *gasket_dev,
			      struct gasket_page_table_ioctl __user *argp)
{
	struct gasket_page_table_ioctl ibuf;

	if (copy_from_user(&ibuf, argp, sizeof(struct gasket_page_table_ioctl)))
		return -EFAULT;

	trace_gasket_ioctl_page_table_data(ibuf.page_table_index, ibuf.size,
					   ibuf.host_address,
					   ibuf.device_address);

	if (ibuf.page_table_index >= gasket_dev->num_page_tables)
		return -EFAULT;

	if (gasket_page_table_are_addrs_bad(gasket_dev->page_table[ibuf.page_table_index],
					    ibuf.host_address,
					    ibuf.device_address, ibuf.size))
		return -EINVAL;

	return gasket_page_table_map(gasket_dev->page_table[ibuf.page_table_index],
				     ibuf.host_address, ibuf.device_address,
				     ibuf.size / PAGE_SIZE);
}

/* Unmap a userspace buffer from a device virtual address. */
static int gasket_unmap_buffers(struct gasket_dev *gasket_dev,
				struct gasket_page_table_ioctl __user *argp)
{
	struct gasket_page_table_ioctl ibuf;

	if (copy_from_user(&ibuf, argp, sizeof(struct gasket_page_table_ioctl)))
		return -EFAULT;

	trace_gasket_ioctl_page_table_data(ibuf.page_table_index, ibuf.size,
					   ibuf.host_address,
					   ibuf.device_address);

	if (ibuf.page_table_index >= gasket_dev->num_page_tables)
		return -EFAULT;

	if (gasket_page_table_is_dev_addr_bad(gasket_dev->page_table[ibuf.page_table_index],
					      ibuf.device_address, ibuf.size))
		return -EINVAL;

	gasket_page_table_unmap(gasket_dev->page_table[ibuf.page_table_index],
				ibuf.device_address, ibuf.size / PAGE_SIZE);

	return 0;
}

/*
 * Reserve structures for coherent allocation, and allocate or free the
 * corresponding memory.
 */
static int gasket_config_coherent_allocator(struct gasket_dev *gasket_dev,
	struct gasket_coherent_alloc_config_ioctl __user *argp)
{
	int ret;
	struct gasket_coherent_alloc_config_ioctl ibuf;

	if (copy_from_user(&ibuf, argp,
			   sizeof(struct gasket_coherent_alloc_config_ioctl)))
		return -EFAULT;

	trace_gasket_ioctl_config_coherent_allocator(ibuf.enable, ibuf.size,
						     ibuf.dma_address);

	if (ibuf.page_table_index >= gasket_dev->num_page_tables)
		return -EFAULT;

	if (ibuf.size > PAGE_SIZE * MAX_NUM_COHERENT_PAGES)
		return -ENOMEM;

	if (ibuf.enable == 0) {
		ret = gasket_free_coherent_memory(gasket_dev, ibuf.size,
						  ibuf.dma_address,
						  ibuf.page_table_index);
	} else {
		ret = gasket_alloc_coherent_memory(gasket_dev, ibuf.size,
						   &ibuf.dma_address,
						   ibuf.page_table_index);
	}
	if (ret)
		return ret;
	if (copy_to_user(argp, &ibuf, sizeof(ibuf)))
		return -EFAULT;

	return 0;
}

/* Check permissions for Gasket ioctls. */
static bool gasket_ioctl_check_permissions(struct file *filp, uint cmd)
{
	bool alive;
	bool read, write;
	struct gasket_dev *gasket_dev = (struct gasket_dev *)filp->private_data;

	alive = (gasket_dev->status == GASKET_STATUS_ALIVE);
	if (!alive)
		dev_dbg(gasket_dev->dev, "%s alive %d status %d\n",
			__func__, alive, gasket_dev->status);

	read = !!(filp->f_mode & FMODE_READ);
	write = !!(filp->f_mode & FMODE_WRITE);

	switch (cmd) {
	case GASKET_IOCTL_RESET:
	case GASKET_IOCTL_CLEAR_INTERRUPT_COUNTS:
		return write;

	case GASKET_IOCTL_PAGE_TABLE_SIZE:
	case GASKET_IOCTL_SIMPLE_PAGE_TABLE_SIZE:
	case GASKET_IOCTL_NUMBER_PAGE_TABLES:
		return read;

	case GASKET_IOCTL_PARTITION_PAGE_TABLE:
	case GASKET_IOCTL_CONFIG_COHERENT_ALLOCATOR:
		return alive && write;

	case GASKET_IOCTL_MAP_BUFFER:
	case GASKET_IOCTL_UNMAP_BUFFER:
		return alive && write;

	case GASKET_IOCTL_CLEAR_EVENTFD:
	case GASKET_IOCTL_SET_EVENTFD:
		return alive && write;
	}

	return false; /* unknown permissions */
}

/*
 * standard ioctl dispatch function.
 * @filp: File structure pointer describing this node usage session.
 * @cmd: ioctl number to handle.
 * @argp: ioctl-specific data pointer.
 *
 * Standard ioctl dispatcher; forwards operations to individual handlers.
 */
long gasket_handle_ioctl(struct file *filp, uint cmd, void __user *argp)
{
	struct gasket_dev *gasket_dev;
	unsigned long arg = (unsigned long)argp;
	gasket_ioctl_permissions_cb_t ioctl_permissions_cb;
	int retval;

	gasket_dev = (struct gasket_dev *)filp->private_data;
	trace_gasket_ioctl_entry(gasket_dev->dev_info.name, cmd);

	ioctl_permissions_cb = gasket_get_ioctl_permissions_cb(gasket_dev);
	if (ioctl_permissions_cb) {
		retval = ioctl_permissions_cb(filp, cmd, argp);
		if (retval < 0) {
			trace_gasket_ioctl_exit(retval);
			return retval;
		} else if (retval == 0) {
			trace_gasket_ioctl_exit(-EPERM);
			return -EPERM;
		}
	} else if (!gasket_ioctl_check_permissions(filp, cmd)) {
		trace_gasket_ioctl_exit(-EPERM);
		dev_dbg(gasket_dev->dev, "ioctl cmd=%x noperm\n", cmd);
		return -EPERM;
	}

	/* Tracing happens in this switch statement for all ioctls with
	 * an integer argrument, but ioctls with a struct argument
	 * that needs copying and decoding, that tracing is done within
	 * the handler call.
	 */
	switch (cmd) {
	case GASKET_IOCTL_RESET:
		retval = gasket_reset(gasket_dev);
		break;
	case GASKET_IOCTL_SET_EVENTFD:
		retval = gasket_set_event_fd(gasket_dev, argp);
		break;
	case GASKET_IOCTL_CLEAR_EVENTFD:
		trace_gasket_ioctl_integer_data(arg);
		retval =
			gasket_interrupt_clear_eventfd(gasket_dev->interrupt_data,
						       (int)arg);
		break;
	case GASKET_IOCTL_PARTITION_PAGE_TABLE:
		trace_gasket_ioctl_integer_data(arg);
		retval = gasket_partition_page_table(gasket_dev, argp);
		break;
	case GASKET_IOCTL_NUMBER_PAGE_TABLES:
		trace_gasket_ioctl_integer_data(gasket_dev->num_page_tables);
		if (copy_to_user(argp, &gasket_dev->num_page_tables,
				 sizeof(uint64_t)))
			retval = -EFAULT;
		else
			retval = 0;
		break;
	case GASKET_IOCTL_PAGE_TABLE_SIZE:
		retval = gasket_read_page_table_size(gasket_dev, argp);
		break;
	case GASKET_IOCTL_SIMPLE_PAGE_TABLE_SIZE:
		retval = gasket_read_simple_page_table_size(gasket_dev, argp);
		break;
	case GASKET_IOCTL_MAP_BUFFER:
		retval = gasket_map_buffers(gasket_dev, argp);
		break;
	case GASKET_IOCTL_CONFIG_COHERENT_ALLOCATOR:
		retval = gasket_config_coherent_allocator(gasket_dev, argp);
		break;
	case GASKET_IOCTL_UNMAP_BUFFER:
		retval = gasket_unmap_buffers(gasket_dev, argp);
		break;
	case GASKET_IOCTL_CLEAR_INTERRUPT_COUNTS:
		/* Clear interrupt counts doesn't take an arg, so use 0. */
		trace_gasket_ioctl_integer_data(0);
		retval = gasket_interrupt_reset_counts(gasket_dev);
		break;
	default:
		/* If we don't understand the ioctl, the best we can do is trace
		 * the arg.
		 */
		trace_gasket_ioctl_integer_data(arg);
		dev_dbg(gasket_dev->dev,
			"Unknown ioctl cmd=0x%x not caught by gasket_is_supported_ioctl\n",
			cmd);
		retval = -EINVAL;
		break;
	}

	trace_gasket_ioctl_exit(retval);
	return retval;
}

/*
 * Determines if an ioctl is part of the standard Gasket framework.
 * @cmd: The ioctl number to handle.
 *
 * Returns 1 if the ioctl is supported and 0 otherwise.
 */
long gasket_is_supported_ioctl(uint cmd)
{
	switch (cmd) {
	case GASKET_IOCTL_RESET:
	case GASKET_IOCTL_SET_EVENTFD:
	case GASKET_IOCTL_CLEAR_EVENTFD:
	case GASKET_IOCTL_PARTITION_PAGE_TABLE:
	case GASKET_IOCTL_NUMBER_PAGE_TABLES:
	case GASKET_IOCTL_PAGE_TABLE_SIZE:
	case GASKET_IOCTL_SIMPLE_PAGE_TABLE_SIZE:
	case GASKET_IOCTL_MAP_BUFFER:
	case GASKET_IOCTL_UNMAP_BUFFER:
	case GASKET_IOCTL_CLEAR_INTERRUPT_COUNTS:
	case GASKET_IOCTL_CONFIG_COHERENT_ALLOCATOR:
		return 1;
	default:
		return 0;
	}
}
