// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (C) 2004 IBM Corporation
 * Authors:
 * Leendert van Doorn <leendert@watson.ibm.com>
 * Dave Safford <safford@watson.ibm.com>
 * Reiner Sailer <sailer@watson.ibm.com>
 * Kylene Hall <kjhall@us.ibm.com>
 *
 * Copyright (C) 2013 Obsidian Research Corp
 * Jason Gunthorpe <jgunthorpe@obsidianresearch.com>
 *
 * Device file system interface to the TPM
 */
#include <linux/poll.h>
#include <linux/slab.h>
#include <linux/uaccess.h>
#include <linux/workqueue.h>
#include "tpm.h"
#include "tpm-dev.h"

static struct workqueue_struct *tpm_dev_wq;

static ssize_t tpm_dev_transmit(struct tpm_chip *chip, struct tpm_space *space,
				u8 *buf, size_t bufsiz)
{
	struct tpm_header *header = (void *)buf;
	ssize_t ret, len;

	if (chip->flags & TPM_CHIP_FLAG_TPM2)
		tpm2_end_auth_session(chip);

	ret = tpm2_prepare_space(chip, space, buf, bufsiz);
	/* If the command is not implemented by the TPM, synthesize a
	 * response with a TPM2_RC_COMMAND_CODE return for user-space.
	 */
	if (ret == -EOPNOTSUPP) {
		header->length = cpu_to_be32(sizeof(*header));
		header->tag = cpu_to_be16(TPM2_ST_NO_SESSIONS);
		header->return_code = cpu_to_be32(TPM2_RC_COMMAND_CODE |
						  TSS2_RESMGR_TPM_RC_LAYER);
		ret = sizeof(*header);
	}
	if (ret)
		goto out_rc;

	len = tpm_transmit(chip, buf, bufsiz);
	if (len < 0)
		ret = len;

	if (!ret)
		ret = tpm2_commit_space(chip, space, buf, &len);
	else
		tpm2_flush_space(chip);

out_rc:
	return ret ? ret : len;
}

static void tpm_dev_async_work(struct work_struct *work)
{
	struct file_priv *priv =
			container_of(work, struct file_priv, async_work);
	ssize_t ret;

	mutex_lock(&priv->buffer_mutex);
	priv->command_enqueued = false;
	ret = tpm_try_get_ops(priv->chip);
	if (ret) {
		priv->response_length = ret;
		goto out;
	}

	ret = tpm_dev_transmit(priv->chip, priv->space, priv->data_buffer,
			       sizeof(priv->data_buffer));
	tpm_put_ops(priv->chip);

	/*
	 * If ret is > 0 then tpm_dev_transmit returned the size of the
	 * response. If ret is < 0 then tpm_dev_transmit failed and
	 * returned an error code.
	 */
	if (ret != 0) {
		priv->response_length = ret;
		mod_timer(&priv->user_read_timer, jiffies + (120 * HZ));
	}
out:
	mutex_unlock(&priv->buffer_mutex);
	wake_up_interruptible(&priv->async_wait);
}

static void user_reader_timeout(struct timer_list *t)
{
	struct file_priv *priv = from_timer(priv, t, user_read_timer);

	pr_warn("TPM user space timeout is deprecated (pid=%d)\n",
		task_tgid_nr(current));

	schedule_work(&priv->timeout_work);
}

static void tpm_timeout_work(struct work_struct *work)
{
	struct file_priv *priv = container_of(work, struct file_priv,
					      timeout_work);

	mutex_lock(&priv->buffer_mutex);
	priv->response_read = true;
	priv->response_length = 0;
	memset(priv->data_buffer, 0, sizeof(priv->data_buffer));
	mutex_unlock(&priv->buffer_mutex);
	wake_up_interruptible(&priv->async_wait);
}

void tpm_common_open(struct file *file, struct tpm_chip *chip,
		     struct file_priv *priv, struct tpm_space *space)
{
	priv->chip = chip;
	priv->space = space;
	priv->response_read = true;

	mutex_init(&priv->buffer_mutex);
	timer_setup(&priv->user_read_timer, user_reader_timeout, 0);
	INIT_WORK(&priv->timeout_work, tpm_timeout_work);
	INIT_WORK(&priv->async_work, tpm_dev_async_work);
	init_waitqueue_head(&priv->async_wait);
	file->private_data = priv;
}

