// SPDX-License-Identifier: GPL-2.0-only
/******************************************************************************
 * privcmd.c
 *
 * Interface to privileged domain-0 commands.
 *
 * Copyright (c) 2002-2004, K A Fraser, B Dragovic
 */

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

#include <linux/eventfd.h>
#include <linux/file.h>
#include <linux/kernel.h>
#include <linux/kstrtox.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/poll.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/srcu.h>
#include <linux/string.h>
#include <linux/workqueue.h>
#include <linux/errno.h>
#include <linux/mm.h>
#include <linux/mman.h>
#include <linux/uaccess.h>
#include <linux/swap.h>
#include <linux/highmem.h>
#include <linux/pagemap.h>
#include <linux/seq_file.h>
#include <linux/miscdevice.h>
#include <linux/moduleparam.h>
#include <linux/notifier.h>
#include <linux/security.h>
#include <linux/virtio_mmio.h>
#include <linux/wait.h>

#include <asm/xen/hypervisor.h>
#include <asm/xen/hypercall.h>

#include <xen/xen.h>
#include <xen/events.h>
#include <xen/privcmd.h>
#include <xen/interface/xen.h>
#include <xen/interface/memory.h>
#include <xen/interface/hvm/dm_op.h>
#include <xen/interface/hvm/ioreq.h>
#include <xen/features.h>
#include <xen/page.h>
#include <xen/xen-ops.h>
#include <xen/balloon.h>
#include <xen/xenbus.h>
#ifdef CONFIG_XEN_ACPI
#include <xen/acpi.h>
#endif

#include "privcmd.h"

MODULE_DESCRIPTION("Xen hypercall passthrough driver");
MODULE_LICENSE("GPL");

#define PRIV_VMA_LOCKED ((void *)1)

static unsigned int privcmd_dm_op_max_num = 16;
module_param_named(dm_op_max_nr_bufs, privcmd_dm_op_max_num, uint, 0644);
MODULE_PARM_DESC(dm_op_max_nr_bufs,
		 "Maximum number of buffers per dm_op hypercall");

static unsigned int privcmd_dm_op_buf_max_size = 4096;
module_param_named(dm_op_buf_max_size, privcmd_dm_op_buf_max_size, uint,
		   0644);
MODULE_PARM_DESC(dm_op_buf_max_size,
		 "Maximum size of a dm_op hypercall buffer");

static bool unrestricted;
module_param(unrestricted, bool, 0);
MODULE_PARM_DESC(unrestricted,
	"Don't restrict hypercalls to target domain if running in a domU");

struct privcmd_data {
	domid_t domid;
};

/* DOMID_INVALID implies no restriction */
static domid_t target_domain = DOMID_INVALID;
static bool restrict_wait;
static DECLARE_WAIT_QUEUE_HEAD(restrict_wait_wq);

static int privcmd_vma_range_is_mapped(
               struct vm_area_struct *vma,
               unsigned long addr,
               unsigned long nr_pages);

static long privcmd_ioctl_hypercall(struct file *file, void __user *udata)
{
	struct privcmd_data *data = file->private_data;
	struct privcmd_hypercall hypercall;
	long ret;

	/* Disallow arbitrary hypercalls if restricted */
	if (data->domid != DOMID_INVALID)
		return -EPERM;

	if (copy_from_user(&hypercall, udata, sizeof(hypercall)))
		return -EFAULT;

	xen_preemptible_hcall_begin();
	ret = privcmd_call(hypercall.op,
			   hypercall.arg[0], hypercall.arg[1],
			   hypercall.arg[2], hypercall.arg[3],
			   hypercall.arg[4]);
	xen_preemptible_hcall_end();

	return ret;
}

static void free_page_list(struct list_head *pages)
{
	struct page *p, *n;

	list_for_each_entry_safe(p, n, pages, lru)
		__free_page(p);

	INIT_LIST_HEAD(pages);
}

/*
 * Given an array of items in userspace, return a list of pages
 * containing the data.  If copying fails, either because of memory
 * allocation failure or a problem reading user memory, return an
 * error code; its up to the caller to dispose of any partial list.
 */
static int gather_array(struct list_head *pagelist,
			unsigned nelem, size_t size,
			const void __user *data)
{
	unsigned pageidx;
	void *pagedata;
	int ret;

	if (size > PAGE_SIZE)
		return 0;

	pageidx = PAGE_SIZE;
	pagedata = NULL;	/* quiet, gcc */
	while (nelem--) {
		if (pageidx > PAGE_SIZE-size) {
			struct page *page = alloc_page(GFP_KERNEL);

			ret = -ENOMEM;
			if (page == NULL)
				goto fail;

			pagedata = page_address(page);

			list_add_tail(&page->lru, pagelist);
			pageidx = 0;
		}

		ret = -EFAULT;
		if (copy_from_user(pagedata + pageidx, data, size))
			goto fail;

		data += size;
		pageidx += size;
	}

	ret = 0;

fail:
	return ret;
}

/*
 * Call function "fn" on each element of the array fragmented
 * over a list of pages.
 */
static int traverse_pages(unsigned nelem, size_t size,
			  struct list_head *pos,
			  int (*fn)(void *data, void *state),
			  void *state)
{
	void *pagedata;
	unsigned pageidx;
	int ret = 0;

	BUG_ON(size > PAGE_SIZE);

	pageidx = PAGE_SIZE;
	pagedata = NULL;	/* hush, gcc */

	while (nelem--) {
		if (pageidx > PAGE_SIZE-size) {
			struct page *page;
			pos = pos->next;
			page = list_entry(pos, struct page, lru);
			pagedata = page_address(page);
			pageidx = 0;
		}

		ret = (*fn)(pagedata + pageidx, state);
		if (ret)
			break;
		pageidx += size;
	}

	return ret;
}

/*
 * Similar to traverse_pages, but use each page as a "block" of
 * data to be processed as one unit.
 */
static int traverse_pages_block(unsigned nelem, size_t size,
				struct list_head *pos,
				int (*fn)(void *data, int nr, void *state),
				void *state)
{
	void *pagedata;
	int ret = 0;

	BUG_ON(size > PAGE_SIZE);

	while (nelem) {
		int nr = (PAGE_SIZE/size);
		struct page *page;
		if (nr > nelem)
			nr = nelem;
		pos = pos->next;
		page = list_entry(pos, struct page, lru);
		pagedata = page_address(page);
		ret = (*fn)(pagedata, nr, state);
		if (ret)
			break;
		nelem -= nr;
	}

	return ret;
}

struct mmap_gfn_state {
	unsigned long va;
	struct vm_area_struct *vma;
	domid_t domain;
};

