/*
 * VMware VMCI Driver
 *
 * Copyright (C) 2012 VMware, Inc. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation version 2 and no later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * for more details.
 */

#include <linux/vmw_vmci_defs.h>
#include <linux/vmw_vmci_api.h>
#include <linux/moduleparam.h>
#include <linux/miscdevice.h>
#include <linux/interrupt.h>
#include <linux/highmem.h>
#include <linux/atomic.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/file.h>
#include <linux/init.h>
#include <linux/poll.h>
#include <linux/pci.h>
#include <linux/smp.h>
#include <linux/fs.h>
#include <linux/io.h>

#include "vmci_handle_array.h"
#include "vmci_queue_pair.h"
#include "vmci_datagram.h"
#include "vmci_doorbell.h"
#include "vmci_resource.h"
#include "vmci_context.h"
#include "vmci_driver.h"
#include "vmci_event.h"

#define VMCI_UTIL_NUM_RESOURCES 1

enum {
	VMCI_NOTIFY_RESOURCE_QUEUE_PAIR = 0,
	VMCI_NOTIFY_RESOURCE_DOOR_BELL = 1,
};

enum {
	VMCI_NOTIFY_RESOURCE_ACTION_NOTIFY = 0,
	VMCI_NOTIFY_RESOURCE_ACTION_CREATE = 1,
	VMCI_NOTIFY_RESOURCE_ACTION_DESTROY = 2,
};

/*
 * VMCI driver initialization. This block can also be used to
 * pass initial group membership etc.
 */
struct vmci_init_blk {
	u32 cid;
	u32 flags;
};

/* VMCIqueue_pairAllocInfo_VMToVM */
struct vmci_qp_alloc_info_vmvm {
	struct vmci_handle handle;
	u32 peer;
	u32 flags;
	u64 produce_size;
	u64 consume_size;
	u64 produce_page_file;	  /* User VA. */
	u64 consume_page_file;	  /* User VA. */
	u64 produce_page_file_size;  /* Size of the file name array. */
	u64 consume_page_file_size;  /* Size of the file name array. */
	s32 result;
	u32 _pad;
};

/* VMCISetNotifyInfo: Used to pass notify flag's address to the host driver. */
struct vmci_set_notify_info {
	u64 notify_uva;
	s32 result;
	u32 _pad;
};

/*
 * Per-instance host state
 */
struct vmci_host_dev {
	struct vmci_ctx *context;
	int user_version;
	enum vmci_obj_type ct_type;
	struct mutex lock;  /* Mutex lock for vmci context access */
};

static struct vmci_ctx *host_context;
static bool vmci_host_device_initialized;
static atomic_t vmci_host_active_users = ATOMIC_INIT(0);

/*
 * Determines whether the VMCI host personality is
 * available. Since the core functionality of the host driver is
 * always present, all guests could possibly use the host
 * personality. However, to minimize the deviation from the
 * pre-unified driver state of affairs, we only consider the host
 * device active if there is no active guest device or if there
 * are VMX'en with active VMCI contexts using the host device.
 */
bool vmci_host_code_active(void)
{
	return vmci_host_device_initialized &&
	    (!vmci_guest_code_active() ||
	     atomic_read(&vmci_host_active_users) > 0);
}

/*
 * Called on open of /dev/vmci.
 */
static int vmci_host_open(struct inode *inode, struct file *filp)
{
	struct vmci_host_dev *vmci_host_dev;

	vmci_host_dev = kzalloc(sizeof(struct vmci_host_dev), GFP_KERNEL);
	if (vmci_host_dev == NULL)
		return -ENOMEM;

	vmci_host_dev->ct_type = VMCIOBJ_NOT_SET;
	mutex_init(&vmci_host_dev->lock);
	filp->private_data = vmci_host_dev;

	return 0;
}

/*
 * Called on close of /dev/vmci, most often when the process
 * exits.
 */
static int vmci_host_close(struct inode *inode, struct file *filp)
{
	struct vmci_host_dev *vmci_host_dev = filp->private_data;

	if (vmci_host_dev->ct_type == VMCIOBJ_CONTEXT) {
		vmci_ctx_destroy(vmci_host_dev->context);
		vmci_host_dev->context = NULL;

		/*
		 * The number of active contexts is used to track whether any
		 * VMX'en are using the host personality. It is incremented when
		 * a context is created through the IOCTL_VMCI_INIT_CONTEXT
		 * ioctl.
		 */
		atomic_dec(&vmci_host_active_users);
	}
	vmci_host_dev->ct_type = VMCIOBJ_NOT_SET;

	kfree(vmci_host_dev);
	filp->private_data = NULL;
	return 0;
}