ssize_t tpm_common_read(struct file *file, char __user *buf,
			size_t size, loff_t *off)
{
	struct file_priv *priv = file->private_data;
	ssize_t ret_size = 0;
	int rc;

	mutex_lock(&priv->buffer_mutex);

	if (priv->response_length) {
		priv->response_read = true;

		ret_size = min_t(ssize_t, size, priv->response_length);
		if (ret_size <= 0) {
			priv->response_length = 0;
			goto out;
		}

		rc = copy_to_user(buf, priv->data_buffer + *off, ret_size);
		if (rc) {
			memset(priv->data_buffer, 0, TPM_BUFSIZE);
			priv->response_length = 0;
			ret_size = -EFAULT;
		} else {
			memset(priv->data_buffer + *off, 0, ret_size);
			priv->response_length -= ret_size;
			*off += ret_size;
		}
	}

out:
	if (!priv->response_length) {
		*off = 0;
		del_timer_sync(&priv->user_read_timer);
		flush_work(&priv->timeout_work);
	}
	mutex_unlock(&priv->buffer_mutex);
	return ret_size;
}

ssize_t tpm_common_write(struct file *file, const char __user *buf,
			 size_t size, loff_t *off)
{
	struct file_priv *priv = file->private_data;
	int ret = 0;

	if (size > TPM_BUFSIZE)
		return -E2BIG;

	mutex_lock(&priv->buffer_mutex);

	/* Cannot perform a write until the read has cleared either via
	 * tpm_read or a user_read_timer timeout. This also prevents split
	 * buffered writes from blocking here.
	 */
	if ((!priv->response_read && priv->response_length) ||
	    priv->command_enqueued) {
		ret = -EBUSY;
		goto out;
	}

	if (copy_from_user(priv->data_buffer, buf, size)) {
		ret = -EFAULT;
		goto out;
	}

	if (size < 6 ||
	    size < be32_to_cpu(*((__be32 *)(priv->data_buffer + 2)))) {
		ret = -EINVAL;
		goto out;
	}

	priv->response_length = 0;
	priv->response_read = false;
	*off = 0;

	/*
	 * If in nonblocking mode schedule an async job to send
	 * the command return the size.
	 * In case of error the err code will be returned in
	 * the subsequent read call.
	 */
	if (file->f_flags & O_NONBLOCK) {
		priv->command_enqueued = true;
		queue_work(tpm_dev_wq, &priv->async_work);
		mutex_unlock(&priv->buffer_mutex);
		return size;
	}

	/* atomic tpm command send and result receive. We only hold the ops
	 * lock during this period so that the tpm can be unregistered even if
	 * the char dev is held open.
	 */
	if (tpm_try_get_ops(priv->chip)) {
		ret = -EPIPE;
		goto out;
	}

	ret = tpm_dev_transmit(priv->chip, priv->space, priv->data_buffer,
			       sizeof(priv->data_buffer));
	tpm_put_ops(priv->chip);

	if (ret > 0) {
		priv->response_length = ret;
		mod_timer(&priv->user_read_timer, jiffies + (120 * HZ));
		ret = size;
	}
out:
	mutex_unlock(&priv->buffer_mutex);
	return ret;
}

__poll_t tpm_common_poll(struct file *file, poll_table *wait)
{
	struct file_priv *priv = file->private_data;
	__poll_t mask = 0;

	poll_wait(file, &priv->async_wait, wait);
	mutex_lock(&priv->buffer_mutex);

	/*
	 * The response_length indicates if there is still response
	 * (or part of it) to be consumed. Partial reads decrease it
	 * by the number of bytes read, and write resets it the zero.
	 */
	if (priv->response_length)
		mask = EPOLLIN | EPOLLRDNORM;
	else
		mask = EPOLLOUT | EPOLLWRNORM;

	mutex_unlock(&priv->buffer_mutex);
	return mask;
}

/*
 * Called on file close
 */
void tpm_common_release(struct file *file, struct file_priv *priv)
{
	flush_work(&priv->async_work);
	del_timer_sync(&priv->user_read_timer);
	flush_work(&priv->timeout_work);
	file->private_data = NULL;
	priv->response_length = 0;
}

int __init tpm_dev_common_init(void)
{
	tpm_dev_wq = alloc_workqueue("tpm_dev_wq", WQ_MEM_RECLAIM, 0);

	return !tpm_dev_wq ? -ENOMEM : 0;
}

void __exit tpm_dev_common_exit(void)
{
	if (tpm_dev_wq) {
		destroy_workqueue(tpm_dev_wq);
		tpm_dev_wq = NULL;
	}
}
