// SPDX-License-Identifier: GPL-2.0-only
/*
 * VMware VMCI Driver
 *
 * Copyright (C) 2012 VMware, Inc. All rights reserved.
 */

#include <linux/vmw_vmci_defs.h>
#include <linux/vmw_vmci_api.h>
#include <linux/moduleparam.h>
#include <linux/interrupt.h>
#include <linux/highmem.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/module.h>
#include <linux/processor.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/pci.h>
#include <linux/smp.h>
#include <linux/io.h>
#include <linux/vmalloc.h>

#include "vmci_datagram.h"
#include "vmci_doorbell.h"
#include "vmci_context.h"
#include "vmci_driver.h"
#include "vmci_event.h"

#define PCI_DEVICE_ID_VMWARE_VMCI	0x0740

#define VMCI_UTIL_NUM_RESOURCES 1

/*
 * Datagram buffers for DMA send/receive must accommodate at least
 * a maximum sized datagram and the header.
 */
#define VMCI_DMA_DG_BUFFER_SIZE (VMCI_MAX_DG_SIZE + PAGE_SIZE)

static bool vmci_disable_msi;
module_param_named(disable_msi, vmci_disable_msi, bool, 0);
MODULE_PARM_DESC(disable_msi, "Disable MSI use in driver - (default=0)");

static bool vmci_disable_msix;
module_param_named(disable_msix, vmci_disable_msix, bool, 0);
MODULE_PARM_DESC(disable_msix, "Disable MSI-X use in driver - (default=0)");

static u32 ctx_update_sub_id = VMCI_INVALID_ID;
static u32 vm_context_id = VMCI_INVALID_ID;

struct vmci_guest_device {
	struct device *dev;	/* PCI device we are attached to */
	void __iomem *iobase;
	void __iomem *mmio_base;

	bool exclusive_vectors;

	struct wait_queue_head inout_wq;

	void *data_buffer;
	dma_addr_t data_buffer_base;
	void *tx_buffer;
	dma_addr_t tx_buffer_base;
	void *notification_bitmap;
	dma_addr_t notification_base;
};

static bool use_ppn64;

bool vmci_use_ppn64(void)
{
	return use_ppn64;
}

/* vmci_dev singleton device and supporting data*/
struct pci_dev *vmci_pdev;
static struct vmci_guest_device *vmci_dev_g;
static DEFINE_SPINLOCK(vmci_dev_spinlock);

static atomic_t vmci_num_guest_devices = ATOMIC_INIT(0);

bool vmci_guest_code_active(void)
{
	return atomic_read(&vmci_num_guest_devices) != 0;
}

u32 vmci_get_vm_context_id(void)
{
	if (vm_context_id == VMCI_INVALID_ID) {
		struct vmci_datagram get_cid_msg;
		get_cid_msg.dst =
		    vmci_make_handle(VMCI_HYPERVISOR_CONTEXT_ID,
				     VMCI_GET_CONTEXT_ID);
		get_cid_msg.src = VMCI_ANON_SRC_HANDLE;
		get_cid_msg.payload_size = 0;
		vm_context_id = vmci_send_datagram(&get_cid_msg);
	}
	return vm_context_id;
}

static unsigned int vmci_read_reg(struct vmci_guest_device *dev, u32 reg)
{
	if (dev->mmio_base != NULL)
		return readl(dev->mmio_base + reg);
	return ioread32(dev->iobase + reg);
}

static void vmci_write_reg(struct vmci_guest_device *dev, u32 val, u32 reg)
{
	if (dev->mmio_base != NULL)
		writel(val, dev->mmio_base + reg);
	else
		iowrite32(val, dev->iobase + reg);
}

static void vmci_read_data(struct vmci_guest_device *vmci_dev,
			   void *dest, size_t size)
{
	if (vmci_dev->mmio_base == NULL)
		ioread8_rep(vmci_dev->iobase + VMCI_DATA_IN_ADDR,
			    dest, size);
	else {
		/*
		 * For DMA datagrams, the data_buffer will contain the header on the
		 * first page, followed by the incoming datagram(s) on the following
		 * pages. The header uses an S/G element immediately following the
		 * header on the first page to point to the data area.
		 */
		struct vmci_data_in_out_header *buffer_header = vmci_dev->data_buffer;
		struct vmci_sg_elem *sg_array = (struct vmci_sg_elem *)(buffer_header + 1);
		size_t buffer_offset = dest - vmci_dev->data_buffer;

		buffer_header->opcode = 1;
		buffer_header->size = 1;
		buffer_header->busy = 0;
		sg_array[0].addr = vmci_dev->data_buffer_base + buffer_offset;
		sg_array[0].size = size;

		vmci_write_reg(vmci_dev, lower_32_bits(vmci_dev->data_buffer_base),
			       VMCI_DATA_IN_LOW_ADDR);

		wait_event(vmci_dev->inout_wq, buffer_header->busy == 1);
	}
}