/*
 * This is used to wake up the VMX when a VMCI call arrives, or
 * to wake up select() or poll() at the next clock tick.
 */
static unsigned int vmci_host_poll(struct file *filp, poll_table *wait)
{
	struct vmci_host_dev *vmci_host_dev = filp->private_data;
	struct vmci_ctx *context = vmci_host_dev->context;
	unsigned int mask = 0;

	if (vmci_host_dev->ct_type == VMCIOBJ_CONTEXT) {
		/* Check for VMCI calls to this VM context. */
		if (wait)
			poll_wait(filp, &context->host_context.wait_queue,
				  wait);

		spin_lock(&context->lock);
		if (context->pending_datagrams > 0 ||
		    vmci_handle_arr_get_size(
				context->pending_doorbell_array) > 0) {
			mask = POLLIN;
		}
		spin_unlock(&context->lock);
	}
	return mask;
}

/*
 * Copies the handles of a handle array into a user buffer, and
 * returns the new length in userBufferSize. If the copy to the
 * user buffer fails, the functions still returns VMCI_SUCCESS,
 * but retval != 0.
 */
static int drv_cp_harray_to_user(void __user *user_buf_uva,
				 u64 *user_buf_size,
				 struct vmci_handle_arr *handle_array,
				 int *retval)
{
	u32 array_size = 0;
	struct vmci_handle *handles;

	if (handle_array)
		array_size = vmci_handle_arr_get_size(handle_array);

	if (array_size * sizeof(*handles) > *user_buf_size)
		return VMCI_ERROR_MORE_DATA;

	*user_buf_size = array_size * sizeof(*handles);
	if (*user_buf_size)
		*retval = copy_to_user(user_buf_uva,
				       vmci_handle_arr_get_handles
				       (handle_array), *user_buf_size);

	return VMCI_SUCCESS;
}

/*
 * Sets up a given context for notify to work.  Calls drv_map_bool_ptr()
 * which maps the notify boolean in user VA in kernel space.
 */
static int vmci_host_setup_notify(struct vmci_ctx *context,
				  unsigned long uva)
{
	struct page *page;
	int retval;

	if (context->notify_page) {
		pr_devel("%s: Notify mechanism is already set up\n", __func__);
		return VMCI_ERROR_DUPLICATE_ENTRY;
	}

	/*
	 * We are using 'bool' internally, but let's make sure we explicit
	 * about the size.
	 */
	BUILD_BUG_ON(sizeof(bool) != sizeof(u8));
	if (!access_ok(VERIFY_WRITE, (void __user *)uva, sizeof(u8)))
		return VMCI_ERROR_GENERIC;

	/*
	 * Lock physical page backing a given user VA.
	 */
	retval = get_user_pages_fast(PAGE_ALIGN(uva), 1, 1, &page);
	if (retval != 1)
		return VMCI_ERROR_GENERIC;

	/*
	 * Map the locked page and set up notify pointer.
	 */
	context->notify = kmap(page) + (uva & (PAGE_SIZE - 1));
	vmci_ctx_check_signal_notify(context);

	return VMCI_SUCCESS;
}

static int vmci_host_get_version(struct vmci_host_dev *vmci_host_dev,
				 unsigned int cmd, void __user *uptr)
{
	if (cmd == IOCTL_VMCI_VERSION2) {
		int __user *vptr = uptr;
		if (get_user(vmci_host_dev->user_version, vptr))
			return -EFAULT;
	}

	/*
	 * The basic logic here is:
	 *
	 * If the user sends in a version of 0 tell it our version.
	 * If the user didn't send in a version, tell it our version.
	 * If the user sent in an old version, tell it -its- version.
	 * If the user sent in an newer version, tell it our version.
	 *
	 * The rationale behind telling the caller its version is that
	 * Workstation 6.5 required that VMX and VMCI kernel module were
	 * version sync'd.  All new VMX users will be programmed to
	 * handle the VMCI kernel module version.
	 */

	if (vmci_host_dev->user_version > 0 &&
	    vmci_host_dev->user_version < VMCI_VERSION_HOSTQP) {
		return vmci_host_dev->user_version;
	}

	return VMCI_VERSION;
}