static int mmap_gfn_range(void *data, void *state)
{
	struct privcmd_mmap_entry *msg = data;
	struct mmap_gfn_state *st = state;
	struct vm_area_struct *vma = st->vma;
	int rc;

	/* Do not allow range to wrap the address space. */
	if ((msg->npages > (LONG_MAX >> PAGE_SHIFT)) ||
	    ((unsigned long)(msg->npages << PAGE_SHIFT) >= -st->va))
		return -EINVAL;

	/* Range chunks must be contiguous in va space. */
	if ((msg->va != st->va) ||
	    ((msg->va+(msg->npages<<PAGE_SHIFT)) > vma->vm_end))
		return -EINVAL;

	rc = xen_remap_domain_gfn_range(vma,
					msg->va & PAGE_MASK,
					msg->mfn, msg->npages,
					vma->vm_page_prot,
					st->domain, NULL);
	if (rc < 0)
		return rc;

	st->va += msg->npages << PAGE_SHIFT;

	return 0;
}

static long privcmd_ioctl_mmap(struct file *file, void __user *udata)
{
	struct privcmd_data *data = file->private_data;
	struct privcmd_mmap mmapcmd;
	struct mm_struct *mm = current->mm;
	struct vm_area_struct *vma;
	int rc;
	LIST_HEAD(pagelist);
	struct mmap_gfn_state state;

	/* We only support privcmd_ioctl_mmap_batch for non-auto-translated. */
	if (!xen_pv_domain())
		return -ENOSYS;

	if (copy_from_user(&mmapcmd, udata, sizeof(mmapcmd)))
		return -EFAULT;

	/* If restriction is in place, check the domid matches */
	if (data->domid != DOMID_INVALID && data->domid != mmapcmd.dom)
		return -EPERM;

	rc = gather_array(&pagelist,
			  mmapcmd.num, sizeof(struct privcmd_mmap_entry),
			  mmapcmd.entry);

	if (rc || list_empty(&pagelist))
		goto out;

	mmap_write_lock(mm);

	{
		struct page *page = list_first_entry(&pagelist,
						     struct page, lru);
		struct privcmd_mmap_entry *msg = page_address(page);

		vma = vma_lookup(mm, msg->va);
		rc = -EINVAL;

		if (!vma || (msg->va != vma->vm_start) || vma->vm_private_data)
			goto out_up;
		vma->vm_private_data = PRIV_VMA_LOCKED;
	}

	state.va = vma->vm_start;
	state.vma = vma;
	state.domain = mmapcmd.dom;

	rc = traverse_pages(mmapcmd.num, sizeof(struct privcmd_mmap_entry),
			    &pagelist,
			    mmap_gfn_range, &state);


out_up:
	mmap_write_unlock(mm);

out:
	free_page_list(&pagelist);

	return rc;
}

struct mmap_batch_state {
	domid_t domain;
	unsigned long va;
	struct vm_area_struct *vma;
	int index;
	/* A tristate:
	 *      0 for no errors
	 *      1 if at least one error has happened (and no
	 *          -ENOENT errors have happened)
	 *      -ENOENT if at least 1 -ENOENT has happened.
	 */
	int global_error;
	int version;

	/* User-space gfn array to store errors in the second pass for V1. */
	xen_pfn_t __user *user_gfn;
	/* User-space int array to store errors in the second pass for V2. */
	int __user *user_err;
};

/* auto translated dom0 note: if domU being created is PV, then gfn is
 * mfn(addr on bus). If it's auto xlated, then gfn is pfn (input to HAP).
 */
static int mmap_batch_fn(void *data, int nr, void *state)
{
	xen_pfn_t *gfnp = data;
	struct mmap_batch_state *st = state;
	struct vm_area_struct *vma = st->vma;
	struct page **pages = vma->vm_private_data;
	struct page **cur_pages = NULL;
	int ret;

	if (!xen_pv_domain())
		cur_pages = &pages[st->index];

	BUG_ON(nr < 0);
	ret = xen_remap_domain_gfn_array(st->vma, st->va & PAGE_MASK, gfnp, nr,
					 (int *)gfnp, st->vma->vm_page_prot,
					 st->domain, cur_pages);

	/* Adjust the global_error? */
	if (ret != nr) {
		if (ret == -ENOENT)
			st->global_error = -ENOENT;
		else {
			/* Record that at least one error has happened. */
			if (st->global_error == 0)
				st->global_error = 1;
		}
	}
	st->va += XEN_PAGE_SIZE * nr;
	st->index += nr / XEN_PFN_PER_PAGE;

	return 0;
}

static int mmap_return_error(int err, struct mmap_batch_state *st)
{
	int ret;

	if (st->version == 1) {
		if (err) {
			xen_pfn_t gfn;

			ret = get_user(gfn, st->user_gfn);
			if (ret < 0)
				return ret;
			/*
			 * V1 encodes the error codes in the 32bit top
			 * nibble of the gfn (with its known
			 * limitations vis-a-vis 64 bit callers).
			 */
			gfn |= (err == -ENOENT) ?
				PRIVCMD_MMAPBATCH_PAGED_ERROR :
				PRIVCMD_MMAPBATCH_MFN_ERROR;
			return __put_user(gfn, st->user_gfn++);
		} else
			st->user_gfn++;
	} else { /* st->version == 2 */
		if (err)
			return __put_user(err, st->user_err++);
		else
			st->user_err++;
	}

	return 0;
}

static int mmap_return_errors(void *data, int nr, void *state)
{
	struct mmap_batch_state *st = state;
	int *errs = data;
	int i;
	int ret;

	for (i = 0; i < nr; i++) {
		ret = mmap_return_error(errs[i], st);
		if (ret < 0)
			return ret;
	}
	return 0;
}

/* Allocate pfns that are then mapped with gfns from foreign domid. Update
 * the vma with the page info to use later.
 * Returns: 0 if success, otherwise -errno
 */
static int alloc_empty_pages(struct vm_area_struct *vma, int numpgs)
{
	int rc;
	struct page **pages;

	pages = kvzalloc_objs(pages[0], numpgs);
	if (pages == NULL)
		return -ENOMEM;

	rc = xen_alloc_unpopulated_pages(numpgs, pages);
	if (rc != 0) {
		pr_warn("%s Could not alloc %d pfns rc:%d\n", __func__,
			numpgs, rc);
		kvfree(pages);
		return -ENOMEM;
	}
	BUG_ON(vma->vm_private_data != NULL);
	vma->vm_private_data = pages;

	return 0;
}

static const struct vm_operations_struct privcmd_vm_ops;

static long privcmd_ioctl_mmap_batch(
	struct file *file, void __user *udata, int version)
{
	struct privcmd_data *data = file->private_data;
	int ret;
	struct privcmd_mmapbatch_v2 m;
	struct mm_struct *mm = current->mm;
	struct vm_area_struct *vma;
	unsigned long nr_pages;
	LIST_HEAD(pagelist);
	struct mmap_batch_state state;