static int vmci_write_data(struct vmci_guest_device *dev,
			   struct vmci_datagram *dg)
{
	int result;

	if (dev->mmio_base != NULL) {
		struct vmci_data_in_out_header *buffer_header = dev->tx_buffer;
		u8 *dg_out_buffer = (u8 *)(buffer_header + 1);

		if (VMCI_DG_SIZE(dg) > VMCI_MAX_DG_SIZE)
			return VMCI_ERROR_INVALID_ARGS;

		/*
		 * Initialize send buffer with outgoing datagram
		 * and set up header for inline data. Device will
		 * not access buffer asynchronously - only after
		 * the write to VMCI_DATA_OUT_LOW_ADDR.
		 */
		memcpy(dg_out_buffer, dg, VMCI_DG_SIZE(dg));
		buffer_header->opcode = 0;
		buffer_header->size = VMCI_DG_SIZE(dg);
		buffer_header->busy = 1;

		vmci_write_reg(dev, lower_32_bits(dev->tx_buffer_base),
			       VMCI_DATA_OUT_LOW_ADDR);

		/* Caller holds a spinlock, so cannot block. */
		spin_until_cond(buffer_header->busy == 0);

		result = vmci_read_reg(vmci_dev_g, VMCI_RESULT_LOW_ADDR);
		if (result == VMCI_SUCCESS)
			result = (int)buffer_header->result;
	} else {
		iowrite8_rep(dev->iobase + VMCI_DATA_OUT_ADDR,
			     dg, VMCI_DG_SIZE(dg));
		result = vmci_read_reg(vmci_dev_g, VMCI_RESULT_LOW_ADDR);
	}

	return result;
}

/*
 * VM to hypervisor call mechanism. We use the standard VMware naming
 * convention since shared code is calling this function as well.
 */
int vmci_send_datagram(struct vmci_datagram *dg)
{
	unsigned long flags;
	int result;

	/* Check args. */
	if (dg == NULL)
		return VMCI_ERROR_INVALID_ARGS;

	/*
	 * Need to acquire spinlock on the device because the datagram
	 * data may be spread over multiple pages and the monitor may
	 * interleave device user rpc calls from multiple
	 * VCPUs. Acquiring the spinlock precludes that
	 * possibility. Disabling interrupts to avoid incoming
	 * datagrams during a "rep out" and possibly landing up in
	 * this function.
	 */
	spin_lock_irqsave(&vmci_dev_spinlock, flags);

	if (vmci_dev_g) {
		vmci_write_data(vmci_dev_g, dg);
		result = vmci_read_reg(vmci_dev_g, VMCI_RESULT_LOW_ADDR);
	} else {
		result = VMCI_ERROR_UNAVAILABLE;
	}

	spin_unlock_irqrestore(&vmci_dev_spinlock, flags);

	return result;
}
EXPORT_SYMBOL_GPL(vmci_send_datagram);

/*
 * Gets called with the new context id if updated or resumed.
 * Context id.
 */
static void vmci_guest_cid_update(u32 sub_id,
				  const struct vmci_event_data *event_data,
				  void *client_data)
{
	const struct vmci_event_payld_ctx *ev_payload =
				vmci_event_data_const_payload(event_data);

	if (sub_id != ctx_update_sub_id) {
		pr_devel("Invalid subscriber (ID=0x%x)\n", sub_id);
		return;
	}

	if (!event_data || ev_payload->context_id == VMCI_INVALID_ID) {
		pr_devel("Invalid event data\n");
		return;
	}

	pr_devel("Updating context from (ID=0x%x) to (ID=0x%x) on event (type=%d)\n",
		 vm_context_id, ev_payload->context_id, event_data->event);

	vm_context_id = ev_payload->context_id;
}

/*
 * Verify that the host supports the hypercalls we need. If it does not,
 * try to find fallback hypercalls and use those instead.  Returns 0 if
 * required hypercalls (or fallback hypercalls) are supported by the host,
 * an error code otherwise.
 */