#define vmci_ioctl_err(fmt, ...)	\
	pr_devel("%s: " fmt, ioctl_name, ##__VA_ARGS__)

static int vmci_host_do_init_context(struct vmci_host_dev *vmci_host_dev,
				     const char *ioctl_name,
				     void __user *uptr)
{
	struct vmci_init_blk init_block;
	const struct cred *cred;
	int retval;

	if (copy_from_user(&init_block, uptr, sizeof(init_block))) {
		vmci_ioctl_err("error reading init block\n");
		return -EFAULT;
	}

	mutex_lock(&vmci_host_dev->lock);

	if (vmci_host_dev->ct_type != VMCIOBJ_NOT_SET) {
		vmci_ioctl_err("received VMCI init on initialized handle\n");
		retval = -EINVAL;
		goto out;
	}

	if (init_block.flags & ~VMCI_PRIVILEGE_FLAG_RESTRICTED) {
		vmci_ioctl_err("unsupported VMCI restriction flag\n");
		retval = -EINVAL;
		goto out;
	}

	cred = get_current_cred();
	vmci_host_dev->context = vmci_ctx_create(init_block.cid,
						 init_block.flags, 0,
						 vmci_host_dev->user_version,
						 cred);
	put_cred(cred);
	if (IS_ERR(vmci_host_dev->context)) {
		retval = PTR_ERR(vmci_host_dev->context);
		vmci_ioctl_err("error initializing context\n");
		goto out;
	}

	/*
	 * Copy cid to userlevel, we do this to allow the VMX
	 * to enforce its policy on cid generation.
	 */
	init_block.cid = vmci_ctx_get_id(vmci_host_dev->context);
	if (copy_to_user(uptr, &init_block, sizeof(init_block))) {
		vmci_ctx_destroy(vmci_host_dev->context);
		vmci_host_dev->context = NULL;
		vmci_ioctl_err("error writing init block\n");
		retval = -EFAULT;
		goto out;
	}

	vmci_host_dev->ct_type = VMCIOBJ_CONTEXT;
	atomic_inc(&vmci_host_active_users);

	retval = 0;

out:
	mutex_unlock(&vmci_host_dev->lock);
	return retval;
}

static int vmci_host_do_send_datagram(struct vmci_host_dev *vmci_host_dev,
				      const char *ioctl_name,
				      void __user *uptr)
{
	struct vmci_datagram_snd_rcv_info send_info;
	struct vmci_datagram *dg = NULL;
	u32 cid;

	if (vmci_host_dev->ct_type != VMCIOBJ_CONTEXT) {
		vmci_ioctl_err("only valid for contexts\n");
		return -EINVAL;
	}

	if (copy_from_user(&send_info, uptr, sizeof(send_info)))
		return -EFAULT;

	if (send_info.len > VMCI_MAX_DG_SIZE) {
		vmci_ioctl_err("datagram is too big (size=%d)\n",
			       send_info.len);
		return -EINVAL;
	}

	if (send_info.len < sizeof(*dg)) {
		vmci_ioctl_err("datagram is too small (size=%d)\n",
			       send_info.len);
		return -EINVAL;
	}

	dg = kmalloc(send_info.len, GFP_KERNEL);
	if (!dg) {
		vmci_ioctl_err(
			"cannot allocate memory to dispatch datagram\n");
		return -ENOMEM;
	}

	if (copy_from_user(dg, (void __user *)(uintptr_t)send_info.addr,
			   send_info.len)) {
		vmci_ioctl_err("error getting datagram\n");
		kfree(dg);
		return -EFAULT;
	}

	pr_devel("Datagram dst (handle=0x%x:0x%x) src (handle=0x%x:0x%x), payload (size=%llu bytes)\n",
		 dg->dst.context, dg->dst.resource,
		 dg->src.context, dg->src.resource,
		 (unsigned long long)dg->payload_size);

	/* Get source context id. */
	cid = vmci_ctx_get_id(vmci_host_dev->context);
	send_info.result = vmci_datagram_dispatch(cid, dg, true);
	kfree(dg);

	return copy_to_user(uptr, &send_info, sizeof(send_info)) ? -EFAULT : 0;
}

static int vmci_host_do_receive_datagram(struct vmci_host_dev *vmci_host_dev,
					 const char *ioctl_name,
					 void __user *uptr)
{
	struct vmci_datagram_snd_rcv_info recv_info;
	struct vmci_datagram *dg = NULL;
	int retval;
	size_t size;

	if (vmci_host_dev->ct_type != VMCIOBJ_CONTEXT) {
		vmci_ioctl_err("only valid for contexts\n");
		return -EINVAL;
	}

	if (copy_from_user(&recv_info, uptr, sizeof(recv_info)))
		return -EFAULT;

	size = recv_info.len;
	recv_info.result = vmci_ctx_dequeue_datagram(vmci_host_dev->context,
						     &size, &dg);

	if (recv_info.result >= VMCI_SUCCESS) {
		void __user *ubuf = (void __user *)(uintptr_t)recv_info.addr;
		retval = copy_to_user(ubuf, dg, VMCI_DG_SIZE(dg));
		kfree(dg);
		if (retval != 0)
			return -EFAULT;
	}

	return copy_to_user(uptr, &recv_info, sizeof(recv_info)) ? -EFAULT : 0;
}

static int vmci_host_do_alloc_queuepair(struct vmci_host_dev *vmci_host_dev,
					const char *ioctl_name,
					void __user *uptr)
{
	struct vmci_handle handle;
	int vmci_status;
	int __user *retptr;
	u32 cid;

	if (vmci_host_dev->ct_type != VMCIOBJ_CONTEXT) {
		vmci_ioctl_err("only valid for contexts\n");
		return -EINVAL;
	}

	cid = vmci_ctx_get_id(vmci_host_dev->context);

	if (vmci_host_dev->user_version < VMCI_VERSION_NOVMVM) {
		struct vmci_qp_alloc_info_vmvm alloc_info;
		struct vmci_qp_alloc_info_vmvm __user *info = uptr;

		if (copy_from_user(&alloc_info, uptr, sizeof(alloc_info)))
			return -EFAULT;

		handle = alloc_info.handle;
		retptr = &info->result;

		vmci_status = vmci_qp_broker_alloc(alloc_info.handle,
						alloc_info.peer,
						alloc_info.flags,
						VMCI_NO_PRIVILEGE_FLAGS,
						alloc_info.produce_size,
						alloc_info.consume_size,
						NULL,
						vmci_host_dev->context);

		if (vmci_status == VMCI_SUCCESS)
			vmci_status = VMCI_SUCCESS_QUEUEPAIR_CREATE;
	} else {
		struct vmci_qp_alloc_info alloc_info;
		struct vmci_qp_alloc_info __user *info = uptr;
		struct vmci_qp_page_store page_store;

		if (copy_from_user(&alloc_info, uptr, sizeof(alloc_info)))
			return -EFAULT;

		handle = alloc_info.handle;
		retptr = &info->result;

		page_store.pages = alloc_info.ppn_va;
		page_store.len = alloc_info.num_ppns;

		vmci_status = vmci_qp_broker_alloc(alloc_info.handle,
						alloc_info.peer,
						alloc_info.flags,
						VMCI_NO_PRIVILEGE_FLAGS,
						alloc_info.produce_size,
						alloc_info.consume_size,
						&page_store,
						vmci_host_dev->context);
	}

	if (put_user(vmci_status, retptr)) {
		if (vmci_status >= VMCI_SUCCESS) {
			vmci_status = vmci_qp_broker_detach(handle,
							vmci_host_dev->context);
		}
		return -EFAULT;
	}

	return 0;
}

static int vmci_host_do_queuepair_setva(struct vmci_host_dev *vmci_host_dev,
					const char *ioctl_name,
					void __user *uptr)
{
	struct vmci_qp_set_va_info set_va_info;
	struct vmci_qp_set_va_info __user *info = uptr;
	s32 result;

	if (vmci_host_dev->ct_type != VMCIOBJ_CONTEXT) {
		vmci_ioctl_err("only valid for contexts\n");
		return -EINVAL;
	}

	if (vmci_host_dev->user_version < VMCI_VERSION_NOVMVM) {
		vmci_ioctl_err("is not allowed\n");
		return -EINVAL;
	}

	if (copy_from_user(&set_va_info, uptr, sizeof(set_va_info)))
		return -EFAULT;

	if (set_va_info.va) {
		/*
		 * VMX is passing down a new VA for the queue
		 * pair mapping.
		 */
		result = vmci_qp_broker_map(set_va_info.handle,
					    vmci_host_dev->context,
					    set_va_info.va);
	} else {
		/*
		 * The queue pair is about to be unmapped by
		 * the VMX.
		 */
		result = vmci_qp_broker_unmap(set_va_info.handle,
					 vmci_host_dev->context, 0);
	}

	return put_user(result, &info->result) ? -EFAULT : 0;
}

static int vmci_host_do_queuepair_setpf(struct vmci_host_dev *vmci_host_dev,
					const char *ioctl_name,
					void __user *uptr)
{
	struct vmci_qp_page_file_info page_file_info;
	struct vmci_qp_page_file_info __user *info = uptr;
	s32 result;

	if (vmci_host_dev->user_version < VMCI_VERSION_HOSTQP ||
	    vmci_host_dev->user_version >= VMCI_VERSION_NOVMVM) {
		vmci_ioctl_err("not supported on this VMX (version=%d)\n",
			       vmci_host_dev->user_version);
		return -EINVAL;
	}

	if (vmci_host_dev->ct_type != VMCIOBJ_CONTEXT) {
		vmci_ioctl_err("only valid for contexts\n");
		return -EINVAL;
	}

	if (copy_from_user(&page_file_info, uptr, sizeof(*info)))
		return -EFAULT;

	/*
	 * Communicate success pre-emptively to the caller.  Note that the
	 * basic premise is that it is incumbent upon the caller not to look at
	 * the info.result field until after the ioctl() returns.  And then,
	 * only if the ioctl() result indicates no error.  We send up the
	 * SUCCESS status before calling SetPageStore() store because failing
	 * to copy up the result code means unwinding the SetPageStore().
	 *
	 * It turns out the logic to unwind a SetPageStore() opens a can of
	 * worms.  For example, if a host had created the queue_pair and a
	 * guest attaches and SetPageStore() is successful but writing success
	 * fails, then ... the host has to be stopped from writing (anymore)
	 * data into the queue_pair.  That means an additional test in the
	 * VMCI_Enqueue() code path.  Ugh.
	 */

	if (put_user(VMCI_SUCCESS, &info->result)) {
		/*
		 * In this case, we can't write a result field of the
		 * caller's info block.  So, we don't even try to
		 * SetPageStore().
		 */
		return -EFAULT;
	}

	result = vmci_qp_broker_set_page_store(page_file_info.handle,
						page_file_info.produce_va,
						page_file_info.consume_va,
						vmci_host_dev->context);
	if (result < VMCI_SUCCESS) {
		if (put_user(result, &info->result)) {
			/*
			 * Note that in this case the SetPageStore()
			 * call failed but we were unable to
			 * communicate that to the caller (because the
			 * copy_to_user() call failed).  So, if we
			 * simply return an error (in this case
			 * -EFAULT) then the caller will know that the
			 *  SetPageStore failed even though we couldn't
			 *  put the result code in the result field and
			 *  indicate exactly why it failed.
			 *
			 * That says nothing about the issue where we
			 * were once able to write to the caller's info
			 * memory and now can't.  Something more
			 * serious is probably going on than the fact
			 * that SetPageStore() didn't work.
			 */
			return -EFAULT;
		}
	}

	return 0;
}

static int vmci_host_do_qp_detach(struct vmci_host_dev *vmci_host_dev,
				  const char *ioctl_name,
				  void __user *uptr)
{
	struct vmci_qp_dtch_info detach_info;
	struct vmci_qp_dtch_info __user *info = uptr;
	s32 result;

	if (vmci_host_dev->ct_type != VMCIOBJ_CONTEXT) {
		vmci_ioctl_err("only valid for contexts\n");
		return -EINVAL;
	}

	if (copy_from_user(&detach_info, uptr, sizeof(detach_info)))
		return -EFAULT;

	result = vmci_qp_broker_detach(detach_info.handle,
				       vmci_host_dev->context);
	if (result == VMCI_SUCCESS &&
	    vmci_host_dev->user_version < VMCI_VERSION_NOVMVM) {
		result = VMCI_SUCCESS_LAST_DETACH;
	}

	return put_user(result, &info->result) ? -EFAULT : 0;
}

static int vmci_host_do_ctx_add_notify(struct vmci_host_dev *vmci_host_dev,
				       const char *ioctl_name,
				       void __user *uptr)
{
	struct vmci_ctx_info ar_info;
	struct vmci_ctx_info __user *info = uptr;
	s32 result;
	u32 cid;

	if (vmci_host_dev->ct_type != VMCIOBJ_CONTEXT) {
		vmci_ioctl_err("only valid for contexts\n");
		return -EINVAL;
	}

	if (copy_from_user(&ar_info, uptr, sizeof(ar_info)))
		return -EFAULT;

	cid = vmci_ctx_get_id(vmci_host_dev->context);
	result = vmci_ctx_add_notification(cid, ar_info.remote_cid);

	return put_user(result, &info->result) ? -EFAULT : 0;
}

static int vmci_host_do_ctx_remove_notify(struct vmci_host_dev *vmci_host_dev,
					  const char *ioctl_name,
					  void __user *uptr)
{
	struct vmci_ctx_info ar_info;
	struct vmci_ctx_info __user *info = uptr;
	u32 cid;
	int result;

	if (vmci_host_dev->ct_type != VMCIOBJ_CONTEXT) {
		vmci_ioctl_err("only valid for contexts\n");
		return -EINVAL;
	}

	if (copy_from_user(&ar_info, uptr, sizeof(ar_info)))
		return -EFAULT;

	cid = vmci_ctx_get_id(vmci_host_dev->context);
	result = vmci_ctx_remove_notification(cid,
					      ar_info.remote_cid);

	return put_user(result, &info->result) ? -EFAULT : 0;
}

static int vmci_host_do_ctx_get_cpt_state(struct vmci_host_dev *vmci_host_dev,
					  const char *ioctl_name,
					  void __user *uptr)
{
	struct vmci_ctx_chkpt_buf_info get_info;
	u32 cid;
	void *cpt_buf;
	int retval;

	if (vmci_host_dev->ct_type != VMCIOBJ_CONTEXT) {
		vmci_ioctl_err("only valid for contexts\n");
		return -EINVAL;
	}

	if (copy_from_user(&get_info, uptr, sizeof(get_info)))
		return -EFAULT;

	cid = vmci_ctx_get_id(vmci_host_dev->context);
	get_info.result = vmci_ctx_get_chkpt_state(cid, get_info.cpt_type,
						&get_info.buf_size, &cpt_buf);
	if (get_info.result == VMCI_SUCCESS && get_info.buf_size) {
		void __user *ubuf = (void __user *)(uintptr_t)get_info.cpt_buf;
		retval = copy_to_user(ubuf, cpt_buf, get_info.buf_size);
		kfree(cpt_buf);

		if (retval)
			return -EFAULT;
	}

	return copy_to_user(uptr, &get_info, sizeof(get_info)) ? -EFAULT : 0;
}

static int vmci_host_do_ctx_set_cpt_state(struct vmci_host_dev *vmci_host_dev,
					  const char *ioctl_name,
					  void __user *uptr)
{
	struct vmci_ctx_chkpt_buf_info set_info;
	u32 cid;
	void *cpt_buf;
	int retval;

	if (vmci_host_dev->ct_type != VMCIOBJ_CONTEXT) {
		vmci_ioctl_err("only valid for contexts\n");
		return -EINVAL;
	}

	if (copy_from_user(&set_info, uptr, sizeof(set_info)))
		return -EFAULT;

	cpt_buf = kmalloc(set_info.buf_size, GFP_KERNEL);
	if (!cpt_buf) {
		vmci_ioctl_err(
			"cannot allocate memory to set cpt state (type=%d)\n",
			set_info.cpt_type);
		return -ENOMEM;
	}

	if (copy_from_user(cpt_buf, (void __user *)(uintptr_t)set_info.cpt_buf,
			   set_info.buf_size)) {
		retval = -EFAULT;
		goto out;
	}

	cid = vmci_ctx_get_id(vmci_host_dev->context);
	set_info.result = vmci_ctx_set_chkpt_state(cid, set_info.cpt_type,
						   set_info.buf_size, cpt_buf);

	retval = copy_to_user(uptr, &set_info, sizeof(set_info)) ? -EFAULT : 0;

out:
	kfree(cpt_buf);
	return retval;
}

static int vmci_host_do_get_context_id(struct vmci_host_dev *vmci_host_dev,
				       const char *ioctl_name,
				       void __user *uptr)
{
	u32 __user *u32ptr = uptr;

	return put_user(VMCI_HOST_CONTEXT_ID, u32ptr) ? -EFAULT : 0;
}

static int vmci_host_do_set_notify(struct vmci_host_dev *vmci_host_dev,
				   const char *ioctl_name,
				   void __user *uptr)
{
	struct vmci_set_notify_info notify_info;

	if (vmci_host_dev->ct_type != VMCIOBJ_CONTEXT) {
		vmci_ioctl_err("only valid for contexts\n");
		return -EINVAL;
	}

	if (copy_from_user(&notify_info, uptr, sizeof(notify_info)))
		return -EFAULT;

	if (notify_info.notify_uva) {
		notify_info.result =
			vmci_host_setup_notify(vmci_host_dev->context,
					       notify_info.notify_uva);
	} else {
		vmci_ctx_unset_notify(vmci_host_dev->context);
		notify_info.result = VMCI_SUCCESS;
	}

	return copy_to_user(uptr, &notify_info, sizeof(notify_info)) ?
		-EFAULT : 0;
}

static int vmci_host_do_notify_resource(struct vmci_host_dev *vmci_host_dev,
					const char *ioctl_name,
					void __user *uptr)
{
	struct vmci_dbell_notify_resource_info info;
	u32 cid;

	if (vmci_host_dev->user_version < VMCI_VERSION_NOTIFY) {
		vmci_ioctl_err("invalid for current VMX versions\n");
		return -EINVAL;
	}

	if (vmci_host_dev->ct_type != VMCIOBJ_CONTEXT) {
		vmci_ioctl_err("only valid for contexts\n");
		return -EINVAL;
	}

	if (copy_from_user(&info, uptr, sizeof(info)))
		return -EFAULT;

	cid = vmci_ctx_get_id(vmci_host_dev->context);

	switch (info.action) {
	case VMCI_NOTIFY_RESOURCE_ACTION_NOTIFY:
		if (info.resource == VMCI_NOTIFY_RESOURCE_DOOR_BELL) {
			u32 flags = VMCI_NO_PRIVILEGE_FLAGS;
			info.result = vmci_ctx_notify_dbell(cid, info.handle,
							    flags);
		} else {
			info.result = VMCI_ERROR_UNAVAILABLE;
		}
		break;

	case VMCI_NOTIFY_RESOURCE_ACTION_CREATE:
		info.result = vmci_ctx_dbell_create(cid, info.handle);
		break;

	case VMCI_NOTIFY_RESOURCE_ACTION_DESTROY:
		info.result = vmci_ctx_dbell_destroy(cid, info.handle);
		break;

	default:
		vmci_ioctl_err("got unknown action (action=%d)\n",
			       info.action);
		info.result = VMCI_ERROR_INVALID_ARGS;
	}

	return copy_to_user(uptr, &info, sizeof(info)) ? -EFAULT : 0;
}

static int vmci_host_do_recv_notifications(struct vmci_host_dev *vmci_host_dev,
					   const char *ioctl_name,
					   void __user *uptr)
{
	struct vmci_ctx_notify_recv_info info;
	struct vmci_handle_arr *db_handle_array;
	struct vmci_handle_arr *qp_handle_array;
	void __user *ubuf;
	u32 cid;
	int retval = 0;

	if (vmci_host_dev->ct_type != VMCIOBJ_CONTEXT) {
		vmci_ioctl_err("only valid for contexts\n");
		return -EINVAL;
	}

	if (vmci_host_dev->user_version < VMCI_VERSION_NOTIFY) {
		vmci_ioctl_err("not supported for the current vmx version\n");
		return -EINVAL;
	}

	if (copy_from_user(&info, uptr, sizeof(info)))
		return -EFAULT;

	if ((info.db_handle_buf_size && !info.db_handle_buf_uva) ||
	    (info.qp_handle_buf_size && !info.qp_handle_buf_uva)) {
		return -EINVAL;
	}

	cid = vmci_ctx_get_id(vmci_host_dev->context);

	info.result = vmci_ctx_rcv_notifications_get(cid,
				&db_handle_array, &qp_handle_array);
	if (info.result != VMCI_SUCCESS)
		return copy_to_user(uptr, &info, sizeof(info)) ? -EFAULT : 0;

	ubuf = (void __user *)(uintptr_t)info.db_handle_buf_uva;
	info.result = drv_cp_harray_to_user(ubuf, &info.db_handle_buf_size,
					    db_handle_array, &retval);
	if (info.result == VMCI_SUCCESS && !retval) {
		ubuf = (void __user *)(uintptr_t)info.qp_handle_buf_uva;
		info.result = drv_cp_harray_to_user(ubuf,
						    &info.qp_handle_buf_size,
						    qp_handle_array, &retval);
	}

	if (!retval && copy_to_user(uptr, &info, sizeof(info)))
		retval = -EFAULT;

	vmci_ctx_rcv_notifications_release(cid,
				db_handle_array, qp_handle_array,
				info.result == VMCI_SUCCESS && !retval);

	return retval;
}

static long vmci_host_unlocked_ioctl(struct file *filp,
				     unsigned int iocmd, unsigned long ioarg)
{
#define VMCI_DO_IOCTL(ioctl_name, ioctl_fn) do {			\
		char *name = __stringify(IOCTL_VMCI_ ## ioctl_name);	\
		return vmci_host_do_ ## ioctl_fn(			\
			vmci_host_dev, name, uptr);			\
	} while (0)

	struct vmci_host_dev *vmci_host_dev = filp->private_data;
	void __user *uptr = (void __user *)ioarg;

	switch (iocmd) {
	case IOCTL_VMCI_INIT_CONTEXT:
		VMCI_DO_IOCTL(INIT_CONTEXT, init_context);
	case IOCTL_VMCI_DATAGRAM_SEND:
		VMCI_DO_IOCTL(DATAGRAM_SEND, send_datagram);
	case IOCTL_VMCI_DATAGRAM_RECEIVE:
		VMCI_DO_IOCTL(DATAGRAM_RECEIVE, receive_datagram);
	case IOCTL_VMCI_QUEUEPAIR_ALLOC:
		VMCI_DO_IOCTL(QUEUEPAIR_ALLOC, alloc_queuepair);
	case IOCTL_VMCI_QUEUEPAIR_SETVA:
		VMCI_DO_IOCTL(QUEUEPAIR_SETVA, queuepair_setva);
	case IOCTL_VMCI_QUEUEPAIR_SETPAGEFILE:
		VMCI_DO_IOCTL(QUEUEPAIR_SETPAGEFILE, queuepair_setpf);
	case IOCTL_VMCI_QUEUEPAIR_DETACH:
		VMCI_DO_IOCTL(QUEUEPAIR_DETACH, qp_detach);
	case IOCTL_VMCI_CTX_ADD_NOTIFICATION:
		VMCI_DO_IOCTL(CTX_ADD_NOTIFICATION, ctx_add_notify);
	case IOCTL_VMCI_CTX_REMOVE_NOTIFICATION:
		VMCI_DO_IOCTL(CTX_REMOVE_NOTIFICATION, ctx_remove_notify);
	case IOCTL_VMCI_CTX_GET_CPT_STATE:
		VMCI_DO_IOCTL(CTX_GET_CPT_STATE, ctx_get_cpt_state);
	case IOCTL_VMCI_CTX_SET_CPT_STATE:
		VMCI_DO_IOCTL(CTX_SET_CPT_STATE, ctx_set_cpt_state);
	case IOCTL_VMCI_GET_CONTEXT_ID:
		VMCI_DO_IOCTL(GET_CONTEXT_ID, get_context_id);
	case IOCTL_VMCI_SET_NOTIFY:
		VMCI_DO_IOCTL(SET_NOTIFY, set_notify);
	case IOCTL_VMCI_NOTIFY_RESOURCE:
		VMCI_DO_IOCTL(NOTIFY_RESOURCE, notify_resource);
	case IOCTL_VMCI_NOTIFICATIONS_RECEIVE:
		VMCI_DO_IOCTL(NOTIFICATIONS_RECEIVE, recv_notifications);

	case IOCTL_VMCI_VERSION:
	case IOCTL_VMCI_VERSION2:
		return vmci_host_get_version(vmci_host_dev, iocmd, uptr);

	default:
		pr_devel("%s: Unknown ioctl (iocmd=%d)\n", __func__, iocmd);
		return -EINVAL;
	}

#undef VMCI_DO_IOCTL
}