	switch (version) {
	case 1:
		if (copy_from_user(&m, udata, sizeof(struct privcmd_mmapbatch)))
			return -EFAULT;
		/* Returns per-frame error in m.arr. */
		m.err = NULL;
		if (!access_ok(m.arr, m.num * sizeof(*m.arr)))
			return -EFAULT;
		break;
	case 2:
		if (copy_from_user(&m, udata, sizeof(struct privcmd_mmapbatch_v2)))
			return -EFAULT;
		/* Returns per-frame error code in m.err. */
		if (!access_ok(m.err, m.num * (sizeof(*m.err))))
			return -EFAULT;
		break;
	default:
		return -EINVAL;
	}

	/* If restriction is in place, check the domid matches */
	if (data->domid != DOMID_INVALID && data->domid != m.dom)
		return -EPERM;

	nr_pages = DIV_ROUND_UP(m.num, XEN_PFN_PER_PAGE);
	if ((m.num <= 0) || (nr_pages > (LONG_MAX >> PAGE_SHIFT)))
		return -EINVAL;

	ret = gather_array(&pagelist, m.num, sizeof(xen_pfn_t), m.arr);

	if (ret)
		goto out;
	if (list_empty(&pagelist)) {
		ret = -EINVAL;
		goto out;
	}

	if (version == 2) {
		/* Zero error array now to only copy back actual errors. */
		if (clear_user(m.err, sizeof(int) * m.num)) {
			ret = -EFAULT;
			goto out;
		}
	}

	mmap_write_lock(mm);

	vma = find_vma(mm, m.addr);
	if (!vma ||
	    vma->vm_ops != &privcmd_vm_ops) {
		ret = -EINVAL;
		goto out_unlock;
	}

	/*
	 * Caller must either:
	 *
	 * Map the whole VMA range, which will also allocate all the
	 * pages required for the auto_translated_physmap case.
	 *
	 * Or
	 *
	 * Map unmapped holes left from a previous map attempt (e.g.,
	 * because those foreign frames were previously paged out).
	 */
	if (vma->vm_private_data == NULL) {
		if (m.addr != vma->vm_start ||
		    m.addr + (nr_pages << PAGE_SHIFT) != vma->vm_end) {
			ret = -EINVAL;
			goto out_unlock;
		}
		if (!xen_pv_domain()) {
			ret = alloc_empty_pages(vma, nr_pages);
			if (ret < 0)
				goto out_unlock;
		} else
			vma->vm_private_data = PRIV_VMA_LOCKED;
	} else {
		if (m.addr < vma->vm_start ||
		    m.addr + (nr_pages << PAGE_SHIFT) > vma->vm_end) {
			ret = -EINVAL;
			goto out_unlock;
		}
		if (privcmd_vma_range_is_mapped(vma, m.addr, nr_pages)) {
			ret = -EINVAL;
			goto out_unlock;
		}
	}

	state.domain        = m.dom;
	state.vma           = vma;
	state.va            = m.addr;
	state.index         = 0;
	state.global_error  = 0;
	state.version       = version;

	BUILD_BUG_ON(((PAGE_SIZE / sizeof(xen_pfn_t)) % XEN_PFN_PER_PAGE) != 0);
	/* mmap_batch_fn guarantees ret == 0 */
	BUG_ON(traverse_pages_block(m.num, sizeof(xen_pfn_t),
				    &pagelist, mmap_batch_fn, &state));

	mmap_write_unlock(mm);

	if (state.global_error) {
		/* Write back errors in second pass. */
		state.user_gfn = (xen_pfn_t *)m.arr;
		state.user_err = m.err;
		ret = traverse_pages_block(m.num, sizeof(xen_pfn_t),
					   &pagelist, mmap_return_errors, &state);
	} else
		ret = 0;

	/* If we have not had any EFAULT-like global errors then set the global
	 * error to -ENOENT if necessary. */
	if ((ret == 0) && (state.global_error == -ENOENT))
		ret = -ENOENT;

out:
	free_page_list(&pagelist);
	return ret;

out_unlock:
	mmap_write_unlock(mm);
	goto out;
}

static int lock_pages(
	struct privcmd_dm_op_buf kbufs[], unsigned int num,
	struct page *pages[], unsigned int nr_pages, unsigned int *pinned)
{
	unsigned int i, off = 0;

	for (i = 0; i < num; ) {
		unsigned int requested;
		int page_count;

		requested = DIV_ROUND_UP(
			offset_in_page(kbufs[i].uptr) + kbufs[i].size,
			PAGE_SIZE) - off;
		if (requested > nr_pages)
			return -ENOSPC;

		page_count = pin_user_pages_fast(
			(unsigned long)kbufs[i].uptr + off * PAGE_SIZE,
			requested, FOLL_WRITE, pages);
		if (page_count <= 0)
			return page_count ? : -EFAULT;

		*pinned += page_count;
		nr_pages -= page_count;
		pages += page_count;

		off = (requested == page_count) ? 0 : off + page_count;
		i += !off;
	}

	return 0;
}

static void unlock_pages(struct page *pages[], unsigned int nr_pages)
{
	unpin_user_pages_dirty_lock(pages, nr_pages, true);
}

static long privcmd_ioctl_dm_op(struct file *file, void __user *udata)
{
	struct privcmd_data *data = file->private_data;
	struct privcmd_dm_op kdata;
	struct privcmd_dm_op_buf *kbufs;
	unsigned int nr_pages = 0;
	struct page **pages = NULL;
	struct xen_dm_op_buf *xbufs = NULL;
	unsigned int i;
	long rc;
	unsigned int pinned = 0;

	if (copy_from_user(&kdata, udata, sizeof(kdata)))
		return -EFAULT;

	/* If restriction is in place, check the domid matches */
	if (data->domid != DOMID_INVALID && data->domid != kdata.dom)
		return -EPERM;

	if (kdata.num == 0)
		return 0;

	if (kdata.num > privcmd_dm_op_max_num)
		return -E2BIG;

	kbufs = kzalloc_objs(*kbufs, kdata.num);
	if (!kbufs)
		return -ENOMEM;

	if (copy_from_user(kbufs, kdata.ubufs,
			   sizeof(*kbufs) * kdata.num)) {
		rc = -EFAULT;
		goto out;
	}

	for (i = 0; i < kdata.num; i++) {
		if (kbufs[i].size > privcmd_dm_op_buf_max_size) {
			rc = -E2BIG;
			goto out;
		}

		if (!access_ok(kbufs[i].uptr,
			       kbufs[i].size)) {
			rc = -EFAULT;
			goto out;
		}

		nr_pages += DIV_ROUND_UP(
			offset_in_page(kbufs[i].uptr) + kbufs[i].size,
			PAGE_SIZE);
	}

	pages = kzalloc_objs(*pages, nr_pages);
	if (!pages) {
		rc = -ENOMEM;
		goto out;
	}

	xbufs = kzalloc_objs(*xbufs, kdata.num);
	if (!xbufs) {
		rc = -ENOMEM;
		goto out;
	}

	rc = lock_pages(kbufs, kdata.num, pages, nr_pages, &pinned);
	if (rc < 0)
		goto out;

	for (i = 0; i < kdata.num; i++) {
		set_xen_guest_handle(xbufs[i].h, kbufs[i].uptr);
		xbufs[i].size = kbufs[i].size;
	}

	xen_preemptible_hcall_begin();
	rc = HYPERVISOR_dm_op(kdata.dom, kdata.num, xbufs);
	xen_preemptible_hcall_end();

out:
	unlock_pages(pages, pinned);
	kfree(xbufs);
	kfree(pages);
	kfree(kbufs);

	return rc;
}