static int vmci_check_host_caps(struct pci_dev *pdev)
{
	bool result;
	struct vmci_resource_query_msg *msg;
	u32 msg_size = sizeof(struct vmci_resource_query_hdr) +
				VMCI_UTIL_NUM_RESOURCES * sizeof(u32);
	struct vmci_datagram *check_msg;

	check_msg = kzalloc(msg_size, GFP_KERNEL);
	if (!check_msg) {
		dev_err(&pdev->dev, "%s: Insufficient memory\n", __func__);
		return -ENOMEM;
	}

	check_msg->dst = vmci_make_handle(VMCI_HYPERVISOR_CONTEXT_ID,
					  VMCI_RESOURCES_QUERY);
	check_msg->src = VMCI_ANON_SRC_HANDLE;
	check_msg->payload_size = msg_size - VMCI_DG_HEADERSIZE;
	msg = (struct vmci_resource_query_msg *)VMCI_DG_PAYLOAD(check_msg);

	msg->num_resources = VMCI_UTIL_NUM_RESOURCES;
	msg->resources[0] = VMCI_GET_CONTEXT_ID;

	/* Checks that hyper calls are supported */
	result = vmci_send_datagram(check_msg) == 0x01;
	kfree(check_msg);

	dev_dbg(&pdev->dev, "%s: Host capability check: %s\n",
		__func__, result ? "PASSED" : "FAILED");

	/* We need the vector. There are no fallbacks. */
	return result ? 0 : -ENXIO;
}

/*
 * Reads datagrams from the device and dispatches them. For IO port
 * based access to the device, we always start reading datagrams into
 * only the first page of the datagram buffer. If the datagrams don't
 * fit into one page, we use the maximum datagram buffer size for the
 * remainder of the invocation. This is a simple heuristic for not
 * penalizing small datagrams. For DMA-based datagrams, we always
 * use the maximum datagram buffer size, since there is no performance
 * penalty for doing so.
 *
 * This function assumes that it has exclusive access to the data
 * in register(s) for the duration of the call.
 */
