/*
 *
 * (C) COPYRIGHT 2017 ARM Limited. All rights reserved.
 *
 * This program is free software and is provided to you under the terms of the
 * GNU General Public License version 2 as published by the Free Software
 * Foundation, and any use by you of this program is subject to the terms
 * of such GNU licence.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, you can access it online at
 * http://www.gnu.org/licenses/gpl-2.0.html.
 *
 * SPDX-License-Identifier: GPL-2.0
 *
 */

/* Kernel UTF test helpers */
#include <kutf/kutf_helpers.h>

#include <linux/err.h>
#include <linux/jiffies.h>
#include <linux/sched.h>
#include <linux/preempt.h>
#include <linux/wait.h>
#include <linux/uaccess.h>

static DEFINE_SPINLOCK(kutf_input_lock);

static bool pending_input(struct kutf_context *context)
{
	bool input_pending;

	spin_lock(&kutf_input_lock);

	input_pending = !list_empty(&context->userdata.input_head);

	spin_unlock(&kutf_input_lock);

	return input_pending;
}

char *kutf_helper_input_dequeue(struct kutf_context *context, size_t *str_size)
{
	struct kutf_userdata_line *line;

	spin_lock(&kutf_input_lock);

	while (list_empty(&context->userdata.input_head)) {
		int err;

		kutf_set_waiting_for_input(context->result_set);

		spin_unlock(&kutf_input_lock);

		err = wait_event_interruptible(context->userdata.input_waitq,
				pending_input(context));

		if (err)
			return ERR_PTR(-EINTR);

		spin_lock(&kutf_input_lock);
	}

	line = list_first_entry(&context->userdata.input_head,
			struct kutf_userdata_line, node);
	if (line->str) {
		/*
		 * Unless it is the end-of-input marker,
		 * remove it from the list
		 */
		list_del(&line->node);
	}

	spin_unlock(&kutf_input_lock);

	if (str_size)
		*str_size = line->size;
	return line->str;
}

int kutf_helper_input_enqueue(struct kutf_context *context,
		const char __user *str, size_t size)
{
	struct kutf_userdata_line *line;

	line = kutf_mempool_alloc(&context->fixture_pool,
			sizeof(*line) + size + 1);
	if (!line)
		return -ENOMEM;
	if (str) {
		unsigned long bytes_not_copied;

		line->size = size;
		line->str = (void *)(line + 1);
		bytes_not_copied = copy_from_user(line->str, str, size);
		if (bytes_not_copied != 0)
			return -EFAULT;
		/* Zero terminate the string */
		line->str[size] = '\0';
	} else {
		/* This is used to mark the end of input */
		WARN_ON(size);
		line->size = 0;
		line->str = NULL;
	}

	spin_lock(&kutf_input_lock);

	list_add_tail(&line->node, &context->userdata.input_head);

	kutf_clear_waiting_for_input(context->result_set);

	spin_unlock(&kutf_input_lock);

	wake_up(&context->userdata.input_waitq);

	return 0;
}

void kutf_helper_input_enqueue_end_of_data(struct kutf_context *context)
{
	kutf_helper_input_enqueue(context, NULL, 0);
}
