/* SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause */
/*
 * Test interface for Jitter RNG.
 *
 * Copyright (C) 2023, Stephan Mueller <smueller@chronox.de>
 */

#include <linux/debugfs.h>
#include <linux/module.h>
#include <linux/uaccess.h>

#include "jitterentropy.h"

#define JENT_TEST_RINGBUFFER_SIZE	(1<<10)
#define JENT_TEST_RINGBUFFER_MASK	(JENT_TEST_RINGBUFFER_SIZE - 1)

struct jent_testing {
	u64 jent_testing_rb[JENT_TEST_RINGBUFFER_SIZE];
	u32 rb_reader;
	atomic_t rb_writer;
	atomic_t jent_testing_enabled;
	spinlock_t lock;
	wait_queue_head_t read_wait;
};

static struct dentry *jent_raw_debugfs_root = NULL;

/*************************** Generic Data Handling ****************************/

/*
 * boot variable:
 * 0 ==> No boot test, gathering of runtime data allowed
 * 1 ==> Boot test enabled and ready for collecting data, gathering runtime
 *	 data is disabled
 * 2 ==> Boot test completed and disabled, gathering of runtime data is
 *	 disabled
 */

static void jent_testing_reset(struct jent_testing *data)
{
	unsigned long flags;

	spin_lock_irqsave(&data->lock, flags);
	data->rb_reader = 0;
	atomic_set(&data->rb_writer, 0);
	spin_unlock_irqrestore(&data->lock, flags);
}

static void jent_testing_data_init(struct jent_testing *data, u32 boot)
{
	/*
	 * The boot time testing implies we have a running test. If the
	 * caller wants to clear it, he has to unset the boot_test flag
	 * at runtime via sysfs to enable regular runtime testing
	 */
	if (boot)
		return;

	jent_testing_reset(data);
	atomic_set(&data->jent_testing_enabled, 1);
	pr_warn("Enabling data collection\n");
}

static void jent_testing_fini(struct jent_testing *data, u32 boot)
{
	/* If we have boot data, we do not reset yet to allow data to be read */
	if (boot)
		return;

	atomic_set(&data->jent_testing_enabled, 0);
	jent_testing_reset(data);
	pr_warn("Disabling data collection\n");
}

static bool jent_testing_store(struct jent_testing *data, u64 value,
			       u32 *boot)
{
	unsigned long flags;

	if (!atomic_read(&data->jent_testing_enabled) && (*boot != 1))
		return false;

	spin_lock_irqsave(&data->lock, flags);

	/*
	 * Disable entropy testing for boot time testing after ring buffer
	 * is filled.
	 */
	if (*boot) {
		if (((u32)atomic_read(&data->rb_writer)) >
		     JENT_TEST_RINGBUFFER_SIZE) {
			*boot = 2;
			pr_warn_once("One time data collection test disabled\n");
			spin_unlock_irqrestore(&data->lock, flags);
			return false;
		}

		if (atomic_read(&data->rb_writer) == 1)
			pr_warn("One time data collection test enabled\n");
	}

	data->jent_testing_rb[((u32)atomic_read(&data->rb_writer)) &
			      JENT_TEST_RINGBUFFER_MASK] = value;
	atomic_inc(&data->rb_writer);

	spin_unlock_irqrestore(&data->lock, flags);

	if (wq_has_sleeper(&data->read_wait))
		wake_up_interruptible(&data->read_wait);

	return true;
}

static bool jent_testing_have_data(struct jent_testing *data)
{
	return ((((u32)atomic_read(&data->rb_writer)) &
		 JENT_TEST_RINGBUFFER_MASK) !=
		 (data->rb_reader & JENT_TEST_RINGBUFFER_MASK));
}

static int jent_testing_reader(struct jent_testing *data, u32 *boot,
			       u8 *outbuf, u32 outbuflen)
{
	unsigned long flags;
	int collected_data = 0;

	jent_testing_data_init(data, *boot);

	while (outbuflen) {
		u32 writer = (u32)atomic_read(&data->rb_writer);

		spin_lock_irqsave(&data->lock, flags);

		/* We have no data or reached the writer. */
		if (!writer || (writer == data->rb_reader)) {

			spin_unlock_irqrestore(&data->lock, flags);

			/*
			 * Now we gathered all boot data, enable regular data
			 * collection.
			 */
			if (*boot) {
				*boot = 0;
				goto out;
			}

			wait_event_interruptible(data->read_wait,
						 jent_testing_have_data(data));
			if (signal_pending(current)) {
				collected_data = -ERESTARTSYS;
				goto out;
			}

			continue;
		}

		/* We copy out word-wise */
		if (outbuflen < sizeof(u64)) {
			spin_unlock_irqrestore(&data->lock, flags);
			goto out;
		}

		memcpy(outbuf, &data->jent_testing_rb[data->rb_reader],
		       sizeof(u64));
		data->rb_reader++;

		spin_unlock_irqrestore(&data->lock, flags);

		outbuf += sizeof(u64);
		outbuflen -= sizeof(u64);
		collected_data += sizeof(u64);
	}

out:
	jent_testing_fini(data, *boot);
	return collected_data;
}