static void vmci_dispatch_dgs(struct vmci_guest_device *vmci_dev)
{
	u8 *dg_in_buffer = vmci_dev->data_buffer;
	struct vmci_datagram *dg;
	size_t dg_in_buffer_size = VMCI_MAX_DG_SIZE;
	size_t current_dg_in_buffer_size;
	size_t remaining_bytes;
	bool is_io_port = vmci_dev->mmio_base == NULL;

	BUILD_BUG_ON(VMCI_MAX_DG_SIZE < PAGE_SIZE);

	if (!is_io_port) {
		/* For mmio, the first page is used for the header. */
		dg_in_buffer += PAGE_SIZE;

		/*
		 * For DMA-based datagram operations, there is no performance
		 * penalty for reading the maximum buffer size.
		 */
		current_dg_in_buffer_size = VMCI_MAX_DG_SIZE;
	} else {
		current_dg_in_buffer_size = PAGE_SIZE;
	}
	vmci_read_data(vmci_dev, dg_in_buffer, current_dg_in_buffer_size);
	dg = (struct vmci_datagram *)dg_in_buffer;
	remaining_bytes = current_dg_in_buffer_size;

	/*
	 * Read through the buffer until an invalid datagram header is
	 * encountered. The exit condition for datagrams read through
	 * VMCI_DATA_IN_ADDR is a bit more complicated, since a datagram
	 * can start on any page boundary in the buffer.
	 */
	while (dg->dst.resource != VMCI_INVALID_ID ||
	       (is_io_port && remaining_bytes > PAGE_SIZE)) {
		unsigned dg_in_size;

		/*
		 * If using VMCI_DATA_IN_ADDR, skip to the next page
		 * as a datagram can start on any page boundary.
		 */
		if (dg->dst.resource == VMCI_INVALID_ID) {
			dg = (struct vmci_datagram *)roundup(
				(uintptr_t)dg + 1, PAGE_SIZE);
			remaining_bytes =
				(size_t)(dg_in_buffer +
					 current_dg_in_buffer_size -
					 (u8 *)dg);
			continue;
		}

		dg_in_size = VMCI_DG_SIZE_ALIGNED(dg);

		if (dg_in_size <= dg_in_buffer_size) {
			int result;

			/*
			 * If the remaining bytes in the datagram
			 * buffer doesn't contain the complete
			 * datagram, we first make sure we have enough
			 * room for it and then we read the reminder
			 * of the datagram and possibly any following
			 * datagrams.
			 */
			if (dg_in_size > remaining_bytes) {
				if (remaining_bytes !=
				    current_dg_in_buffer_size) {

					/*
					 * We move the partial
					 * datagram to the front and
					 * read the reminder of the
					 * datagram and possibly
					 * following calls into the
					 * following bytes.
					 */
					memmove(dg_in_buffer, dg_in_buffer +
						current_dg_in_buffer_size -
						remaining_bytes,
						remaining_bytes);
					dg = (struct vmci_datagram *)
					    dg_in_buffer;
				}

				if (current_dg_in_buffer_size !=
				    dg_in_buffer_size)
					current_dg_in_buffer_size =
					    dg_in_buffer_size;

				vmci_read_data(vmci_dev,
					       dg_in_buffer +
						remaining_bytes,
					       current_dg_in_buffer_size -
						remaining_bytes);
			}

			/*
			 * We special case event datagrams from the
			 * hypervisor.
			 */
			if (dg->src.context == VMCI_HYPERVISOR_CONTEXT_ID &&
			    dg->dst.resource == VMCI_EVENT_HANDLER) {
				result = vmci_event_dispatch(dg);
			} else {
				result = vmci_datagram_invoke_guest_handler(dg);
			}
			if (result < VMCI_SUCCESS)
				dev_dbg(vmci_dev->dev,
					"Datagram with resource (ID=0x%x) failed (err=%d)\n",
					 dg->dst.resource, result);

			/* On to the next datagram. */
			dg = (struct vmci_datagram *)((u8 *)dg +
						      dg_in_size);
		} else {
			size_t bytes_to_skip;

			/*
			 * Datagram doesn't fit in datagram buffer of maximal
			 * size. We drop it.
			 */
			dev_dbg(vmci_dev->dev,
				"Failed to receive datagram (size=%u bytes)\n",
				 dg_in_size);

			bytes_to_skip = dg_in_size - remaining_bytes;
			if (current_dg_in_buffer_size != dg_in_buffer_size)
				current_dg_in_buffer_size = dg_in_buffer_size;

			for (;;) {
				vmci_read_data(vmci_dev, dg_in_buffer,
					       current_dg_in_buffer_size);
				if (bytes_to_skip <= current_dg_in_buffer_size)
					break;

				bytes_to_skip -= current_dg_in_buffer_size;
			}
			dg = (struct vmci_datagram *)(dg_in_buffer +
						      bytes_to_skip);
		}

		remaining_bytes =
		    (size_t) (dg_in_buffer + current_dg_in_buffer_size -
			      (u8 *)dg);

		if (remaining_bytes < VMCI_DG_HEADERSIZE) {
			/* Get the next batch of datagrams. */

			vmci_read_data(vmci_dev, dg_in_buffer,
				    current_dg_in_buffer_size);
			dg = (struct vmci_datagram *)dg_in_buffer;
			remaining_bytes = current_dg_in_buffer_size;
		}
	}
}

/*
 * Scans the notification bitmap for raised flags, clears them
 * and handles the notifications.
 */
static void vmci_process_bitmap(struct vmci_guest_device *dev)
{
	if (!dev->notification_bitmap) {
		dev_dbg(dev->dev, "No bitmap present in %s\n", __func__);
		return;
	}

	vmci_dbell_scan_notification_entries(dev->notification_bitmap);
}

/*
 * Interrupt handler for legacy or MSI interrupt, or for first MSI-X
 * interrupt (vector VMCI_INTR_DATAGRAM).
 */
static irqreturn_t vmci_interrupt(int irq, void *_dev)
{
	struct vmci_guest_device *dev = _dev;

	/*
	 * If we are using MSI-X with exclusive vectors then we simply call
	 * vmci_dispatch_dgs(), since we know the interrupt was meant for us.
	 * Otherwise we must read the ICR to determine what to do.
	 */

	if (dev->exclusive_vectors) {
		vmci_dispatch_dgs(dev);
	} else {
		unsigned int icr;

		/* Acknowledge interrupt and determine what needs doing. */
		icr = vmci_read_reg(dev, VMCI_ICR_ADDR);
		if (icr == 0 || icr == ~0)
			return IRQ_NONE;

		if (icr & VMCI_ICR_DATAGRAM) {
			vmci_dispatch_dgs(dev);
			icr &= ~VMCI_ICR_DATAGRAM;
		}

		if (icr & VMCI_ICR_NOTIFICATION) {
			vmci_process_bitmap(dev);
			icr &= ~VMCI_ICR_NOTIFICATION;
		}


		if (icr & VMCI_ICR_DMA_DATAGRAM) {
			wake_up_all(&dev->inout_wq);
			icr &= ~VMCI_ICR_DMA_DATAGRAM;
		}

		if (icr != 0)
			dev_warn(dev->dev,
				 "Ignoring unknown interrupt cause (%d)\n",
				 icr);
	}

	return IRQ_HANDLED;
}