static long privcmd_ioctl_restrict(struct file *file, void __user *udata)
{
	struct privcmd_data *data = file->private_data;
	domid_t dom;

	if (copy_from_user(&dom, udata, sizeof(dom)))
		return -EFAULT;

	/* Set restriction to the specified domain, or check it matches */
	if (data->domid == DOMID_INVALID)
		data->domid = dom;
	else if (data->domid != dom)
		return -EINVAL;

	return 0;
}

static long privcmd_ioctl_mmap_resource(struct file *file,
				struct privcmd_mmap_resource __user *udata)
{
	struct privcmd_data *data = file->private_data;
	struct mm_struct *mm = current->mm;
	struct vm_area_struct *vma;
	struct privcmd_mmap_resource kdata;
	xen_pfn_t *pfns = NULL;
	struct xen_mem_acquire_resource xdata = { };
	int rc;

	if (copy_from_user(&kdata, udata, sizeof(kdata)))
		return -EFAULT;

	/* If restriction is in place, check the domid matches */
	if (data->domid != DOMID_INVALID && data->domid != kdata.dom)
		return -EPERM;

	/* Both fields must be set or unset */
	if (!!kdata.addr != !!kdata.num)
		return -EINVAL;

	xdata.domid = kdata.dom;
	xdata.type = kdata.type;
	xdata.id = kdata.id;

	if (!kdata.addr && !kdata.num) {
		/* Query the size of the resource. */
		rc = HYPERVISOR_memory_op(XENMEM_acquire_resource, &xdata);
		if (rc)
			return rc;
		return __put_user(xdata.nr_frames, &udata->num);
	}

	mmap_write_lock(mm);

	vma = find_vma(mm, kdata.addr);
	if (!vma || vma->vm_ops != &privcmd_vm_ops) {
		rc = -EINVAL;
		goto out;
	}

	pfns = kzalloc_objs(*pfns, kdata.num, GFP_KERNEL | __GFP_NOWARN);
	if (!pfns) {
		rc = -ENOMEM;
		goto out;
	}

	if (!xen_pv_domain()) {
		unsigned int nr = DIV_ROUND_UP(kdata.num, XEN_PFN_PER_PAGE);
		struct page **pages;
		unsigned int i;

		rc = alloc_empty_pages(vma, nr);
		if (rc < 0)
			goto out;

		pages = vma->vm_private_data;

		for (i = 0; i < kdata.num; i++) {
			xen_pfn_t pfn =
				page_to_xen_pfn(pages[i / XEN_PFN_PER_PAGE]);

			pfns[i] = pfn + (i % XEN_PFN_PER_PAGE);
		}
	} else
		vma->vm_private_data = PRIV_VMA_LOCKED;

	xdata.frame = kdata.idx;
	xdata.nr_frames = kdata.num;
	set_xen_guest_handle(xdata.frame_list, pfns);

	xen_preemptible_hcall_begin();
	rc = HYPERVISOR_memory_op(XENMEM_acquire_resource, &xdata);
	xen_preemptible_hcall_end();

	if (rc)
		goto out;

	if (!xen_pv_domain()) {
		rc = xen_remap_vma_range(vma, kdata.addr, kdata.num << PAGE_SHIFT);
	} else {
		unsigned int domid =
			(xdata.flags & XENMEM_rsrc_acq_caller_owned) ?
			DOMID_SELF : kdata.dom;
		int num, *errs = (int *)pfns;

		BUILD_BUG_ON(sizeof(*errs) > sizeof(*pfns));
		num = xen_remap_domain_mfn_array(vma,
						 kdata.addr & PAGE_MASK,
						 pfns, kdata.num, errs,
						 vma->vm_page_prot,
						 domid);
		if (num < 0)
			rc = num;
		else if (num != kdata.num) {
			unsigned int i;

			for (i = 0; i < num; i++) {
				rc = errs[i];
				if (rc < 0)
					break;
			}
		} else
			rc = 0;
	}

out:
	mmap_write_unlock(mm);
	kfree(pfns);

	return rc;
}

static long privcmd_ioctl_pcidev_get_gsi(struct file *file, void __user *udata)
{
#if defined(CONFIG_XEN_ACPI)
	int rc;
	struct privcmd_pcidev_get_gsi kdata;

	if (copy_from_user(&kdata, udata, sizeof(kdata)))
		return -EFAULT;

	rc = xen_acpi_get_gsi_from_sbdf(kdata.sbdf);
	if (rc < 0)
		return rc;

	kdata.gsi = rc;
	if (copy_to_user(udata, &kdata, sizeof(kdata)))
		return -EFAULT;

	return 0;
#else
	return -EINVAL;
#endif
}

#ifdef CONFIG_XEN_PRIVCMD_EVENTFD
/* Irqfd support */
static struct workqueue_struct *irqfd_cleanup_wq;
static DEFINE_SPINLOCK(irqfds_lock);
DEFINE_STATIC_SRCU(irqfds_srcu);
static LIST_HEAD(irqfds_list);

struct privcmd_kernel_irqfd {
	struct xen_dm_op_buf xbufs;
	domid_t dom;
	bool error;
	struct eventfd_ctx *eventfd;
	struct work_struct shutdown;
	wait_queue_entry_t wait;
	struct list_head list;
	poll_table pt;
};

static void irqfd_deactivate(struct privcmd_kernel_irqfd *kirqfd)
{
	lockdep_assert_held(&irqfds_lock);

	list_del_init(&kirqfd->list);
	queue_work(irqfd_cleanup_wq, &kirqfd->shutdown);
}

static void irqfd_shutdown(struct work_struct *work)
{
	struct privcmd_kernel_irqfd *kirqfd =
		container_of(work, struct privcmd_kernel_irqfd, shutdown);
	u64 cnt;

	/* Make sure irqfd has been initialized in assign path */
	synchronize_srcu(&irqfds_srcu);

	eventfd_ctx_remove_wait_queue(kirqfd->eventfd, &kirqfd->wait, &cnt);
	eventfd_ctx_put(kirqfd->eventfd);
	kfree(kirqfd);
}