static int jent_testing_extract_user(struct file *file, char __user *buf,
				     size_t nbytes, loff_t *ppos,
				     int (*reader)(u8 *outbuf, u32 outbuflen))
{
	u8 *tmp, *tmp_aligned;
	int ret = 0, large_request = (nbytes > 256);

	if (!nbytes)
		return 0;

	/*
	 * The intention of this interface is for collecting at least
	 * 1000 samples due to the SP800-90B requirements. However, due to
	 * memory and performance constraints, it is not desirable to allocate
	 * 8000 bytes of memory. Instead, we allocate space for only 125
	 * samples, which will allow the user to collect all 1000 samples using
	 * 8 calls to this interface.
	 */
	tmp = kmalloc(125 * sizeof(u64) + sizeof(u64), GFP_KERNEL);
	if (!tmp)
		return -ENOMEM;

	tmp_aligned = PTR_ALIGN(tmp, sizeof(u64));

	while (nbytes) {
		int i;

		if (large_request && need_resched()) {
			if (signal_pending(current)) {
				if (ret == 0)
					ret = -ERESTARTSYS;
				break;
			}
			schedule();
		}

		i = min_t(int, nbytes, 125 * sizeof(u64));
		i = reader(tmp_aligned, i);
		if (i <= 0) {
			if (i < 0)
				ret = i;
			break;
		}
		if (copy_to_user(buf, tmp_aligned, i)) {
			ret = -EFAULT;
			break;
		}

		nbytes -= i;
		buf += i;
		ret += i;
	}

	kfree_sensitive(tmp);

	if (ret > 0)
		*ppos += ret;

	return ret;
}

/************** Raw High-Resolution Timer Entropy Data Handling **************/

static u32 boot_raw_hires_test = 0;
module_param(boot_raw_hires_test, uint, 0644);
MODULE_PARM_DESC(boot_raw_hires_test,
		 "Enable gathering boot time high resolution timer entropy of the first Jitter RNG entropy events");

static struct jent_testing jent_raw_hires = {
	.rb_reader = 0,
	.rb_writer = ATOMIC_INIT(0),
	.lock      = __SPIN_LOCK_UNLOCKED(jent_raw_hires.lock),
	.read_wait = __WAIT_QUEUE_HEAD_INITIALIZER(jent_raw_hires.read_wait)
};

int jent_raw_hires_entropy_store(__u64 value)
{
	return jent_testing_store(&jent_raw_hires, value, &boot_raw_hires_test);
}
EXPORT_SYMBOL(jent_raw_hires_entropy_store);

static int jent_raw_hires_entropy_reader(u8 *outbuf, u32 outbuflen)
{
	return jent_testing_reader(&jent_raw_hires, &boot_raw_hires_test,
				   outbuf, outbuflen);
}

static ssize_t jent_raw_hires_read(struct file *file, char __user *to,
				   size_t count, loff_t *ppos)
{
	return jent_testing_extract_user(file, to, count, ppos,
					 jent_raw_hires_entropy_reader);
}

static const struct file_operations jent_raw_hires_fops = {
	.owner = THIS_MODULE,
	.read = jent_raw_hires_read,
};

/******************************* Initialization *******************************/

void jent_testing_init(void)
{
	jent_raw_debugfs_root = debugfs_create_dir(KBUILD_MODNAME, NULL);

	debugfs_create_file_unsafe("jent_raw_hires", 0400,
				   jent_raw_debugfs_root, NULL,
				   &jent_raw_hires_fops);
}
EXPORT_SYMBOL(jent_testing_init);

void jent_testing_exit(void)
{
	debugfs_remove_recursive(jent_raw_debugfs_root);
}
EXPORT_SYMBOL(jent_testing_exit);
