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