static void irqfd_inject(struct privcmd_kernel_irqfd *kirqfd)
{
	u64 cnt;
	long rc;

	eventfd_ctx_do_read(kirqfd->eventfd, &cnt);

	xen_preemptible_hcall_begin();
	rc = HYPERVISOR_dm_op(kirqfd->dom, 1, &kirqfd->xbufs);
	xen_preemptible_hcall_end();

	/* Don't repeat the error message for consecutive failures */
	if (rc && !kirqfd->error) {
		pr_err("Failed to configure irq for guest domain: %d\n",
		       kirqfd->dom);
	}

	kirqfd->error = rc;
}

static int
irqfd_wakeup(wait_queue_entry_t *wait, unsigned int mode, int sync, void *key)
{
	struct privcmd_kernel_irqfd *kirqfd =
		container_of(wait, struct privcmd_kernel_irqfd, wait);
	__poll_t flags = key_to_poll(key);

	if (flags & EPOLLIN)
		irqfd_inject(kirqfd);

	if (flags & EPOLLHUP) {
		unsigned long flags;

		spin_lock_irqsave(&irqfds_lock, flags);
		irqfd_deactivate(kirqfd);
		spin_unlock_irqrestore(&irqfds_lock, flags);
	}

	return 0;
}

static void
irqfd_poll_func(struct file *file, wait_queue_head_t *wqh, poll_table *pt)
{
	struct privcmd_kernel_irqfd *kirqfd =
		container_of(pt, struct privcmd_kernel_irqfd, pt);

	add_wait_queue_priority(wqh, &kirqfd->wait);
}

static int privcmd_irqfd_assign(struct privcmd_irqfd *irqfd)
{
	struct privcmd_kernel_irqfd *kirqfd, *tmp;
	unsigned long flags;
	__poll_t events;
	void *dm_op;
	int ret, idx;

	CLASS(fd, f)(irqfd->fd);

	kirqfd = kzalloc(sizeof(*kirqfd) + irqfd->size, GFP_KERNEL);
	if (!kirqfd)
		return -ENOMEM;
	dm_op = kirqfd + 1;

	if (copy_from_user(dm_op, u64_to_user_ptr(irqfd->dm_op), irqfd->size)) {
		ret = -EFAULT;
		goto error_kfree;
	}

	kirqfd->xbufs.size = irqfd->size;
	set_xen_guest_handle(kirqfd->xbufs.h, dm_op);
	kirqfd->dom = irqfd->dom;
	INIT_WORK(&kirqfd->shutdown, irqfd_shutdown);

	if (fd_empty(f)) {
		ret = -EBADF;
		goto error_kfree;
	}

	kirqfd->eventfd = eventfd_ctx_fileget(fd_file(f));
	if (IS_ERR(kirqfd->eventfd)) {
		ret = PTR_ERR(kirqfd->eventfd);
		goto error_kfree;
	}

	/*
	 * Install our own custom wake-up handling so we are notified via a
	 * callback whenever someone signals the underlying eventfd.
	 */
	init_waitqueue_func_entry(&kirqfd->wait, irqfd_wakeup);
	init_poll_funcptr(&kirqfd->pt, irqfd_poll_func);

	spin_lock_irqsave(&irqfds_lock, flags);

	list_for_each_entry(tmp, &irqfds_list, list) {
		if (kirqfd->eventfd == tmp->eventfd) {
			ret = -EBUSY;
			spin_unlock_irqrestore(&irqfds_lock, flags);
			goto error_eventfd;
		}
	}

	idx = srcu_read_lock(&irqfds_srcu);
	list_add_tail(&kirqfd->list, &irqfds_list);
	spin_unlock_irqrestore(&irqfds_lock, flags);

	/*
	 * Check if there was an event already pending on the eventfd before we
	 * registered, and trigger it as if we didn't miss it.
	 */
	events = vfs_poll(fd_file(f), &kirqfd->pt);
	if (events & EPOLLIN)
		irqfd_inject(kirqfd);

	srcu_read_unlock(&irqfds_srcu, idx);
	return 0;

error_eventfd:
	eventfd_ctx_put(kirqfd->eventfd);

error_kfree:
	kfree(kirqfd);
	return ret;
}

static int privcmd_irqfd_deassign(struct privcmd_irqfd *irqfd)
{
	struct privcmd_kernel_irqfd *kirqfd;
	struct eventfd_ctx *eventfd;
	unsigned long flags;

	eventfd = eventfd_ctx_fdget(irqfd->fd);
	if (IS_ERR(eventfd))
		return PTR_ERR(eventfd);

	spin_lock_irqsave(&irqfds_lock, flags);

	list_for_each_entry(kirqfd, &irqfds_list, list) {
		if (kirqfd->eventfd == eventfd) {
			irqfd_deactivate(kirqfd);
			break;
		}
	}

	spin_unlock_irqrestore(&irqfds_lock, flags);

	eventfd_ctx_put(eventfd);

	/*
	 * Block until we know all outstanding shutdown jobs have completed so
	 * that we guarantee there will not be any more interrupts once this
	 * deassign function returns.
	 */
	flush_workqueue(irqfd_cleanup_wq);

	return 0;
}

static long privcmd_ioctl_irqfd(struct file *file, void __user *udata)
{
	struct privcmd_data *data = file->private_data;
	struct privcmd_irqfd irqfd;

	if (copy_from_user(&irqfd, udata, sizeof(irqfd)))
		return -EFAULT;

	/* No other flags should be set */
	if (irqfd.flags & ~PRIVCMD_IRQFD_FLAG_DEASSIGN)
		return -EINVAL;

	/* If restriction is in place, check the domid matches */
	if (data->domid != DOMID_INVALID && data->domid != irqfd.dom)
		return -EPERM;

	if (irqfd.flags & PRIVCMD_IRQFD_FLAG_DEASSIGN)
		return privcmd_irqfd_deassign(&irqfd);

	return privcmd_irqfd_assign(&irqfd);
}

static int privcmd_irqfd_init(void)
{
	irqfd_cleanup_wq = alloc_workqueue("privcmd-irqfd-cleanup", WQ_PERCPU,
					   0);
	if (!irqfd_cleanup_wq)
		return -ENOMEM;

	return 0;
}

static void privcmd_irqfd_exit(void)
{
	struct privcmd_kernel_irqfd *kirqfd, *tmp;
	unsigned long flags;

	spin_lock_irqsave(&irqfds_lock, flags);

	list_for_each_entry_safe(kirqfd, tmp, &irqfds_list, list)
		irqfd_deactivate(kirqfd);

	spin_unlock_irqrestore(&irqfds_lock, flags);

	destroy_workqueue(irqfd_cleanup_wq);
}

/* Ioeventfd Support */
#define QUEUE_NOTIFY_VQ_MASK 0xFFFF

static DEFINE_MUTEX(ioreq_lock);
static LIST_HEAD(ioreq_list);