/*
 * Interrupt handler for MSI-X interrupt vector VMCI_INTR_NOTIFICATION,
 * which is for the notification bitmap.  Will only get called if we are
 * using MSI-X with exclusive vectors.
 */
static irqreturn_t vmci_interrupt_bm(int irq, void *_dev)
{
	struct vmci_guest_device *dev = _dev;

	/* For MSI-X we can just assume it was meant for us. */
	vmci_process_bitmap(dev);

	return IRQ_HANDLED;
}

/*
 * Interrupt handler for MSI-X interrupt vector VMCI_INTR_DMA_DATAGRAM,
 * which is for the completion of a DMA datagram send or receive operation.
 * Will only get called if we are using MSI-X with exclusive vectors.
 */
static irqreturn_t vmci_interrupt_dma_datagram(int irq, void *_dev)
{
	struct vmci_guest_device *dev = _dev;

	wake_up_all(&dev->inout_wq);

	return IRQ_HANDLED;
}

static void vmci_free_dg_buffers(struct vmci_guest_device *vmci_dev)
{
	if (vmci_dev->mmio_base != NULL) {
		if (vmci_dev->tx_buffer != NULL)
			dma_free_coherent(vmci_dev->dev,
					  VMCI_DMA_DG_BUFFER_SIZE,
					  vmci_dev->tx_buffer,
					  vmci_dev->tx_buffer_base);
		if (vmci_dev->data_buffer != NULL)
			dma_free_coherent(vmci_dev->dev,
					  VMCI_DMA_DG_BUFFER_SIZE,
					  vmci_dev->data_buffer,
					  vmci_dev->data_buffer_base);
	} else {
		vfree(vmci_dev->data_buffer);
	}
}

/*
 * Most of the initialization at module load time is done here.
 */
