// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (C) 2021 - Google LLC
 * Author: David Brazdil <dbrazdil@google.com>
 *
 * Driver for Open Profile for DICE.
 *
 * This driver takes ownership of a reserved memory region containing data
 * generated by the Open Profile for DICE measured boot protocol. The memory
 * contents are not interpreted by the kernel but can be mapped into a userspace
 * process via a misc device. Userspace can also request a wipe of the memory.
 *
 * Userspace can access the data with (w/o error handling):
 *
 *     fd = open("/dev/open-dice0", O_RDWR);
 *     read(fd, &size, sizeof(unsigned long));
 *     data = mmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0);
 *     write(fd, NULL, 0); // wipe
 *     close(fd);
 */

#include <linux/io.h>
#include <linux/miscdevice.h>
#include <linux/mm.h>
#include <linux/module.h>
#include <linux/of_reserved_mem.h>
#include <linux/platform_device.h>

#define DRIVER_NAME "open-dice"

struct open_dice_drvdata {
	struct mutex lock;
	char name[16];
	struct reserved_mem *rmem;
	struct miscdevice misc;
};

static inline struct open_dice_drvdata *to_open_dice_drvdata(struct file *filp)
{
	return container_of(filp->private_data, struct open_dice_drvdata, misc);
}

static int open_dice_wipe(struct open_dice_drvdata *drvdata)
{
	void *kaddr;

	mutex_lock(&drvdata->lock);
	kaddr = devm_memremap(drvdata->misc.this_device, drvdata->rmem->base,
			      drvdata->rmem->size, MEMREMAP_WC);
	if (IS_ERR(kaddr)) {
		mutex_unlock(&drvdata->lock);
		return PTR_ERR(kaddr);
	}

	memset(kaddr, 0, drvdata->rmem->size);
	devm_memunmap(drvdata->misc.this_device, kaddr);
	mutex_unlock(&drvdata->lock);
	return 0;
}

/*
 * Copies the size of the reserved memory region to the user-provided buffer.
 */
static ssize_t open_dice_read(struct file *filp, char __user *ptr, size_t len,
			      loff_t *off)
{
	unsigned long val = to_open_dice_drvdata(filp)->rmem->size;

	return simple_read_from_buffer(ptr, len, off, &val, sizeof(val));
}

/*
 * Triggers a wipe of the reserved memory region. The user-provided pointer
 * is never dereferenced.
 */
static ssize_t open_dice_write(struct file *filp, const char __user *ptr,
			       size_t len, loff_t *off)
{
	if (open_dice_wipe(to_open_dice_drvdata(filp)))
		return -EIO;

	/* Consume the input buffer. */
	return len;
}

/*
 * Creates a mapping of the reserved memory region in user address space.
 */
static int open_dice_mmap_prepare(struct vm_area_desc *desc)
{
	struct file *filp = desc->file;
	struct open_dice_drvdata *drvdata = to_open_dice_drvdata(filp);

	if (vma_desc_test(desc, VMA_MAYSHARE_BIT)) {
		/* Do not allow userspace to modify the underlying data. */
		if (vma_desc_test(desc, VMA_WRITE_BIT))
			return -EPERM;
		/* Ensure userspace cannot acquire VM_WRITE later. */
		vma_desc_clear_flags(desc, VMA_MAYWRITE_BIT);
	}

	/* Create write-combine mapping so all clients observe a wipe. */
	desc->page_prot = pgprot_writecombine(desc->page_prot);
	vma_desc_set_flags(desc, VMA_DONTCOPY_BIT, VMA_DONTDUMP_BIT);
	mmap_action_simple_ioremap(desc, drvdata->rmem->base,
				   drvdata->rmem->size);
	return 0;
}

static const struct file_operations open_dice_fops = {
	.owner = THIS_MODULE,
	.read = open_dice_read,
	.write = open_dice_write,
	.mmap_prepare = open_dice_mmap_prepare,
};

static int __init open_dice_probe(struct platform_device *pdev)
{
	static unsigned int dev_idx;
	struct device *dev = &pdev->dev;
	struct reserved_mem *rmem;
	struct open_dice_drvdata *drvdata;
	int ret;

	rmem = of_reserved_mem_lookup(dev->of_node);
	if (!rmem) {
		dev_err(dev, "failed to lookup reserved memory\n");
		return -EINVAL;
	}

	if (!rmem->size || (rmem->size > ULONG_MAX)) {
		dev_err(dev, "invalid memory region size\n");
		return -EINVAL;
	}

	if (!PAGE_ALIGNED(rmem->base) || !PAGE_ALIGNED(rmem->size)) {
		dev_err(dev, "memory region must be page-aligned\n");
		return -EINVAL;
	}

	drvdata = devm_kmalloc(dev, sizeof(*drvdata), GFP_KERNEL);
	if (!drvdata)
		return -ENOMEM;

	*drvdata = (struct open_dice_drvdata){
		.rmem = rmem,
		.misc = (struct miscdevice){
			.parent	= dev,
			.name	= drvdata->name,
			.minor	= MISC_DYNAMIC_MINOR,
			.fops	= &open_dice_fops,
			.mode	= 0600,
		},
	};
	mutex_init(&drvdata->lock);

	/* Index overflow check not needed, misc_register() will fail. */
	snprintf(drvdata->name, sizeof(drvdata->name), DRIVER_NAME"%u", dev_idx++);

	ret = misc_register(&drvdata->misc);
	if (ret) {
		dev_err(dev, "failed to register misc device '%s': %d\n",
			drvdata->name, ret);
		return ret;
	}

	platform_set_drvdata(pdev, drvdata);
	return 0;
}

static void open_dice_remove(struct platform_device *pdev)
{
	struct open_dice_drvdata *drvdata = platform_get_drvdata(pdev);

	misc_deregister(&drvdata->misc);
}

static const struct of_device_id open_dice_of_match[] = {
	{ .compatible = "google,open-dice" },
	{},
};

static struct platform_driver open_dice_driver = {
	.remove = open_dice_remove,
	.driver = {
		.name = DRIVER_NAME,
		.of_match_table = open_dice_of_match,
	},
};

static int __init open_dice_init(void)
{
	int ret = platform_driver_probe(&open_dice_driver, open_dice_probe);

	/* DICE regions are optional. Succeed even with zero instances. */
	return (ret == -ENODEV) ? 0 : ret;
}

static void __exit open_dice_exit(void)
{
	platform_driver_unregister(&open_dice_driver);
}

module_init(open_dice_init);
module_exit(open_dice_exit);

MODULE_DESCRIPTION("Driver for Open Profile for DICE.");
MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("David Brazdil <dbrazdil@google.com>");