static const struct file_operations vmuser_fops = {
	.owner		= THIS_MODULE,
	.open		= vmci_host_open,
	.release	= vmci_host_close,
	.poll		= vmci_host_poll,
	.unlocked_ioctl	= vmci_host_unlocked_ioctl,
	.compat_ioctl	= vmci_host_unlocked_ioctl,
};

static struct miscdevice vmci_host_miscdev = {
	 .name = "vmci",
	 .minor = MISC_DYNAMIC_MINOR,
	 .fops = &vmuser_fops,
};

int __init vmci_host_init(void)
{
	int error;

	host_context = vmci_ctx_create(VMCI_HOST_CONTEXT_ID,
					VMCI_DEFAULT_PROC_PRIVILEGE_FLAGS,
					-1, VMCI_VERSION, NULL);
	if (IS_ERR(host_context)) {
		error = PTR_ERR(host_context);
		pr_warn("Failed to initialize VMCIContext (error%d)\n",
			error);
		return error;
	}

	error = misc_register(&vmci_host_miscdev);
	if (error) {
		pr_warn("Module registration error (name=%s, major=%d, minor=%d, err=%d)\n",
			vmci_host_miscdev.name,
			MISC_MAJOR, vmci_host_miscdev.minor,
			error);
		pr_warn("Unable to initialize host personality\n");
		vmci_ctx_destroy(host_context);
		return error;
	}

	pr_info("VMCI host device registered (name=%s, major=%d, minor=%d)\n",
		vmci_host_miscdev.name, MISC_MAJOR, vmci_host_miscdev.minor);

	vmci_host_device_initialized = true;
	return 0;
}

void __exit vmci_host_exit(void)
{
	int error;

	vmci_host_device_initialized = false;

	error = misc_deregister(&vmci_host_miscdev);
	if (error)
		pr_warn("Error unregistering character device: %d\n", error);

	vmci_ctx_destroy(host_context);
	vmci_qp_broker_exit();

	pr_debug("VMCI host driver module unloaded\n");
}