static int vmci_guest_probe_device(struct pci_dev *pdev,
				   const struct pci_device_id *id)
{
	struct vmci_guest_device *vmci_dev;
	void __iomem *iobase = NULL;
	void __iomem *mmio_base = NULL;
	unsigned int num_irq_vectors;
	unsigned int capabilities;
	unsigned int caps_in_use;
	unsigned long cmd;
	int vmci_err;
	int error;

	dev_dbg(&pdev->dev, "Probing for vmci/PCI guest device\n");

	error = pcim_enable_device(pdev);
	if (error) {
		dev_err(&pdev->dev,
			"Failed to enable VMCI device: %d\n", error);
		return error;
	}

	/*
	 * The VMCI device with mmio access to registers requests 256KB
	 * for BAR1. If present, driver will use new VMCI device
	 * functionality for register access and datagram send/recv.
	 */

	if (pci_resource_len(pdev, 1) == VMCI_WITH_MMIO_ACCESS_BAR_SIZE) {
		dev_info(&pdev->dev, "MMIO register access is available\n");
		mmio_base = pci_iomap_range(pdev, 1, VMCI_MMIO_ACCESS_OFFSET,
					    VMCI_MMIO_ACCESS_SIZE);
		/* If the map fails, we fall back to IOIO access. */
		if (!mmio_base)
			dev_warn(&pdev->dev, "Failed to map MMIO register access\n");
	}

	if (!mmio_base) {
		if (IS_ENABLED(CONFIG_ARM64)) {
			dev_err(&pdev->dev, "MMIO base is invalid\n");
			return -ENXIO;
		}
		error = pcim_iomap_regions(pdev, BIT(0), KBUILD_MODNAME);
		if (error) {
			dev_err(&pdev->dev, "Failed to reserve/map IO regions\n");
			return error;
		}
		iobase = pcim_iomap_table(pdev)[0];
	}

	vmci_dev = devm_kzalloc(&pdev->dev, sizeof(*vmci_dev), GFP_KERNEL);
	if (!vmci_dev) {
		dev_err(&pdev->dev,
			"Can't allocate memory for VMCI device\n");
		return -ENOMEM;
	}

	vmci_dev->dev = &pdev->dev;
	vmci_dev->exclusive_vectors = false;
	vmci_dev->iobase = iobase;
	vmci_dev->mmio_base = mmio_base;

	init_waitqueue_head(&vmci_dev->inout_wq);

	if (mmio_base != NULL) {
		vmci_dev->tx_buffer = dma_alloc_coherent(&pdev->dev, VMCI_DMA_DG_BUFFER_SIZE,
							 &vmci_dev->tx_buffer_base,
							 GFP_KERNEL);
		if (!vmci_dev->tx_buffer) {
			dev_err(&pdev->dev,
				"Can't allocate memory for datagram tx buffer\n");
			return -ENOMEM;
		}

		vmci_dev->data_buffer = dma_alloc_coherent(&pdev->dev, VMCI_DMA_DG_BUFFER_SIZE,
							   &vmci_dev->data_buffer_base,
							   GFP_KERNEL);
	} else {
		vmci_dev->data_buffer = vmalloc(VMCI_MAX_DG_SIZE);
	}
	if (!vmci_dev->data_buffer) {
		dev_err(&pdev->dev,
			"Can't allocate memory for datagram buffer\n");
		error = -ENOMEM;
		goto err_free_data_buffers;
	}

	pci_set_master(pdev);	/* To enable queue_pair functionality. */

	/*
	 * Verify that the VMCI Device supports the capabilities that
	 * we need. If the device is missing capabilities that we would
	 * like to use, check for fallback capabilities and use those
	 * instead (so we can run a new VM on old hosts). Fail the load if
	 * a required capability is missing and there is no fallback.
	 *
	 * Right now, we need datagrams. There are no fallbacks.
	 */
	capabilities = vmci_read_reg(vmci_dev, VMCI_CAPS_ADDR);
	if (!(capabilities & VMCI_CAPS_DATAGRAM)) {
		dev_err(&pdev->dev, "Device does not support datagrams\n");
		error = -ENXIO;
		goto err_free_data_buffers;
	}
	caps_in_use = VMCI_CAPS_DATAGRAM;

	/*
	 * Use 64-bit PPNs if the device supports.
	 *
	 * There is no check for the return value of dma_set_mask_and_coherent
	 * since this driver can handle the default mask values if
	 * dma_set_mask_and_coherent fails.
	 */
	if (capabilities & VMCI_CAPS_PPN64) {
		dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
		use_ppn64 = true;
		caps_in_use |= VMCI_CAPS_PPN64;
	} else {
		dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(44));
		use_ppn64 = false;
	}

	/*
	 * If the hardware supports notifications, we will use that as
	 * well.
	 */
	if (capabilities & VMCI_CAPS_NOTIFICATIONS) {
		vmci_dev->notification_bitmap = dma_alloc_coherent(
			&pdev->dev, PAGE_SIZE, &vmci_dev->notification_base,
			GFP_KERNEL);
		if (!vmci_dev->notification_bitmap)
			dev_warn(&pdev->dev,
				 "Unable to allocate notification bitmap\n");
		else
			caps_in_use |= VMCI_CAPS_NOTIFICATIONS;
	}

	if (mmio_base != NULL) {
		if (capabilities & VMCI_CAPS_DMA_DATAGRAM) {
			caps_in_use |= VMCI_CAPS_DMA_DATAGRAM;
		} else {
			dev_err(&pdev->dev,
				"Missing capability: VMCI_CAPS_DMA_DATAGRAM\n");
			error = -ENXIO;
			goto err_free_notification_bitmap;
		}
	}

	dev_info(&pdev->dev, "Using capabilities 0x%x\n", caps_in_use);

	/* Let the host know which capabilities we intend to use. */
	vmci_write_reg(vmci_dev, caps_in_use, VMCI_CAPS_ADDR);

	if (caps_in_use & VMCI_CAPS_DMA_DATAGRAM) {
		/* Let the device know the size for pages passed down. */
		vmci_write_reg(vmci_dev, PAGE_SHIFT, VMCI_GUEST_PAGE_SHIFT);

		/* Configure the high order parts of the data in/out buffers. */
		vmci_write_reg(vmci_dev, upper_32_bits(vmci_dev->data_buffer_base),
			       VMCI_DATA_IN_HIGH_ADDR);
		vmci_write_reg(vmci_dev, upper_32_bits(vmci_dev->tx_buffer_base),
			       VMCI_DATA_OUT_HIGH_ADDR);
	}

	/* Set up global device so that we can start sending datagrams */
	spin_lock_irq(&vmci_dev_spinlock);
	vmci_dev_g = vmci_dev;
	vmci_pdev = pdev;
	spin_unlock_irq(&vmci_dev_spinlock);

	/*
	 * Register notification bitmap with device if that capability is
	 * used.
	 */
	if (caps_in_use & VMCI_CAPS_NOTIFICATIONS) {
		unsigned long bitmap_ppn =
			vmci_dev->notification_base >> PAGE_SHIFT;
		if (!vmci_dbell_register_notification_bitmap(bitmap_ppn)) {
			dev_warn(&pdev->dev,
				 "VMCI device unable to register notification bitmap with PPN 0x%lx\n",
				 bitmap_ppn);
			error = -ENXIO;
			goto err_remove_vmci_dev_g;
		}
	}

	/* Check host capabilities. */
	error = vmci_check_host_caps(pdev);
	if (error)
		goto err_remove_vmci_dev_g;

	/* Enable device. */

	/*
	 * We subscribe to the VMCI_EVENT_CTX_ID_UPDATE here so we can
	 * update the internal context id when needed.
	 */
	vmci_err = vmci_event_subscribe(VMCI_EVENT_CTX_ID_UPDATE,
					vmci_guest_cid_update, NULL,
					&ctx_update_sub_id);
	if (vmci_err < VMCI_SUCCESS)
		dev_warn(&pdev->dev,
			 "Failed to subscribe to event (type=%d): %d\n",
			 VMCI_EVENT_CTX_ID_UPDATE, vmci_err);

	/*
	 * Enable interrupts.  Try MSI-X first, then MSI, and then fallback on
	 * legacy interrupts.
	 */
	if (vmci_dev->mmio_base != NULL)
		num_irq_vectors = VMCI_MAX_INTRS;
	else
		num_irq_vectors = VMCI_MAX_INTRS_NOTIFICATION;
	error = pci_alloc_irq_vectors(pdev, num_irq_vectors, num_irq_vectors,
				      PCI_IRQ_MSIX);
	if (error < 0) {
		error = pci_alloc_irq_vectors(pdev, 1, 1,
				PCI_IRQ_MSIX | PCI_IRQ_MSI | PCI_IRQ_LEGACY);
		if (error < 0)
			goto err_unsubscribe_event;
	} else {
		vmci_dev->exclusive_vectors = true;
	}

	/*
	 * Request IRQ for legacy or MSI interrupts, or for first
	 * MSI-X vector.
	 */
	error = request_threaded_irq(pci_irq_vector(pdev, 0), NULL,
				     vmci_interrupt, IRQF_SHARED,
				     KBUILD_MODNAME, vmci_dev);
	if (error) {
		dev_err(&pdev->dev, "Irq %u in use: %d\n",
			pci_irq_vector(pdev, 0), error);
		goto err_disable_msi;
	}

	/*
	 * For MSI-X with exclusive vectors we need to request an
	 * interrupt for each vector so that we get a separate
	 * interrupt handler routine.  This allows us to distinguish
	 * between the vectors.
	 */
	if (vmci_dev->exclusive_vectors) {
		error = request_threaded_irq(pci_irq_vector(pdev, 1), NULL,
					     vmci_interrupt_bm, 0,
					     KBUILD_MODNAME, vmci_dev);
		if (error) {
			dev_err(&pdev->dev,
				"Failed to allocate irq %u: %d\n",
				pci_irq_vector(pdev, 1), error);
			goto err_free_irq;
		}
		if (caps_in_use & VMCI_CAPS_DMA_DATAGRAM) {
			error = request_threaded_irq(pci_irq_vector(pdev, 2),
						     NULL,
						    vmci_interrupt_dma_datagram,
						     0, KBUILD_MODNAME,
						     vmci_dev);
			if (error) {
				dev_err(&pdev->dev,
					"Failed to allocate irq %u: %d\n",
					pci_irq_vector(pdev, 2), error);
				goto err_free_bm_irq;
			}
		}
	}

	dev_dbg(&pdev->dev, "Registered device\n");

	atomic_inc(&vmci_num_guest_devices);

	/* Enable specific interrupt bits. */
	cmd = VMCI_IMR_DATAGRAM;
	if (caps_in_use & VMCI_CAPS_NOTIFICATIONS)
		cmd |= VMCI_IMR_NOTIFICATION;
	if (caps_in_use & VMCI_CAPS_DMA_DATAGRAM)
		cmd |= VMCI_IMR_DMA_DATAGRAM;
	vmci_write_reg(vmci_dev, cmd, VMCI_IMR_ADDR);

	/* Enable interrupts. */
	vmci_write_reg(vmci_dev, VMCI_CONTROL_INT_ENABLE, VMCI_CONTROL_ADDR);

	pci_set_drvdata(pdev, vmci_dev);

	vmci_call_vsock_callback(false);
	return 0;

