// SPDX-License-Identifier: GPL-2.0-only
/*
 * s390 TRNG device driver
 *
 * Driver for the TRNG (true random number generation) command
 * available via CPACF extension MSA 7 on the s390 arch.

 * Copyright IBM Corp. 2017
 * Author(s): Harald Freudenberger <freude@de.ibm.com>
 */

#define KMSG_COMPONENT "trng"
#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt

#include <linux/hw_random.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/cpufeature.h>
#include <linux/miscdevice.h>
#include <linux/debugfs.h>
#include <linux/atomic.h>
#include <linux/random.h>
#include <linux/sched/signal.h>
#include <asm/debug.h>
#include <asm/cpacf.h>

MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("IBM Corporation");
MODULE_DESCRIPTION("s390 CPACF TRNG device driver");


/* trng related debug feature things */

static debug_info_t *debug_info;

#define DEBUG_DBG(...)	debug_sprintf_event(debug_info, 6, ##__VA_ARGS__)
#define DEBUG_INFO(...) debug_sprintf_event(debug_info, 5, ##__VA_ARGS__)
#define DEBUG_WARN(...) debug_sprintf_event(debug_info, 4, ##__VA_ARGS__)
#define DEBUG_ERR(...)	debug_sprintf_event(debug_info, 3, ##__VA_ARGS__)


/* trng helpers */

static atomic64_t trng_dev_counter = ATOMIC64_INIT(0);
static atomic64_t trng_hwrng_counter = ATOMIC64_INIT(0);


/* file io functions */

static int trng_open(struct inode *inode, struct file *file)
{
	return nonseekable_open(inode, file);
}

static ssize_t trng_read(struct file *file, char __user *ubuf,
			 size_t nbytes, loff_t *ppos)
{
	u8 buf[32];
	u8 *p = buf;
	unsigned int n;
	ssize_t ret = 0;

	/*
	 * use buf for requests <= sizeof(buf),
	 * otherwise allocate one page and fetch
	 * pagewise.
	 */

	if (nbytes > sizeof(buf)) {
		p = (u8 *) __get_free_page(GFP_KERNEL);
		if (!p)
			return -ENOMEM;
	}

	while (nbytes) {
		if (need_resched()) {
			if (signal_pending(current)) {
				if (ret == 0)
					ret = -ERESTARTSYS;
				break;
			}
			schedule();
		}
		n = nbytes > PAGE_SIZE ? PAGE_SIZE : nbytes;
		cpacf_trng(NULL, 0, p, n);
		atomic64_add(n, &trng_dev_counter);
		if (copy_to_user(ubuf, p, n)) {
			ret = -EFAULT;
			break;
		}
		nbytes -= n;
		ubuf += n;
		ret += n;
	}

	if (p != buf)
		free_page((unsigned long) p);

	DEBUG_DBG("trng_read()=%zd\n", ret);
	return ret;
}


/* sysfs */

static ssize_t trng_counter_show(struct device *dev,
				 struct device_attribute *attr, char *buf)
{
	u64 dev_counter = atomic64_read(&trng_dev_counter);
	u64 hwrng_counter = atomic64_read(&trng_hwrng_counter);
#if IS_ENABLED(CONFIG_ARCH_RANDOM)
	u64 arch_counter = atomic64_read(&s390_arch_random_counter);

	return snprintf(buf, PAGE_SIZE,
			"trng:  %llu\n"
			"hwrng: %llu\n"
			"arch:  %llu\n"
			"total: %llu\n",
			dev_counter, hwrng_counter, arch_counter,
			dev_counter + hwrng_counter + arch_counter);
#else
	return snprintf(buf, PAGE_SIZE,
			"trng:  %llu\n"
			"hwrng: %llu\n"
			"total: %llu\n",
			dev_counter, hwrng_counter,
			dev_counter + hwrng_counter);
#endif
}
static DEVICE_ATTR(byte_counter, 0444, trng_counter_show, NULL);

static struct attribute *trng_dev_attrs[] = {
	&dev_attr_byte_counter.attr,
	NULL
};

static const struct attribute_group trng_dev_attr_group = {
	.attrs = trng_dev_attrs
};

static const struct attribute_group *trng_dev_attr_groups[] = {
	&trng_dev_attr_group,
	NULL
};

static const struct file_operations trng_fops = {
	.owner		= THIS_MODULE,
	.open		= &trng_open,
	.release	= NULL,
	.read		= &trng_read,
	.llseek		= noop_llseek,
};

static struct miscdevice trng_dev = {
	.name	= "trng",
	.minor	= MISC_DYNAMIC_MINOR,
	.mode	= 0444,
	.fops	= &trng_fops,
	.groups = trng_dev_attr_groups,
};


/* hwrng_register */

static inline void _trng_hwrng_read(u8 *buf, size_t len)
{
	cpacf_trng(NULL, 0, buf, len);
	atomic64_add(len, &trng_hwrng_counter);
}

static int trng_hwrng_data_read(struct hwrng *rng, u32 *data)
{
	size_t len = sizeof(*data);

	_trng_hwrng_read((u8 *) data, len);

	DEBUG_DBG("trng_hwrng_data_read()=%zu\n", len);

	return len;
}

static int trng_hwrng_read(struct hwrng *rng, void *data, size_t max, bool wait)
{
	size_t len = max <= PAGE_SIZE ? max : PAGE_SIZE;

	_trng_hwrng_read((u8 *) data, len);

	DEBUG_DBG("trng_hwrng_read()=%zu\n", len);

	return len;
}

/*
 * hwrng register struct
 * The trng is suppost to have 100% entropy, and thus
 * we register with a very high quality value.
 */
static struct hwrng trng_hwrng_dev = {
	.name		= "s390-trng",
	.data_read	= trng_hwrng_data_read,
	.read		= trng_hwrng_read,
	.quality	= 999,
};


/* init and exit */

static void __init trng_debug_init(void)
{
	debug_info = debug_register("trng", 1, 1, 4 * sizeof(long));
	debug_register_view(debug_info, &debug_sprintf_view);
	debug_set_level(debug_info, 3);
}

static void trng_debug_exit(void)
{
	debug_unregister(debug_info);
}

static int __init trng_init(void)
{
	int ret;

	trng_debug_init();

	/* check if subfunction CPACF_PRNO_TRNG is available */
	if (!cpacf_query_func(CPACF_PRNO, CPACF_PRNO_TRNG)) {
		DEBUG_INFO("trng_init CPACF_PRNO_TRNG not available\n");
		ret = -ENODEV;
		goto out_dbg;
	}

	ret = misc_register(&trng_dev);
	if (ret) {
		DEBUG_WARN("trng_init misc_register() failed rc=%d\n", ret);
		goto out_dbg;
	}

	ret = hwrng_register(&trng_hwrng_dev);
	if (ret) {
		DEBUG_WARN("trng_init hwrng_register() failed rc=%d\n", ret);
		goto out_misc;
	}

	DEBUG_DBG("trng_init successful\n");

	return 0;

out_misc:
	misc_deregister(&trng_dev);
out_dbg:
	trng_debug_exit();
	return ret;
}

static void __exit trng_exit(void)
{
	hwrng_unregister(&trng_hwrng_dev);
	misc_deregister(&trng_dev);
	trng_debug_exit();
}

module_cpu_feature_match(MSA, trng_init);
module_exit(trng_exit);