/* per-eventfd structure */
struct privcmd_kernel_ioeventfd {
	struct eventfd_ctx *eventfd;
	struct list_head list;
	u64 addr;
	unsigned int addr_len;
	unsigned int vq;
};

/* per-guest CPU / port structure */
struct ioreq_port {
	int vcpu;
	unsigned int port;
	struct privcmd_kernel_ioreq *kioreq;
};

/* per-guest structure */
struct privcmd_kernel_ioreq {
	domid_t dom;
	unsigned int vcpus;
	u64 uioreq;
	struct ioreq *ioreq;
	spinlock_t lock; /* Protects ioeventfds list */
	struct list_head ioeventfds;
	struct list_head list;
	struct ioreq_port ports[] __counted_by(vcpus);
};

static irqreturn_t ioeventfd_interrupt(int irq, void *dev_id)
{
	struct ioreq_port *port = dev_id;
	struct privcmd_kernel_ioreq *kioreq = port->kioreq;
	struct ioreq *ioreq = &kioreq->ioreq[port->vcpu];
	struct privcmd_kernel_ioeventfd *kioeventfd;
	unsigned int state = STATE_IOREQ_READY;

	if (ioreq->state != STATE_IOREQ_READY ||
	    ioreq->type != IOREQ_TYPE_COPY || ioreq->dir != IOREQ_WRITE)
		return IRQ_NONE;

	/*
	 * We need a barrier, smp_mb(), here to ensure reads are finished before
	 * `state` is updated. Since the lock implementation ensures that
	 * appropriate barrier will be added anyway, we can avoid adding
	 * explicit barrier here.
	 *
	 * Ideally we don't need to update `state` within the locks, but we do
	 * that here to avoid adding explicit barrier.
	 */

	spin_lock(&kioreq->lock);
	ioreq->state = STATE_IOREQ_INPROCESS;

	list_for_each_entry(kioeventfd, &kioreq->ioeventfds, list) {
		if (ioreq->addr == kioeventfd->addr + VIRTIO_MMIO_QUEUE_NOTIFY &&
		    ioreq->size == kioeventfd->addr_len &&
		    (ioreq->data & QUEUE_NOTIFY_VQ_MASK) == kioeventfd->vq) {
			eventfd_signal(kioeventfd->eventfd);
			state = STATE_IORESP_READY;
			break;
		}
	}
	spin_unlock(&kioreq->lock);

	/*
	 * We need a barrier, smp_mb(), here to ensure writes are finished
	 * before `state` is updated. Since the lock implementation ensures that
	 * appropriate barrier will be added anyway, we can avoid adding
	 * explicit barrier here.
	 */

	ioreq->state = state;

	if (state == STATE_IORESP_READY) {
		notify_remote_via_evtchn(port->port);
		return IRQ_HANDLED;
	}

	return IRQ_NONE;
}

static void ioreq_free(struct privcmd_kernel_ioreq *kioreq)
{
	struct ioreq_port *ports = kioreq->ports;
	int i;

	lockdep_assert_held(&ioreq_lock);

	list_del(&kioreq->list);

	for (i = kioreq->vcpus - 1; i >= 0; i--)
		unbind_from_irqhandler(irq_from_evtchn(ports[i].port), &ports[i]);

	kfree(kioreq);
}

static
struct privcmd_kernel_ioreq *alloc_ioreq(struct privcmd_ioeventfd *ioeventfd)
{
	struct privcmd_kernel_ioreq *kioreq;
	struct mm_struct *mm = current->mm;
	struct vm_area_struct *vma;
	struct page **pages;
	unsigned int *ports;
	int ret, size, i;

	lockdep_assert_held(&ioreq_lock);

	size = struct_size(kioreq, ports, ioeventfd->vcpus);
	kioreq = kzalloc(size, GFP_KERNEL);
	if (!kioreq)
		return ERR_PTR(-ENOMEM);

	kioreq->dom = ioeventfd->dom;
	kioreq->vcpus = ioeventfd->vcpus;
	kioreq->uioreq = ioeventfd->ioreq;
	spin_lock_init(&kioreq->lock);
	INIT_LIST_HEAD(&kioreq->ioeventfds);

	/* The memory for ioreq server must have been mapped earlier */
	mmap_write_lock(mm);
	vma = find_vma(mm, (unsigned long)ioeventfd->ioreq);
	if (!vma) {
		pr_err("Failed to find vma for ioreq page!\n");
		mmap_write_unlock(mm);
		ret = -EFAULT;
		goto error_kfree;
	}

	pages = vma->vm_private_data;
	kioreq->ioreq = (struct ioreq *)(page_to_virt(pages[0]));
	mmap_write_unlock(mm);

	ports = memdup_array_user(u64_to_user_ptr(ioeventfd->ports),
				  kioreq->vcpus, sizeof(*ports));
	if (IS_ERR(ports)) {
		ret = PTR_ERR(ports);
		goto error_kfree;
	}

	for (i = 0; i < kioreq->vcpus; i++) {
		kioreq->ports[i].vcpu = i;
		kioreq->ports[i].port = ports[i];
		kioreq->ports[i].kioreq = kioreq;

		ret = bind_evtchn_to_irqhandler_lateeoi(ports[i],
				ioeventfd_interrupt, IRQF_SHARED, "ioeventfd",
				&kioreq->ports[i]);
		if (ret < 0)
			goto error_unbind;
	}

	kfree(ports);

	list_add_tail(&kioreq->list, &ioreq_list);

	return kioreq;

error_unbind:
	while (--i >= 0)
		unbind_from_irqhandler(irq_from_evtchn(ports[i]), &kioreq->ports[i]);

	kfree(ports);
error_kfree:
	kfree(kioreq);
	return ERR_PTR(ret);
}

static struct privcmd_kernel_ioreq *
get_ioreq(struct privcmd_ioeventfd *ioeventfd, struct eventfd_ctx *eventfd)
{
	struct privcmd_kernel_ioreq *kioreq;
	unsigned long flags;

	list_for_each_entry(kioreq, &ioreq_list, list) {
		struct privcmd_kernel_ioeventfd *kioeventfd;

		/*
		 * kioreq fields can be accessed here without a lock as they are
		 * never updated after being added to the ioreq_list.
		 */
		if (kioreq->uioreq != ioeventfd->ioreq) {
			continue;
		} else if (kioreq->dom != ioeventfd->dom ||
			   kioreq->vcpus != ioeventfd->vcpus) {
			pr_err("Invalid ioeventfd configuration mismatch, dom (%u vs %u), vcpus (%u vs %u)\n",
			       kioreq->dom, ioeventfd->dom, kioreq->vcpus,
			       ioeventfd->vcpus);
			return ERR_PTR(-EINVAL);
		}

		/* Look for a duplicate eventfd for the same guest */
		spin_lock_irqsave(&kioreq->lock, flags);
		list_for_each_entry(kioeventfd, &kioreq->ioeventfds, list) {
			if (eventfd == kioeventfd->eventfd) {
				spin_unlock_irqrestore(&kioreq->lock, flags);
				return ERR_PTR(-EBUSY);
			}
		}
		spin_unlock_irqrestore(&kioreq->lock, flags);

		return kioreq;
	}

	/* Matching kioreq isn't found, allocate a new one */
	return alloc_ioreq(ioeventfd);
}