err_free_bm_irq:
	if (vmci_dev->exclusive_vectors)
		free_irq(pci_irq_vector(pdev, 1), vmci_dev);

err_free_irq:
	free_irq(pci_irq_vector(pdev, 0), vmci_dev);

err_disable_msi:
	pci_free_irq_vectors(pdev);

err_unsubscribe_event:
	vmci_err = vmci_event_unsubscribe(ctx_update_sub_id);
	if (vmci_err < VMCI_SUCCESS)
		dev_warn(&pdev->dev,
			 "Failed to unsubscribe from event (type=%d) with subscriber (ID=0x%x): %d\n",
			 VMCI_EVENT_CTX_ID_UPDATE, ctx_update_sub_id, vmci_err);

err_remove_vmci_dev_g:
	spin_lock_irq(&vmci_dev_spinlock);
	vmci_pdev = NULL;
	vmci_dev_g = NULL;
	spin_unlock_irq(&vmci_dev_spinlock);

err_free_notification_bitmap:
	if (vmci_dev->notification_bitmap) {
		vmci_write_reg(vmci_dev, VMCI_CONTROL_RESET, VMCI_CONTROL_ADDR);
		dma_free_coherent(&pdev->dev, PAGE_SIZE,
				  vmci_dev->notification_bitmap,
				  vmci_dev->notification_base);
	}

