// SPDX-License-Identifier: GPL-2.0 OR MIT

/******************************************************************************
 * privcmd-buf.c
 *
 * Mmap of hypercall buffers.
 *
 * Copyright (c) 2018 Juergen Gross
 */

#define pr_fmt(fmt) "xen:" KBUILD_MODNAME ": " fmt

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/list.h>
#include <linux/miscdevice.h>
#include <linux/mm.h>
#include <linux/slab.h>

#include "privcmd.h"

MODULE_DESCRIPTION("Xen Mmap of hypercall buffers");
MODULE_LICENSE("GPL");

struct privcmd_buf_private {
	struct mutex lock;
	struct list_head list;
};

struct privcmd_buf_vma_private {
	struct privcmd_buf_private *file_priv;
	struct list_head list;
	unsigned int users;
	unsigned int n_pages;
	struct page *pages[];
};

static int privcmd_buf_open(struct inode *ino, struct file *file)
{
	struct privcmd_buf_private *file_priv;

	file_priv = kzalloc_obj(*file_priv);
	if (!file_priv)
		return -ENOMEM;

	mutex_init(&file_priv->lock);
	INIT_LIST_HEAD(&file_priv->list);

	file->private_data = file_priv;

	return 0;
}

static void privcmd_buf_vmapriv_free(struct privcmd_buf_vma_private *vma_priv)
{
	unsigned int i;

	list_del(&vma_priv->list);

	for (i = 0; i < vma_priv->n_pages; i++)
		__free_page(vma_priv->pages[i]);

	kfree(vma_priv);
}

static int privcmd_buf_release(struct inode *ino, struct file *file)
{
	struct privcmd_buf_private *file_priv = file->private_data;
	struct privcmd_buf_vma_private *vma_priv;

	mutex_lock(&file_priv->lock);

	while (!list_empty(&file_priv->list)) {
		vma_priv = list_first_entry(&file_priv->list,
					    struct privcmd_buf_vma_private,
					    list);
		privcmd_buf_vmapriv_free(vma_priv);
	}

	mutex_unlock(&file_priv->lock);

	kfree(file_priv);

	return 0;
}

static void privcmd_buf_vma_open(struct vm_area_struct *vma)
{
	struct privcmd_buf_vma_private *vma_priv = vma->vm_private_data;

	if (!vma_priv)
		return;

	mutex_lock(&vma_priv->file_priv->lock);
	vma_priv->users++;
	mutex_unlock(&vma_priv->file_priv->lock);
}

static void privcmd_buf_vma_close(struct vm_area_struct *vma)
{
	struct privcmd_buf_vma_private *vma_priv = vma->vm_private_data;
	struct privcmd_buf_private *file_priv;

	if (!vma_priv)
		return;

	file_priv = vma_priv->file_priv;

	mutex_lock(&file_priv->lock);

	vma_priv->users--;
	if (!vma_priv->users)
		privcmd_buf_vmapriv_free(vma_priv);

	mutex_unlock(&file_priv->lock);
}

static vm_fault_t privcmd_buf_vma_fault(struct vm_fault *vmf)
{
	pr_debug("fault: vma=%p %lx-%lx, pgoff=%lx, uv=%p\n",
		 vmf->vma, vmf->vma->vm_start, vmf->vma->vm_end,
		 vmf->pgoff, (void *)vmf->address);

	return VM_FAULT_SIGBUS;
}

static const struct vm_operations_struct privcmd_buf_vm_ops = {
	.open = privcmd_buf_vma_open,
	.close = privcmd_buf_vma_close,
	.fault = privcmd_buf_vma_fault,
};

static int privcmd_buf_mmap(struct file *file, struct vm_area_struct *vma)
{
	struct privcmd_buf_private *file_priv = file->private_data;
	struct privcmd_buf_vma_private *vma_priv;
	unsigned long count = vma_pages(vma);
	unsigned int i;
	int ret = 0;

	if (!(vma->vm_flags & VM_SHARED))
		return -EINVAL;

	vma_priv = kzalloc_flex(*vma_priv, pages, count);
	if (!vma_priv)
		return -ENOMEM;

	for (i = 0; i < count; i++) {
		vma_priv->pages[i] = alloc_page(GFP_KERNEL | __GFP_ZERO);
		if (!vma_priv->pages[i])
			break;
		vma_priv->n_pages++;
	}

	mutex_lock(&file_priv->lock);

	vma_priv->file_priv = file_priv;
	vma_priv->users = 1;

	vm_flags_set(vma, VM_IO | VM_DONTEXPAND);
	vma->vm_ops = &privcmd_buf_vm_ops;
	vma->vm_private_data = vma_priv;

	list_add(&vma_priv->list, &file_priv->list);

	if (vma_priv->n_pages != count)
		ret = -ENOMEM;
	else
		ret = vm_map_pages_zero(vma, vma_priv->pages,
						vma_priv->n_pages);

	if (ret)
		privcmd_buf_vmapriv_free(vma_priv);

	mutex_unlock(&file_priv->lock);

	return ret;
}

const struct file_operations xen_privcmdbuf_fops = {
	.owner = THIS_MODULE,
	.open = privcmd_buf_open,
	.release = privcmd_buf_release,
	.mmap = privcmd_buf_mmap,
};
EXPORT_SYMBOL_GPL(xen_privcmdbuf_fops);

struct miscdevice xen_privcmdbuf_dev = {
	.minor = MISC_DYNAMIC_MINOR,
	.name = "xen/hypercall",
	.fops = &xen_privcmdbuf_fops,
};