static void ioeventfd_free(struct privcmd_kernel_ioeventfd *kioeventfd)
{
	list_del(&kioeventfd->list);
	eventfd_ctx_put(kioeventfd->eventfd);
	kfree(kioeventfd);
}

static int privcmd_ioeventfd_assign(struct privcmd_ioeventfd *ioeventfd)
{
	struct privcmd_kernel_ioeventfd *kioeventfd;
	struct privcmd_kernel_ioreq *kioreq;
	unsigned long flags;
	int ret;

	/* Check for range overflow */
	if (ioeventfd->addr + ioeventfd->addr_len < ioeventfd->addr)
		return -EINVAL;

	/* Vhost requires us to support length 1, 2, 4, and 8 */
	if (!(ioeventfd->addr_len == 1 || ioeventfd->addr_len == 2 ||
	      ioeventfd->addr_len == 4 || ioeventfd->addr_len == 8))
		return -EINVAL;

	/* 4096 vcpus limit enough ? */
	if (!ioeventfd->vcpus || ioeventfd->vcpus > 4096)
		return -EINVAL;

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

	kioeventfd->eventfd = eventfd_ctx_fdget(ioeventfd->event_fd);
	if (IS_ERR(kioeventfd->eventfd)) {
		ret = PTR_ERR(kioeventfd->eventfd);
		goto error_kfree;
	}

	kioeventfd->addr = ioeventfd->addr;
	kioeventfd->addr_len = ioeventfd->addr_len;
	kioeventfd->vq = ioeventfd->vq;

	mutex_lock(&ioreq_lock);
	kioreq = get_ioreq(ioeventfd, kioeventfd->eventfd);
	if (IS_ERR(kioreq)) {
		mutex_unlock(&ioreq_lock);
		ret = PTR_ERR(kioreq);
		goto error_eventfd;
	}

	spin_lock_irqsave(&kioreq->lock, flags);
	list_add_tail(&kioeventfd->list, &kioreq->ioeventfds);
	spin_unlock_irqrestore(&kioreq->lock, flags);

	mutex_unlock(&ioreq_lock);

	return 0;

error_eventfd:
	eventfd_ctx_put(kioeventfd->eventfd);

error_kfree:
	kfree(kioeventfd);
	return ret;
}

static int privcmd_ioeventfd_deassign(struct privcmd_ioeventfd *ioeventfd)
{
	struct privcmd_kernel_ioreq *kioreq, *tkioreq;
	struct eventfd_ctx *eventfd;
	unsigned long flags;
	int ret = 0;

	eventfd = eventfd_ctx_fdget(ioeventfd->event_fd);
	if (IS_ERR(eventfd))
		return PTR_ERR(eventfd);

	mutex_lock(&ioreq_lock);
	list_for_each_entry_safe(kioreq, tkioreq, &ioreq_list, list) {
		struct privcmd_kernel_ioeventfd *kioeventfd, *tmp;
		/*
		 * kioreq fields can be accessed here without a lock as they are
		 * never updated after being added to the ioreq_list.
		 */
		if (kioreq->dom != ioeventfd->dom ||
		    kioreq->uioreq != ioeventfd->ioreq ||
		    kioreq->vcpus != ioeventfd->vcpus)
			continue;

		spin_lock_irqsave(&kioreq->lock, flags);
		list_for_each_entry_safe(kioeventfd, tmp, &kioreq->ioeventfds, list) {
			if (eventfd == kioeventfd->eventfd) {
				ioeventfd_free(kioeventfd);
				spin_unlock_irqrestore(&kioreq->lock, flags);

				if (list_empty(&kioreq->ioeventfds))
					ioreq_free(kioreq);
				goto unlock;
			}
		}
		spin_unlock_irqrestore(&kioreq->lock, flags);
		break;
	}

	pr_err("Ioeventfd isn't already assigned, dom: %u, addr: %llu\n",
	       ioeventfd->dom, ioeventfd->addr);
	ret = -ENODEV;

unlock:
	mutex_unlock(&ioreq_lock);
	eventfd_ctx_put(eventfd);

	return ret;
}

static long privcmd_ioctl_ioeventfd(struct file *file, void __user *udata)
{
	struct privcmd_data *data = file->private_data;
	struct privcmd_ioeventfd ioeventfd;

	if (copy_from_user(&ioeventfd, udata, sizeof(ioeventfd)))
		return -EFAULT;

	/* No other flags should be set */
	if (ioeventfd.flags & ~PRIVCMD_IOEVENTFD_FLAG_DEASSIGN)
		return -EINVAL;

	/* If restriction is in place, check the domid matches */
	if (data->domid != DOMID_INVALID && data->domid != ioeventfd.dom)
		return -EPERM;

	if (ioeventfd.flags & PRIVCMD_IOEVENTFD_FLAG_DEASSIGN)
		return privcmd_ioeventfd_deassign(&ioeventfd);

	return privcmd_ioeventfd_assign(&ioeventfd);
}

static void privcmd_ioeventfd_exit(void)
{
	struct privcmd_kernel_ioreq *kioreq, *tmp;
	unsigned long flags;

	mutex_lock(&ioreq_lock);
	list_for_each_entry_safe(kioreq, tmp, &ioreq_list, list) {
		struct privcmd_kernel_ioeventfd *kioeventfd, *tmp;

		spin_lock_irqsave(&kioreq->lock, flags);
		list_for_each_entry_safe(kioeventfd, tmp, &kioreq->ioeventfds, list)
			ioeventfd_free(kioeventfd);
		spin_unlock_irqrestore(&kioreq->lock, flags);

		ioreq_free(kioreq);
	}
	mutex_unlock(&ioreq_lock);
}
#else
static inline long privcmd_ioctl_irqfd(struct file *file, void __user *udata)
{
	return -EOPNOTSUPP;
}

static inline int privcmd_irqfd_init(void)
{
	return 0;
}

static inline void privcmd_irqfd_exit(void)
{
}

static inline long privcmd_ioctl_ioeventfd(struct file *file, void __user *udata)
{
	return -EOPNOTSUPP;
}

static inline void privcmd_ioeventfd_exit(void)
{
}
#endif /* CONFIG_XEN_PRIVCMD_EVENTFD */