err_free_data_buffers:
	vmci_free_dg_buffers(vmci_dev);

	/* The rest are managed resources and will be freed by PCI core */
	return error;
}

static void vmci_guest_remove_device(struct pci_dev *pdev)
{
	struct vmci_guest_device *vmci_dev = pci_get_drvdata(pdev);
	int vmci_err;

	dev_dbg(&pdev->dev, "Removing device\n");

	atomic_dec(&vmci_num_guest_devices);

	vmci_qp_guest_endpoints_exit();

	vmci_err = vmci_event_unsubscribe(ctx_update_sub_id);
	if (vmci_err < VMCI_SUCCESS)
		dev_warn(&pdev->dev,
			 "Failed to unsubscribe from event (type=%d) with subscriber (ID=0x%x): %d\n",
			 VMCI_EVENT_CTX_ID_UPDATE, ctx_update_sub_id, vmci_err);

	spin_lock_irq(&vmci_dev_spinlock);
	vmci_dev_g = NULL;
	vmci_pdev = NULL;
	spin_unlock_irq(&vmci_dev_spinlock);

	dev_dbg(&pdev->dev, "Resetting vmci device\n");
	vmci_write_reg(vmci_dev, VMCI_CONTROL_RESET, VMCI_CONTROL_ADDR);

	/*
	 * Free IRQ and then disable MSI/MSI-X as appropriate.  For
	 * MSI-X, we might have multiple vectors, each with their own
	 * IRQ, which we must free too.
	 */
	if (vmci_dev->exclusive_vectors) {
		free_irq(pci_irq_vector(pdev, 1), vmci_dev);
		if (vmci_dev->mmio_base != NULL)
			free_irq(pci_irq_vector(pdev, 2), vmci_dev);
	}
	free_irq(pci_irq_vector(pdev, 0), vmci_dev);
	pci_free_irq_vectors(pdev);

	if (vmci_dev->notification_bitmap) {
		/*
		 * The device reset above cleared the bitmap state of the
		 * device, so we can safely free it here.
		 */

		dma_free_coherent(&pdev->dev, PAGE_SIZE,
				  vmci_dev->notification_bitmap,
				  vmci_dev->notification_base);
	}

	vmci_free_dg_buffers(vmci_dev);

	if (vmci_dev->mmio_base != NULL)
		pci_iounmap(pdev, vmci_dev->mmio_base);

	/* The rest are managed resources and will be freed by PCI core */
}

static const struct pci_device_id vmci_ids[] = {
	{ PCI_DEVICE(PCI_VENDOR_ID_VMWARE, PCI_DEVICE_ID_VMWARE_VMCI), },
	{ 0 },
};
MODULE_DEVICE_TABLE(pci, vmci_ids);

static struct pci_driver vmci_guest_driver = {
	.name		= KBUILD_MODNAME,
	.id_table	= vmci_ids,
	.probe		= vmci_guest_probe_device,
	.remove		= vmci_guest_remove_device,
};

int __init vmci_guest_init(void)
{
	return pci_register_driver(&vmci_guest_driver);
}

void __exit vmci_guest_exit(void)
{
	pci_unregister_driver(&vmci_guest_driver);
}