static long privcmd_ioctl(struct file *file,
			  unsigned int cmd, unsigned long data)
{
	int ret = -ENOTTY;
	void __user *udata = (void __user *) data;

	switch (cmd) {
	case IOCTL_PRIVCMD_HYPERCALL:
		ret = privcmd_ioctl_hypercall(file, udata);
		break;

	case IOCTL_PRIVCMD_MMAP:
		ret = privcmd_ioctl_mmap(file, udata);
		break;

	case IOCTL_PRIVCMD_MMAPBATCH:
		ret = privcmd_ioctl_mmap_batch(file, udata, 1);
		break;

	case IOCTL_PRIVCMD_MMAPBATCH_V2:
		ret = privcmd_ioctl_mmap_batch(file, udata, 2);
		break;

	case IOCTL_PRIVCMD_DM_OP:
		ret = privcmd_ioctl_dm_op(file, udata);
		break;

	case IOCTL_PRIVCMD_RESTRICT:
		ret = privcmd_ioctl_restrict(file, udata);
		break;

	case IOCTL_PRIVCMD_MMAP_RESOURCE:
		ret = privcmd_ioctl_mmap_resource(file, udata);
		break;

	case IOCTL_PRIVCMD_IRQFD:
		ret = privcmd_ioctl_irqfd(file, udata);
		break;

	case IOCTL_PRIVCMD_IOEVENTFD:
		ret = privcmd_ioctl_ioeventfd(file, udata);
		break;

	case IOCTL_PRIVCMD_PCIDEV_GET_GSI:
		ret = privcmd_ioctl_pcidev_get_gsi(file, udata);
		break;

	default:
		break;
	}

	return ret;
}

static int privcmd_open(struct inode *ino, struct file *file)
{
	struct privcmd_data *data;

	if (wait_event_interruptible(restrict_wait_wq, !restrict_wait) < 0)
		return -EINTR;

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

	data->domid = target_domain;

	file->private_data = data;
	return 0;
}

static int privcmd_release(struct inode *ino, struct file *file)
{
	struct privcmd_data *data = file->private_data;

	kfree(data);
	return 0;
}

static void privcmd_close(struct vm_area_struct *vma)
{
	struct page **pages = vma->vm_private_data;
	int numpgs = vma_pages(vma);
	int numgfns = (vma->vm_end - vma->vm_start) >> XEN_PAGE_SHIFT;
	int rc;

	if (xen_pv_domain() || !numpgs || !pages)
		return;

	rc = xen_unmap_domain_gfn_range(vma, numgfns, pages);
	if (rc == 0)
		xen_free_unpopulated_pages(numpgs, pages);
	else
		pr_crit("unable to unmap MFN range: leaking %d pages. rc=%d\n",
			numpgs, rc);
	kvfree(pages);
}

static int privcmd_may_split(struct vm_area_struct *area, unsigned long addr)
{
	/* Forbid splitting, avoids double free via privcmd_close(). */
	return -EINVAL;
}

static vm_fault_t privcmd_fault(struct vm_fault *vmf)
{
	printk(KERN_DEBUG "privcmd_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_vm_ops = {
	.close = privcmd_close,
	.may_split = privcmd_may_split,
	.fault = privcmd_fault
};

static int privcmd_mmap(struct file *file, struct vm_area_struct *vma)
{
	/* DONTCOPY is essential for Xen because copy_page_range doesn't know
	 * how to recreate these mappings */
	vm_flags_set(vma, VM_IO | VM_PFNMAP | VM_DONTCOPY |
			 VM_DONTEXPAND | VM_DONTDUMP);
	vma->vm_ops = &privcmd_vm_ops;
	vma->vm_private_data = NULL;

	return 0;
}

/*
 * For MMAPBATCH*. This allows asserting the singleshot mapping
 * on a per pfn/pte basis. Mapping calls that fail with ENOENT
 * can be then retried until success.
 */
static int is_mapped_fn(pte_t *pte, unsigned long addr, void *data)
{
	return pte_none(ptep_get(pte)) ? 0 : -EBUSY;
}

static int privcmd_vma_range_is_mapped(
	           struct vm_area_struct *vma,
	           unsigned long addr,
	           unsigned long nr_pages)
{
	return apply_to_page_range(vma->vm_mm, addr, nr_pages << PAGE_SHIFT,
				   is_mapped_fn, NULL) != 0;
}

const struct file_operations xen_privcmd_fops = {
	.owner = THIS_MODULE,
	.unlocked_ioctl = privcmd_ioctl,
	.open = privcmd_open,
	.release = privcmd_release,
	.mmap = privcmd_mmap,
};
EXPORT_SYMBOL_GPL(xen_privcmd_fops);

static struct miscdevice privcmd_dev = {
	.minor = MISC_DYNAMIC_MINOR,
	.name = "xen/privcmd",
	.fops = &xen_privcmd_fops,
};

static int init_restrict(struct notifier_block *notifier,
			 unsigned long event,
			 void *data)
{
	char *target;
	unsigned int domid;

	/* Default to an guaranteed unused domain-id. */
	target_domain = DOMID_IDLE;

	target = xenbus_read(XBT_NIL, "target", "", NULL);
	if (IS_ERR(target) || kstrtouint(target, 10, &domid)) {
		pr_err("No target domain found, blocking all hypercalls\n");
		goto out;
	}

	target_domain = domid;

 out:
	if (!IS_ERR(target))
		kfree(target);

	restrict_wait = false;
	wake_up_all(&restrict_wait_wq);

	return NOTIFY_DONE;
}

static struct notifier_block xenstore_notifier = {
	.notifier_call = init_restrict,
};

static void __init restrict_driver(void)
{
	if (unrestricted) {
		if (security_locked_down(LOCKDOWN_XEN_USER_ACTIONS))
			pr_warn("Kernel is locked down, parameter \"unrestricted\" ignored\n");
		else
			return;
	}

	restrict_wait = true;

	register_xenstore_notifier(&xenstore_notifier);
}

static int __init privcmd_init(void)
{
	int err;

	if (!xen_domain())
		return -ENODEV;

	if (!xen_initial_domain())
		restrict_driver();

	err = misc_register(&privcmd_dev);
	if (err != 0) {
		pr_err("Could not register Xen privcmd device\n");
		return err;
	}

	err = misc_register(&xen_privcmdbuf_dev);
	if (err != 0) {
		pr_err("Could not register Xen hypercall-buf device\n");
		goto err_privcmdbuf;
	}

	err = privcmd_irqfd_init();
	if (err != 0) {
		pr_err("irqfd init failed\n");
		goto err_irqfd;
	}

	return 0;

err_irqfd:
	misc_deregister(&xen_privcmdbuf_dev);
err_privcmdbuf:
	misc_deregister(&privcmd_dev);
	return err;
}

static void __exit privcmd_exit(void)
{
	if (!xen_initial_domain())
		unregister_xenstore_notifier(&xenstore_notifier);

	privcmd_ioeventfd_exit();
	privcmd_irqfd_exit();
	misc_deregister(&privcmd_dev);
	misc_deregister(&xen_privcmdbuf_dev);
}

module_init(privcmd_init);
module_exit(privcmd_exit);
