xref: /OK3568_Linux_fs/kernel/drivers/misc/vmw_vmci/vmci_guest.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-only
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * VMware VMCI Driver
4*4882a593Smuzhiyun  *
5*4882a593Smuzhiyun  * Copyright (C) 2012 VMware, Inc. All rights reserved.
6*4882a593Smuzhiyun  */
7*4882a593Smuzhiyun 
8*4882a593Smuzhiyun #include <linux/vmw_vmci_defs.h>
9*4882a593Smuzhiyun #include <linux/vmw_vmci_api.h>
10*4882a593Smuzhiyun #include <linux/moduleparam.h>
11*4882a593Smuzhiyun #include <linux/interrupt.h>
12*4882a593Smuzhiyun #include <linux/highmem.h>
13*4882a593Smuzhiyun #include <linux/kernel.h>
14*4882a593Smuzhiyun #include <linux/mm.h>
15*4882a593Smuzhiyun #include <linux/module.h>
16*4882a593Smuzhiyun #include <linux/sched.h>
17*4882a593Smuzhiyun #include <linux/slab.h>
18*4882a593Smuzhiyun #include <linux/init.h>
19*4882a593Smuzhiyun #include <linux/pci.h>
20*4882a593Smuzhiyun #include <linux/smp.h>
21*4882a593Smuzhiyun #include <linux/io.h>
22*4882a593Smuzhiyun #include <linux/vmalloc.h>
23*4882a593Smuzhiyun 
24*4882a593Smuzhiyun #include "vmci_datagram.h"
25*4882a593Smuzhiyun #include "vmci_doorbell.h"
26*4882a593Smuzhiyun #include "vmci_context.h"
27*4882a593Smuzhiyun #include "vmci_driver.h"
28*4882a593Smuzhiyun #include "vmci_event.h"
29*4882a593Smuzhiyun 
30*4882a593Smuzhiyun #define PCI_DEVICE_ID_VMWARE_VMCI	0x0740
31*4882a593Smuzhiyun 
32*4882a593Smuzhiyun #define VMCI_UTIL_NUM_RESOURCES 1
33*4882a593Smuzhiyun 
34*4882a593Smuzhiyun static bool vmci_disable_msi;
35*4882a593Smuzhiyun module_param_named(disable_msi, vmci_disable_msi, bool, 0);
36*4882a593Smuzhiyun MODULE_PARM_DESC(disable_msi, "Disable MSI use in driver - (default=0)");
37*4882a593Smuzhiyun 
38*4882a593Smuzhiyun static bool vmci_disable_msix;
39*4882a593Smuzhiyun module_param_named(disable_msix, vmci_disable_msix, bool, 0);
40*4882a593Smuzhiyun MODULE_PARM_DESC(disable_msix, "Disable MSI-X use in driver - (default=0)");
41*4882a593Smuzhiyun 
42*4882a593Smuzhiyun static u32 ctx_update_sub_id = VMCI_INVALID_ID;
43*4882a593Smuzhiyun static u32 vm_context_id = VMCI_INVALID_ID;
44*4882a593Smuzhiyun 
45*4882a593Smuzhiyun struct vmci_guest_device {
46*4882a593Smuzhiyun 	struct device *dev;	/* PCI device we are attached to */
47*4882a593Smuzhiyun 	void __iomem *iobase;
48*4882a593Smuzhiyun 
49*4882a593Smuzhiyun 	bool exclusive_vectors;
50*4882a593Smuzhiyun 
51*4882a593Smuzhiyun 	struct tasklet_struct datagram_tasklet;
52*4882a593Smuzhiyun 	struct tasklet_struct bm_tasklet;
53*4882a593Smuzhiyun 
54*4882a593Smuzhiyun 	void *data_buffer;
55*4882a593Smuzhiyun 	void *notification_bitmap;
56*4882a593Smuzhiyun 	dma_addr_t notification_base;
57*4882a593Smuzhiyun };
58*4882a593Smuzhiyun 
59*4882a593Smuzhiyun static bool use_ppn64;
60*4882a593Smuzhiyun 
vmci_use_ppn64(void)61*4882a593Smuzhiyun bool vmci_use_ppn64(void)
62*4882a593Smuzhiyun {
63*4882a593Smuzhiyun 	return use_ppn64;
64*4882a593Smuzhiyun }
65*4882a593Smuzhiyun 
66*4882a593Smuzhiyun /* vmci_dev singleton device and supporting data*/
67*4882a593Smuzhiyun struct pci_dev *vmci_pdev;
68*4882a593Smuzhiyun static struct vmci_guest_device *vmci_dev_g;
69*4882a593Smuzhiyun static DEFINE_SPINLOCK(vmci_dev_spinlock);
70*4882a593Smuzhiyun 
71*4882a593Smuzhiyun static atomic_t vmci_num_guest_devices = ATOMIC_INIT(0);
72*4882a593Smuzhiyun 
vmci_guest_code_active(void)73*4882a593Smuzhiyun bool vmci_guest_code_active(void)
74*4882a593Smuzhiyun {
75*4882a593Smuzhiyun 	return atomic_read(&vmci_num_guest_devices) != 0;
76*4882a593Smuzhiyun }
77*4882a593Smuzhiyun 
vmci_get_vm_context_id(void)78*4882a593Smuzhiyun u32 vmci_get_vm_context_id(void)
79*4882a593Smuzhiyun {
80*4882a593Smuzhiyun 	if (vm_context_id == VMCI_INVALID_ID) {
81*4882a593Smuzhiyun 		struct vmci_datagram get_cid_msg;
82*4882a593Smuzhiyun 		get_cid_msg.dst =
83*4882a593Smuzhiyun 		    vmci_make_handle(VMCI_HYPERVISOR_CONTEXT_ID,
84*4882a593Smuzhiyun 				     VMCI_GET_CONTEXT_ID);
85*4882a593Smuzhiyun 		get_cid_msg.src = VMCI_ANON_SRC_HANDLE;
86*4882a593Smuzhiyun 		get_cid_msg.payload_size = 0;
87*4882a593Smuzhiyun 		vm_context_id = vmci_send_datagram(&get_cid_msg);
88*4882a593Smuzhiyun 	}
89*4882a593Smuzhiyun 	return vm_context_id;
90*4882a593Smuzhiyun }
91*4882a593Smuzhiyun 
92*4882a593Smuzhiyun /*
93*4882a593Smuzhiyun  * VM to hypervisor call mechanism. We use the standard VMware naming
94*4882a593Smuzhiyun  * convention since shared code is calling this function as well.
95*4882a593Smuzhiyun  */
vmci_send_datagram(struct vmci_datagram * dg)96*4882a593Smuzhiyun int vmci_send_datagram(struct vmci_datagram *dg)
97*4882a593Smuzhiyun {
98*4882a593Smuzhiyun 	unsigned long flags;
99*4882a593Smuzhiyun 	int result;
100*4882a593Smuzhiyun 
101*4882a593Smuzhiyun 	/* Check args. */
102*4882a593Smuzhiyun 	if (dg == NULL)
103*4882a593Smuzhiyun 		return VMCI_ERROR_INVALID_ARGS;
104*4882a593Smuzhiyun 
105*4882a593Smuzhiyun 	/*
106*4882a593Smuzhiyun 	 * Need to acquire spinlock on the device because the datagram
107*4882a593Smuzhiyun 	 * data may be spread over multiple pages and the monitor may
108*4882a593Smuzhiyun 	 * interleave device user rpc calls from multiple
109*4882a593Smuzhiyun 	 * VCPUs. Acquiring the spinlock precludes that
110*4882a593Smuzhiyun 	 * possibility. Disabling interrupts to avoid incoming
111*4882a593Smuzhiyun 	 * datagrams during a "rep out" and possibly landing up in
112*4882a593Smuzhiyun 	 * this function.
113*4882a593Smuzhiyun 	 */
114*4882a593Smuzhiyun 	spin_lock_irqsave(&vmci_dev_spinlock, flags);
115*4882a593Smuzhiyun 
116*4882a593Smuzhiyun 	if (vmci_dev_g) {
117*4882a593Smuzhiyun 		iowrite8_rep(vmci_dev_g->iobase + VMCI_DATA_OUT_ADDR,
118*4882a593Smuzhiyun 			     dg, VMCI_DG_SIZE(dg));
119*4882a593Smuzhiyun 		result = ioread32(vmci_dev_g->iobase + VMCI_RESULT_LOW_ADDR);
120*4882a593Smuzhiyun 	} else {
121*4882a593Smuzhiyun 		result = VMCI_ERROR_UNAVAILABLE;
122*4882a593Smuzhiyun 	}
123*4882a593Smuzhiyun 
124*4882a593Smuzhiyun 	spin_unlock_irqrestore(&vmci_dev_spinlock, flags);
125*4882a593Smuzhiyun 
126*4882a593Smuzhiyun 	return result;
127*4882a593Smuzhiyun }
128*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(vmci_send_datagram);
129*4882a593Smuzhiyun 
130*4882a593Smuzhiyun /*
131*4882a593Smuzhiyun  * Gets called with the new context id if updated or resumed.
132*4882a593Smuzhiyun  * Context id.
133*4882a593Smuzhiyun  */
vmci_guest_cid_update(u32 sub_id,const struct vmci_event_data * event_data,void * client_data)134*4882a593Smuzhiyun static void vmci_guest_cid_update(u32 sub_id,
135*4882a593Smuzhiyun 				  const struct vmci_event_data *event_data,
136*4882a593Smuzhiyun 				  void *client_data)
137*4882a593Smuzhiyun {
138*4882a593Smuzhiyun 	const struct vmci_event_payld_ctx *ev_payload =
139*4882a593Smuzhiyun 				vmci_event_data_const_payload(event_data);
140*4882a593Smuzhiyun 
141*4882a593Smuzhiyun 	if (sub_id != ctx_update_sub_id) {
142*4882a593Smuzhiyun 		pr_devel("Invalid subscriber (ID=0x%x)\n", sub_id);
143*4882a593Smuzhiyun 		return;
144*4882a593Smuzhiyun 	}
145*4882a593Smuzhiyun 
146*4882a593Smuzhiyun 	if (!event_data || ev_payload->context_id == VMCI_INVALID_ID) {
147*4882a593Smuzhiyun 		pr_devel("Invalid event data\n");
148*4882a593Smuzhiyun 		return;
149*4882a593Smuzhiyun 	}
150*4882a593Smuzhiyun 
151*4882a593Smuzhiyun 	pr_devel("Updating context from (ID=0x%x) to (ID=0x%x) on event (type=%d)\n",
152*4882a593Smuzhiyun 		 vm_context_id, ev_payload->context_id, event_data->event);
153*4882a593Smuzhiyun 
154*4882a593Smuzhiyun 	vm_context_id = ev_payload->context_id;
155*4882a593Smuzhiyun }
156*4882a593Smuzhiyun 
157*4882a593Smuzhiyun /*
158*4882a593Smuzhiyun  * Verify that the host supports the hypercalls we need. If it does not,
159*4882a593Smuzhiyun  * try to find fallback hypercalls and use those instead.  Returns
160*4882a593Smuzhiyun  * true if required hypercalls (or fallback hypercalls) are
161*4882a593Smuzhiyun  * supported by the host, false otherwise.
162*4882a593Smuzhiyun  */
vmci_check_host_caps(struct pci_dev * pdev)163*4882a593Smuzhiyun static int vmci_check_host_caps(struct pci_dev *pdev)
164*4882a593Smuzhiyun {
165*4882a593Smuzhiyun 	bool result;
166*4882a593Smuzhiyun 	struct vmci_resource_query_msg *msg;
167*4882a593Smuzhiyun 	u32 msg_size = sizeof(struct vmci_resource_query_hdr) +
168*4882a593Smuzhiyun 				VMCI_UTIL_NUM_RESOURCES * sizeof(u32);
169*4882a593Smuzhiyun 	struct vmci_datagram *check_msg;
170*4882a593Smuzhiyun 
171*4882a593Smuzhiyun 	check_msg = kzalloc(msg_size, GFP_KERNEL);
172*4882a593Smuzhiyun 	if (!check_msg) {
173*4882a593Smuzhiyun 		dev_err(&pdev->dev, "%s: Insufficient memory\n", __func__);
174*4882a593Smuzhiyun 		return -ENOMEM;
175*4882a593Smuzhiyun 	}
176*4882a593Smuzhiyun 
177*4882a593Smuzhiyun 	check_msg->dst = vmci_make_handle(VMCI_HYPERVISOR_CONTEXT_ID,
178*4882a593Smuzhiyun 					  VMCI_RESOURCES_QUERY);
179*4882a593Smuzhiyun 	check_msg->src = VMCI_ANON_SRC_HANDLE;
180*4882a593Smuzhiyun 	check_msg->payload_size = msg_size - VMCI_DG_HEADERSIZE;
181*4882a593Smuzhiyun 	msg = (struct vmci_resource_query_msg *)VMCI_DG_PAYLOAD(check_msg);
182*4882a593Smuzhiyun 
183*4882a593Smuzhiyun 	msg->num_resources = VMCI_UTIL_NUM_RESOURCES;
184*4882a593Smuzhiyun 	msg->resources[0] = VMCI_GET_CONTEXT_ID;
185*4882a593Smuzhiyun 
186*4882a593Smuzhiyun 	/* Checks that hyper calls are supported */
187*4882a593Smuzhiyun 	result = vmci_send_datagram(check_msg) == 0x01;
188*4882a593Smuzhiyun 	kfree(check_msg);
189*4882a593Smuzhiyun 
190*4882a593Smuzhiyun 	dev_dbg(&pdev->dev, "%s: Host capability check: %s\n",
191*4882a593Smuzhiyun 		__func__, result ? "PASSED" : "FAILED");
192*4882a593Smuzhiyun 
193*4882a593Smuzhiyun 	/* We need the vector. There are no fallbacks. */
194*4882a593Smuzhiyun 	return result ? 0 : -ENXIO;
195*4882a593Smuzhiyun }
196*4882a593Smuzhiyun 
197*4882a593Smuzhiyun /*
198*4882a593Smuzhiyun  * Reads datagrams from the data in port and dispatches them. We
199*4882a593Smuzhiyun  * always start reading datagrams into only the first page of the
200*4882a593Smuzhiyun  * datagram buffer. If the datagrams don't fit into one page, we
201*4882a593Smuzhiyun  * use the maximum datagram buffer size for the remainder of the
202*4882a593Smuzhiyun  * invocation. This is a simple heuristic for not penalizing
203*4882a593Smuzhiyun  * small datagrams.
204*4882a593Smuzhiyun  *
205*4882a593Smuzhiyun  * This function assumes that it has exclusive access to the data
206*4882a593Smuzhiyun  * in port for the duration of the call.
207*4882a593Smuzhiyun  */
vmci_dispatch_dgs(unsigned long data)208*4882a593Smuzhiyun static void vmci_dispatch_dgs(unsigned long data)
209*4882a593Smuzhiyun {
210*4882a593Smuzhiyun 	struct vmci_guest_device *vmci_dev = (struct vmci_guest_device *)data;
211*4882a593Smuzhiyun 	u8 *dg_in_buffer = vmci_dev->data_buffer;
212*4882a593Smuzhiyun 	struct vmci_datagram *dg;
213*4882a593Smuzhiyun 	size_t dg_in_buffer_size = VMCI_MAX_DG_SIZE;
214*4882a593Smuzhiyun 	size_t current_dg_in_buffer_size = PAGE_SIZE;
215*4882a593Smuzhiyun 	size_t remaining_bytes;
216*4882a593Smuzhiyun 
217*4882a593Smuzhiyun 	BUILD_BUG_ON(VMCI_MAX_DG_SIZE < PAGE_SIZE);
218*4882a593Smuzhiyun 
219*4882a593Smuzhiyun 	ioread8_rep(vmci_dev->iobase + VMCI_DATA_IN_ADDR,
220*4882a593Smuzhiyun 		    vmci_dev->data_buffer, current_dg_in_buffer_size);
221*4882a593Smuzhiyun 	dg = (struct vmci_datagram *)dg_in_buffer;
222*4882a593Smuzhiyun 	remaining_bytes = current_dg_in_buffer_size;
223*4882a593Smuzhiyun 
224*4882a593Smuzhiyun 	while (dg->dst.resource != VMCI_INVALID_ID ||
225*4882a593Smuzhiyun 	       remaining_bytes > PAGE_SIZE) {
226*4882a593Smuzhiyun 		unsigned dg_in_size;
227*4882a593Smuzhiyun 
228*4882a593Smuzhiyun 		/*
229*4882a593Smuzhiyun 		 * When the input buffer spans multiple pages, a datagram can
230*4882a593Smuzhiyun 		 * start on any page boundary in the buffer.
231*4882a593Smuzhiyun 		 */
232*4882a593Smuzhiyun 		if (dg->dst.resource == VMCI_INVALID_ID) {
233*4882a593Smuzhiyun 			dg = (struct vmci_datagram *)roundup(
234*4882a593Smuzhiyun 				(uintptr_t)dg + 1, PAGE_SIZE);
235*4882a593Smuzhiyun 			remaining_bytes =
236*4882a593Smuzhiyun 				(size_t)(dg_in_buffer +
237*4882a593Smuzhiyun 					 current_dg_in_buffer_size -
238*4882a593Smuzhiyun 					 (u8 *)dg);
239*4882a593Smuzhiyun 			continue;
240*4882a593Smuzhiyun 		}
241*4882a593Smuzhiyun 
242*4882a593Smuzhiyun 		dg_in_size = VMCI_DG_SIZE_ALIGNED(dg);
243*4882a593Smuzhiyun 
244*4882a593Smuzhiyun 		if (dg_in_size <= dg_in_buffer_size) {
245*4882a593Smuzhiyun 			int result;
246*4882a593Smuzhiyun 
247*4882a593Smuzhiyun 			/*
248*4882a593Smuzhiyun 			 * If the remaining bytes in the datagram
249*4882a593Smuzhiyun 			 * buffer doesn't contain the complete
250*4882a593Smuzhiyun 			 * datagram, we first make sure we have enough
251*4882a593Smuzhiyun 			 * room for it and then we read the reminder
252*4882a593Smuzhiyun 			 * of the datagram and possibly any following
253*4882a593Smuzhiyun 			 * datagrams.
254*4882a593Smuzhiyun 			 */
255*4882a593Smuzhiyun 			if (dg_in_size > remaining_bytes) {
256*4882a593Smuzhiyun 				if (remaining_bytes !=
257*4882a593Smuzhiyun 				    current_dg_in_buffer_size) {
258*4882a593Smuzhiyun 
259*4882a593Smuzhiyun 					/*
260*4882a593Smuzhiyun 					 * We move the partial
261*4882a593Smuzhiyun 					 * datagram to the front and
262*4882a593Smuzhiyun 					 * read the reminder of the
263*4882a593Smuzhiyun 					 * datagram and possibly
264*4882a593Smuzhiyun 					 * following calls into the
265*4882a593Smuzhiyun 					 * following bytes.
266*4882a593Smuzhiyun 					 */
267*4882a593Smuzhiyun 					memmove(dg_in_buffer, dg_in_buffer +
268*4882a593Smuzhiyun 						current_dg_in_buffer_size -
269*4882a593Smuzhiyun 						remaining_bytes,
270*4882a593Smuzhiyun 						remaining_bytes);
271*4882a593Smuzhiyun 					dg = (struct vmci_datagram *)
272*4882a593Smuzhiyun 					    dg_in_buffer;
273*4882a593Smuzhiyun 				}
274*4882a593Smuzhiyun 
275*4882a593Smuzhiyun 				if (current_dg_in_buffer_size !=
276*4882a593Smuzhiyun 				    dg_in_buffer_size)
277*4882a593Smuzhiyun 					current_dg_in_buffer_size =
278*4882a593Smuzhiyun 					    dg_in_buffer_size;
279*4882a593Smuzhiyun 
280*4882a593Smuzhiyun 				ioread8_rep(vmci_dev->iobase +
281*4882a593Smuzhiyun 						VMCI_DATA_IN_ADDR,
282*4882a593Smuzhiyun 					vmci_dev->data_buffer +
283*4882a593Smuzhiyun 						remaining_bytes,
284*4882a593Smuzhiyun 					current_dg_in_buffer_size -
285*4882a593Smuzhiyun 						remaining_bytes);
286*4882a593Smuzhiyun 			}
287*4882a593Smuzhiyun 
288*4882a593Smuzhiyun 			/*
289*4882a593Smuzhiyun 			 * We special case event datagrams from the
290*4882a593Smuzhiyun 			 * hypervisor.
291*4882a593Smuzhiyun 			 */
292*4882a593Smuzhiyun 			if (dg->src.context == VMCI_HYPERVISOR_CONTEXT_ID &&
293*4882a593Smuzhiyun 			    dg->dst.resource == VMCI_EVENT_HANDLER) {
294*4882a593Smuzhiyun 				result = vmci_event_dispatch(dg);
295*4882a593Smuzhiyun 			} else {
296*4882a593Smuzhiyun 				result = vmci_datagram_invoke_guest_handler(dg);
297*4882a593Smuzhiyun 			}
298*4882a593Smuzhiyun 			if (result < VMCI_SUCCESS)
299*4882a593Smuzhiyun 				dev_dbg(vmci_dev->dev,
300*4882a593Smuzhiyun 					"Datagram with resource (ID=0x%x) failed (err=%d)\n",
301*4882a593Smuzhiyun 					 dg->dst.resource, result);
302*4882a593Smuzhiyun 
303*4882a593Smuzhiyun 			/* On to the next datagram. */
304*4882a593Smuzhiyun 			dg = (struct vmci_datagram *)((u8 *)dg +
305*4882a593Smuzhiyun 						      dg_in_size);
306*4882a593Smuzhiyun 		} else {
307*4882a593Smuzhiyun 			size_t bytes_to_skip;
308*4882a593Smuzhiyun 
309*4882a593Smuzhiyun 			/*
310*4882a593Smuzhiyun 			 * Datagram doesn't fit in datagram buffer of maximal
311*4882a593Smuzhiyun 			 * size. We drop it.
312*4882a593Smuzhiyun 			 */
313*4882a593Smuzhiyun 			dev_dbg(vmci_dev->dev,
314*4882a593Smuzhiyun 				"Failed to receive datagram (size=%u bytes)\n",
315*4882a593Smuzhiyun 				 dg_in_size);
316*4882a593Smuzhiyun 
317*4882a593Smuzhiyun 			bytes_to_skip = dg_in_size - remaining_bytes;
318*4882a593Smuzhiyun 			if (current_dg_in_buffer_size != dg_in_buffer_size)
319*4882a593Smuzhiyun 				current_dg_in_buffer_size = dg_in_buffer_size;
320*4882a593Smuzhiyun 
321*4882a593Smuzhiyun 			for (;;) {
322*4882a593Smuzhiyun 				ioread8_rep(vmci_dev->iobase +
323*4882a593Smuzhiyun 						VMCI_DATA_IN_ADDR,
324*4882a593Smuzhiyun 					vmci_dev->data_buffer,
325*4882a593Smuzhiyun 					current_dg_in_buffer_size);
326*4882a593Smuzhiyun 				if (bytes_to_skip <= current_dg_in_buffer_size)
327*4882a593Smuzhiyun 					break;
328*4882a593Smuzhiyun 
329*4882a593Smuzhiyun 				bytes_to_skip -= current_dg_in_buffer_size;
330*4882a593Smuzhiyun 			}
331*4882a593Smuzhiyun 			dg = (struct vmci_datagram *)(dg_in_buffer +
332*4882a593Smuzhiyun 						      bytes_to_skip);
333*4882a593Smuzhiyun 		}
334*4882a593Smuzhiyun 
335*4882a593Smuzhiyun 		remaining_bytes =
336*4882a593Smuzhiyun 		    (size_t) (dg_in_buffer + current_dg_in_buffer_size -
337*4882a593Smuzhiyun 			      (u8 *)dg);
338*4882a593Smuzhiyun 
339*4882a593Smuzhiyun 		if (remaining_bytes < VMCI_DG_HEADERSIZE) {
340*4882a593Smuzhiyun 			/* Get the next batch of datagrams. */
341*4882a593Smuzhiyun 
342*4882a593Smuzhiyun 			ioread8_rep(vmci_dev->iobase + VMCI_DATA_IN_ADDR,
343*4882a593Smuzhiyun 				    vmci_dev->data_buffer,
344*4882a593Smuzhiyun 				    current_dg_in_buffer_size);
345*4882a593Smuzhiyun 			dg = (struct vmci_datagram *)dg_in_buffer;
346*4882a593Smuzhiyun 			remaining_bytes = current_dg_in_buffer_size;
347*4882a593Smuzhiyun 		}
348*4882a593Smuzhiyun 	}
349*4882a593Smuzhiyun }
350*4882a593Smuzhiyun 
351*4882a593Smuzhiyun /*
352*4882a593Smuzhiyun  * Scans the notification bitmap for raised flags, clears them
353*4882a593Smuzhiyun  * and handles the notifications.
354*4882a593Smuzhiyun  */
vmci_process_bitmap(unsigned long data)355*4882a593Smuzhiyun static void vmci_process_bitmap(unsigned long data)
356*4882a593Smuzhiyun {
357*4882a593Smuzhiyun 	struct vmci_guest_device *dev = (struct vmci_guest_device *)data;
358*4882a593Smuzhiyun 
359*4882a593Smuzhiyun 	if (!dev->notification_bitmap) {
360*4882a593Smuzhiyun 		dev_dbg(dev->dev, "No bitmap present in %s\n", __func__);
361*4882a593Smuzhiyun 		return;
362*4882a593Smuzhiyun 	}
363*4882a593Smuzhiyun 
364*4882a593Smuzhiyun 	vmci_dbell_scan_notification_entries(dev->notification_bitmap);
365*4882a593Smuzhiyun }
366*4882a593Smuzhiyun 
367*4882a593Smuzhiyun /*
368*4882a593Smuzhiyun  * Interrupt handler for legacy or MSI interrupt, or for first MSI-X
369*4882a593Smuzhiyun  * interrupt (vector VMCI_INTR_DATAGRAM).
370*4882a593Smuzhiyun  */
vmci_interrupt(int irq,void * _dev)371*4882a593Smuzhiyun static irqreturn_t vmci_interrupt(int irq, void *_dev)
372*4882a593Smuzhiyun {
373*4882a593Smuzhiyun 	struct vmci_guest_device *dev = _dev;
374*4882a593Smuzhiyun 
375*4882a593Smuzhiyun 	/*
376*4882a593Smuzhiyun 	 * If we are using MSI-X with exclusive vectors then we simply schedule
377*4882a593Smuzhiyun 	 * the datagram tasklet, since we know the interrupt was meant for us.
378*4882a593Smuzhiyun 	 * Otherwise we must read the ICR to determine what to do.
379*4882a593Smuzhiyun 	 */
380*4882a593Smuzhiyun 
381*4882a593Smuzhiyun 	if (dev->exclusive_vectors) {
382*4882a593Smuzhiyun 		tasklet_schedule(&dev->datagram_tasklet);
383*4882a593Smuzhiyun 	} else {
384*4882a593Smuzhiyun 		unsigned int icr;
385*4882a593Smuzhiyun 
386*4882a593Smuzhiyun 		/* Acknowledge interrupt and determine what needs doing. */
387*4882a593Smuzhiyun 		icr = ioread32(dev->iobase + VMCI_ICR_ADDR);
388*4882a593Smuzhiyun 		if (icr == 0 || icr == ~0)
389*4882a593Smuzhiyun 			return IRQ_NONE;
390*4882a593Smuzhiyun 
391*4882a593Smuzhiyun 		if (icr & VMCI_ICR_DATAGRAM) {
392*4882a593Smuzhiyun 			tasklet_schedule(&dev->datagram_tasklet);
393*4882a593Smuzhiyun 			icr &= ~VMCI_ICR_DATAGRAM;
394*4882a593Smuzhiyun 		}
395*4882a593Smuzhiyun 
396*4882a593Smuzhiyun 		if (icr & VMCI_ICR_NOTIFICATION) {
397*4882a593Smuzhiyun 			tasklet_schedule(&dev->bm_tasklet);
398*4882a593Smuzhiyun 			icr &= ~VMCI_ICR_NOTIFICATION;
399*4882a593Smuzhiyun 		}
400*4882a593Smuzhiyun 
401*4882a593Smuzhiyun 		if (icr != 0)
402*4882a593Smuzhiyun 			dev_warn(dev->dev,
403*4882a593Smuzhiyun 				 "Ignoring unknown interrupt cause (%d)\n",
404*4882a593Smuzhiyun 				 icr);
405*4882a593Smuzhiyun 	}
406*4882a593Smuzhiyun 
407*4882a593Smuzhiyun 	return IRQ_HANDLED;
408*4882a593Smuzhiyun }
409*4882a593Smuzhiyun 
410*4882a593Smuzhiyun /*
411*4882a593Smuzhiyun  * Interrupt handler for MSI-X interrupt vector VMCI_INTR_NOTIFICATION,
412*4882a593Smuzhiyun  * which is for the notification bitmap.  Will only get called if we are
413*4882a593Smuzhiyun  * using MSI-X with exclusive vectors.
414*4882a593Smuzhiyun  */
vmci_interrupt_bm(int irq,void * _dev)415*4882a593Smuzhiyun static irqreturn_t vmci_interrupt_bm(int irq, void *_dev)
416*4882a593Smuzhiyun {
417*4882a593Smuzhiyun 	struct vmci_guest_device *dev = _dev;
418*4882a593Smuzhiyun 
419*4882a593Smuzhiyun 	/* For MSI-X we can just assume it was meant for us. */
420*4882a593Smuzhiyun 	tasklet_schedule(&dev->bm_tasklet);
421*4882a593Smuzhiyun 
422*4882a593Smuzhiyun 	return IRQ_HANDLED;
423*4882a593Smuzhiyun }
424*4882a593Smuzhiyun 
425*4882a593Smuzhiyun /*
426*4882a593Smuzhiyun  * Most of the initialization at module load time is done here.
427*4882a593Smuzhiyun  */
vmci_guest_probe_device(struct pci_dev * pdev,const struct pci_device_id * id)428*4882a593Smuzhiyun static int vmci_guest_probe_device(struct pci_dev *pdev,
429*4882a593Smuzhiyun 				   const struct pci_device_id *id)
430*4882a593Smuzhiyun {
431*4882a593Smuzhiyun 	struct vmci_guest_device *vmci_dev;
432*4882a593Smuzhiyun 	void __iomem *iobase;
433*4882a593Smuzhiyun 	unsigned int capabilities;
434*4882a593Smuzhiyun 	unsigned int caps_in_use;
435*4882a593Smuzhiyun 	unsigned long cmd;
436*4882a593Smuzhiyun 	int vmci_err;
437*4882a593Smuzhiyun 	int error;
438*4882a593Smuzhiyun 
439*4882a593Smuzhiyun 	dev_dbg(&pdev->dev, "Probing for vmci/PCI guest device\n");
440*4882a593Smuzhiyun 
441*4882a593Smuzhiyun 	error = pcim_enable_device(pdev);
442*4882a593Smuzhiyun 	if (error) {
443*4882a593Smuzhiyun 		dev_err(&pdev->dev,
444*4882a593Smuzhiyun 			"Failed to enable VMCI device: %d\n", error);
445*4882a593Smuzhiyun 		return error;
446*4882a593Smuzhiyun 	}
447*4882a593Smuzhiyun 
448*4882a593Smuzhiyun 	error = pcim_iomap_regions(pdev, 1 << 0, KBUILD_MODNAME);
449*4882a593Smuzhiyun 	if (error) {
450*4882a593Smuzhiyun 		dev_err(&pdev->dev, "Failed to reserve/map IO regions\n");
451*4882a593Smuzhiyun 		return error;
452*4882a593Smuzhiyun 	}
453*4882a593Smuzhiyun 
454*4882a593Smuzhiyun 	iobase = pcim_iomap_table(pdev)[0];
455*4882a593Smuzhiyun 
456*4882a593Smuzhiyun 	dev_info(&pdev->dev, "Found VMCI PCI device at %#lx, irq %u\n",
457*4882a593Smuzhiyun 		 (unsigned long)iobase, pdev->irq);
458*4882a593Smuzhiyun 
459*4882a593Smuzhiyun 	vmci_dev = devm_kzalloc(&pdev->dev, sizeof(*vmci_dev), GFP_KERNEL);
460*4882a593Smuzhiyun 	if (!vmci_dev) {
461*4882a593Smuzhiyun 		dev_err(&pdev->dev,
462*4882a593Smuzhiyun 			"Can't allocate memory for VMCI device\n");
463*4882a593Smuzhiyun 		return -ENOMEM;
464*4882a593Smuzhiyun 	}
465*4882a593Smuzhiyun 
466*4882a593Smuzhiyun 	vmci_dev->dev = &pdev->dev;
467*4882a593Smuzhiyun 	vmci_dev->exclusive_vectors = false;
468*4882a593Smuzhiyun 	vmci_dev->iobase = iobase;
469*4882a593Smuzhiyun 
470*4882a593Smuzhiyun 	tasklet_init(&vmci_dev->datagram_tasklet,
471*4882a593Smuzhiyun 		     vmci_dispatch_dgs, (unsigned long)vmci_dev);
472*4882a593Smuzhiyun 	tasklet_init(&vmci_dev->bm_tasklet,
473*4882a593Smuzhiyun 		     vmci_process_bitmap, (unsigned long)vmci_dev);
474*4882a593Smuzhiyun 
475*4882a593Smuzhiyun 	vmci_dev->data_buffer = vmalloc(VMCI_MAX_DG_SIZE);
476*4882a593Smuzhiyun 	if (!vmci_dev->data_buffer) {
477*4882a593Smuzhiyun 		dev_err(&pdev->dev,
478*4882a593Smuzhiyun 			"Can't allocate memory for datagram buffer\n");
479*4882a593Smuzhiyun 		return -ENOMEM;
480*4882a593Smuzhiyun 	}
481*4882a593Smuzhiyun 
482*4882a593Smuzhiyun 	pci_set_master(pdev);	/* To enable queue_pair functionality. */
483*4882a593Smuzhiyun 
484*4882a593Smuzhiyun 	/*
485*4882a593Smuzhiyun 	 * Verify that the VMCI Device supports the capabilities that
486*4882a593Smuzhiyun 	 * we need. If the device is missing capabilities that we would
487*4882a593Smuzhiyun 	 * like to use, check for fallback capabilities and use those
488*4882a593Smuzhiyun 	 * instead (so we can run a new VM on old hosts). Fail the load if
489*4882a593Smuzhiyun 	 * a required capability is missing and there is no fallback.
490*4882a593Smuzhiyun 	 *
491*4882a593Smuzhiyun 	 * Right now, we need datagrams. There are no fallbacks.
492*4882a593Smuzhiyun 	 */
493*4882a593Smuzhiyun 	capabilities = ioread32(vmci_dev->iobase + VMCI_CAPS_ADDR);
494*4882a593Smuzhiyun 	if (!(capabilities & VMCI_CAPS_DATAGRAM)) {
495*4882a593Smuzhiyun 		dev_err(&pdev->dev, "Device does not support datagrams\n");
496*4882a593Smuzhiyun 		error = -ENXIO;
497*4882a593Smuzhiyun 		goto err_free_data_buffer;
498*4882a593Smuzhiyun 	}
499*4882a593Smuzhiyun 	caps_in_use = VMCI_CAPS_DATAGRAM;
500*4882a593Smuzhiyun 
501*4882a593Smuzhiyun 	/*
502*4882a593Smuzhiyun 	 * Use 64-bit PPNs if the device supports.
503*4882a593Smuzhiyun 	 *
504*4882a593Smuzhiyun 	 * There is no check for the return value of dma_set_mask_and_coherent
505*4882a593Smuzhiyun 	 * since this driver can handle the default mask values if
506*4882a593Smuzhiyun 	 * dma_set_mask_and_coherent fails.
507*4882a593Smuzhiyun 	 */
508*4882a593Smuzhiyun 	if (capabilities & VMCI_CAPS_PPN64) {
509*4882a593Smuzhiyun 		dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
510*4882a593Smuzhiyun 		use_ppn64 = true;
511*4882a593Smuzhiyun 		caps_in_use |= VMCI_CAPS_PPN64;
512*4882a593Smuzhiyun 	} else {
513*4882a593Smuzhiyun 		dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(44));
514*4882a593Smuzhiyun 		use_ppn64 = false;
515*4882a593Smuzhiyun 	}
516*4882a593Smuzhiyun 
517*4882a593Smuzhiyun 	/*
518*4882a593Smuzhiyun 	 * If the hardware supports notifications, we will use that as
519*4882a593Smuzhiyun 	 * well.
520*4882a593Smuzhiyun 	 */
521*4882a593Smuzhiyun 	if (capabilities & VMCI_CAPS_NOTIFICATIONS) {
522*4882a593Smuzhiyun 		vmci_dev->notification_bitmap = dma_alloc_coherent(
523*4882a593Smuzhiyun 			&pdev->dev, PAGE_SIZE, &vmci_dev->notification_base,
524*4882a593Smuzhiyun 			GFP_KERNEL);
525*4882a593Smuzhiyun 		if (!vmci_dev->notification_bitmap) {
526*4882a593Smuzhiyun 			dev_warn(&pdev->dev,
527*4882a593Smuzhiyun 				 "Unable to allocate notification bitmap\n");
528*4882a593Smuzhiyun 		} else {
529*4882a593Smuzhiyun 			memset(vmci_dev->notification_bitmap, 0, PAGE_SIZE);
530*4882a593Smuzhiyun 			caps_in_use |= VMCI_CAPS_NOTIFICATIONS;
531*4882a593Smuzhiyun 		}
532*4882a593Smuzhiyun 	}
533*4882a593Smuzhiyun 
534*4882a593Smuzhiyun 	dev_info(&pdev->dev, "Using capabilities 0x%x\n", caps_in_use);
535*4882a593Smuzhiyun 
536*4882a593Smuzhiyun 	/* Let the host know which capabilities we intend to use. */
537*4882a593Smuzhiyun 	iowrite32(caps_in_use, vmci_dev->iobase + VMCI_CAPS_ADDR);
538*4882a593Smuzhiyun 
539*4882a593Smuzhiyun 	/* Set up global device so that we can start sending datagrams */
540*4882a593Smuzhiyun 	spin_lock_irq(&vmci_dev_spinlock);
541*4882a593Smuzhiyun 	vmci_dev_g = vmci_dev;
542*4882a593Smuzhiyun 	vmci_pdev = pdev;
543*4882a593Smuzhiyun 	spin_unlock_irq(&vmci_dev_spinlock);
544*4882a593Smuzhiyun 
545*4882a593Smuzhiyun 	/*
546*4882a593Smuzhiyun 	 * Register notification bitmap with device if that capability is
547*4882a593Smuzhiyun 	 * used.
548*4882a593Smuzhiyun 	 */
549*4882a593Smuzhiyun 	if (caps_in_use & VMCI_CAPS_NOTIFICATIONS) {
550*4882a593Smuzhiyun 		unsigned long bitmap_ppn =
551*4882a593Smuzhiyun 			vmci_dev->notification_base >> PAGE_SHIFT;
552*4882a593Smuzhiyun 		if (!vmci_dbell_register_notification_bitmap(bitmap_ppn)) {
553*4882a593Smuzhiyun 			dev_warn(&pdev->dev,
554*4882a593Smuzhiyun 				 "VMCI device unable to register notification bitmap with PPN 0x%lx\n",
555*4882a593Smuzhiyun 				 bitmap_ppn);
556*4882a593Smuzhiyun 			error = -ENXIO;
557*4882a593Smuzhiyun 			goto err_remove_vmci_dev_g;
558*4882a593Smuzhiyun 		}
559*4882a593Smuzhiyun 	}
560*4882a593Smuzhiyun 
561*4882a593Smuzhiyun 	/* Check host capabilities. */
562*4882a593Smuzhiyun 	error = vmci_check_host_caps(pdev);
563*4882a593Smuzhiyun 	if (error)
564*4882a593Smuzhiyun 		goto err_remove_bitmap;
565*4882a593Smuzhiyun 
566*4882a593Smuzhiyun 	/* Enable device. */
567*4882a593Smuzhiyun 
568*4882a593Smuzhiyun 	/*
569*4882a593Smuzhiyun 	 * We subscribe to the VMCI_EVENT_CTX_ID_UPDATE here so we can
570*4882a593Smuzhiyun 	 * update the internal context id when needed.
571*4882a593Smuzhiyun 	 */
572*4882a593Smuzhiyun 	vmci_err = vmci_event_subscribe(VMCI_EVENT_CTX_ID_UPDATE,
573*4882a593Smuzhiyun 					vmci_guest_cid_update, NULL,
574*4882a593Smuzhiyun 					&ctx_update_sub_id);
575*4882a593Smuzhiyun 	if (vmci_err < VMCI_SUCCESS)
576*4882a593Smuzhiyun 		dev_warn(&pdev->dev,
577*4882a593Smuzhiyun 			 "Failed to subscribe to event (type=%d): %d\n",
578*4882a593Smuzhiyun 			 VMCI_EVENT_CTX_ID_UPDATE, vmci_err);
579*4882a593Smuzhiyun 
580*4882a593Smuzhiyun 	/*
581*4882a593Smuzhiyun 	 * Enable interrupts.  Try MSI-X first, then MSI, and then fallback on
582*4882a593Smuzhiyun 	 * legacy interrupts.
583*4882a593Smuzhiyun 	 */
584*4882a593Smuzhiyun 	error = pci_alloc_irq_vectors(pdev, VMCI_MAX_INTRS, VMCI_MAX_INTRS,
585*4882a593Smuzhiyun 			PCI_IRQ_MSIX);
586*4882a593Smuzhiyun 	if (error < 0) {
587*4882a593Smuzhiyun 		error = pci_alloc_irq_vectors(pdev, 1, 1,
588*4882a593Smuzhiyun 				PCI_IRQ_MSIX | PCI_IRQ_MSI | PCI_IRQ_LEGACY);
589*4882a593Smuzhiyun 		if (error < 0)
590*4882a593Smuzhiyun 			goto err_remove_bitmap;
591*4882a593Smuzhiyun 	} else {
592*4882a593Smuzhiyun 		vmci_dev->exclusive_vectors = true;
593*4882a593Smuzhiyun 	}
594*4882a593Smuzhiyun 
595*4882a593Smuzhiyun 	/*
596*4882a593Smuzhiyun 	 * Request IRQ for legacy or MSI interrupts, or for first
597*4882a593Smuzhiyun 	 * MSI-X vector.
598*4882a593Smuzhiyun 	 */
599*4882a593Smuzhiyun 	error = request_irq(pci_irq_vector(pdev, 0), vmci_interrupt,
600*4882a593Smuzhiyun 			    IRQF_SHARED, KBUILD_MODNAME, vmci_dev);
601*4882a593Smuzhiyun 	if (error) {
602*4882a593Smuzhiyun 		dev_err(&pdev->dev, "Irq %u in use: %d\n",
603*4882a593Smuzhiyun 			pci_irq_vector(pdev, 0), error);
604*4882a593Smuzhiyun 		goto err_disable_msi;
605*4882a593Smuzhiyun 	}
606*4882a593Smuzhiyun 
607*4882a593Smuzhiyun 	/*
608*4882a593Smuzhiyun 	 * For MSI-X with exclusive vectors we need to request an
609*4882a593Smuzhiyun 	 * interrupt for each vector so that we get a separate
610*4882a593Smuzhiyun 	 * interrupt handler routine.  This allows us to distinguish
611*4882a593Smuzhiyun 	 * between the vectors.
612*4882a593Smuzhiyun 	 */
613*4882a593Smuzhiyun 	if (vmci_dev->exclusive_vectors) {
614*4882a593Smuzhiyun 		error = request_irq(pci_irq_vector(pdev, 1),
615*4882a593Smuzhiyun 				    vmci_interrupt_bm, 0, KBUILD_MODNAME,
616*4882a593Smuzhiyun 				    vmci_dev);
617*4882a593Smuzhiyun 		if (error) {
618*4882a593Smuzhiyun 			dev_err(&pdev->dev,
619*4882a593Smuzhiyun 				"Failed to allocate irq %u: %d\n",
620*4882a593Smuzhiyun 				pci_irq_vector(pdev, 1), error);
621*4882a593Smuzhiyun 			goto err_free_irq;
622*4882a593Smuzhiyun 		}
623*4882a593Smuzhiyun 	}
624*4882a593Smuzhiyun 
625*4882a593Smuzhiyun 	dev_dbg(&pdev->dev, "Registered device\n");
626*4882a593Smuzhiyun 
627*4882a593Smuzhiyun 	atomic_inc(&vmci_num_guest_devices);
628*4882a593Smuzhiyun 
629*4882a593Smuzhiyun 	/* Enable specific interrupt bits. */
630*4882a593Smuzhiyun 	cmd = VMCI_IMR_DATAGRAM;
631*4882a593Smuzhiyun 	if (caps_in_use & VMCI_CAPS_NOTIFICATIONS)
632*4882a593Smuzhiyun 		cmd |= VMCI_IMR_NOTIFICATION;
633*4882a593Smuzhiyun 	iowrite32(cmd, vmci_dev->iobase + VMCI_IMR_ADDR);
634*4882a593Smuzhiyun 
635*4882a593Smuzhiyun 	/* Enable interrupts. */
636*4882a593Smuzhiyun 	iowrite32(VMCI_CONTROL_INT_ENABLE,
637*4882a593Smuzhiyun 		  vmci_dev->iobase + VMCI_CONTROL_ADDR);
638*4882a593Smuzhiyun 
639*4882a593Smuzhiyun 	pci_set_drvdata(pdev, vmci_dev);
640*4882a593Smuzhiyun 
641*4882a593Smuzhiyun 	vmci_call_vsock_callback(false);
642*4882a593Smuzhiyun 	return 0;
643*4882a593Smuzhiyun 
644*4882a593Smuzhiyun err_free_irq:
645*4882a593Smuzhiyun 	free_irq(pci_irq_vector(pdev, 0), vmci_dev);
646*4882a593Smuzhiyun 	tasklet_kill(&vmci_dev->datagram_tasklet);
647*4882a593Smuzhiyun 	tasklet_kill(&vmci_dev->bm_tasklet);
648*4882a593Smuzhiyun 
649*4882a593Smuzhiyun err_disable_msi:
650*4882a593Smuzhiyun 	pci_free_irq_vectors(pdev);
651*4882a593Smuzhiyun 
652*4882a593Smuzhiyun 	vmci_err = vmci_event_unsubscribe(ctx_update_sub_id);
653*4882a593Smuzhiyun 	if (vmci_err < VMCI_SUCCESS)
654*4882a593Smuzhiyun 		dev_warn(&pdev->dev,
655*4882a593Smuzhiyun 			 "Failed to unsubscribe from event (type=%d) with subscriber (ID=0x%x): %d\n",
656*4882a593Smuzhiyun 			 VMCI_EVENT_CTX_ID_UPDATE, ctx_update_sub_id, vmci_err);
657*4882a593Smuzhiyun 
658*4882a593Smuzhiyun err_remove_bitmap:
659*4882a593Smuzhiyun 	if (vmci_dev->notification_bitmap) {
660*4882a593Smuzhiyun 		iowrite32(VMCI_CONTROL_RESET,
661*4882a593Smuzhiyun 			  vmci_dev->iobase + VMCI_CONTROL_ADDR);
662*4882a593Smuzhiyun 		dma_free_coherent(&pdev->dev, PAGE_SIZE,
663*4882a593Smuzhiyun 				  vmci_dev->notification_bitmap,
664*4882a593Smuzhiyun 				  vmci_dev->notification_base);
665*4882a593Smuzhiyun 	}
666*4882a593Smuzhiyun 
667*4882a593Smuzhiyun err_remove_vmci_dev_g:
668*4882a593Smuzhiyun 	spin_lock_irq(&vmci_dev_spinlock);
669*4882a593Smuzhiyun 	vmci_pdev = NULL;
670*4882a593Smuzhiyun 	vmci_dev_g = NULL;
671*4882a593Smuzhiyun 	spin_unlock_irq(&vmci_dev_spinlock);
672*4882a593Smuzhiyun 
673*4882a593Smuzhiyun err_free_data_buffer:
674*4882a593Smuzhiyun 	vfree(vmci_dev->data_buffer);
675*4882a593Smuzhiyun 
676*4882a593Smuzhiyun 	/* The rest are managed resources and will be freed by PCI core */
677*4882a593Smuzhiyun 	return error;
678*4882a593Smuzhiyun }
679*4882a593Smuzhiyun 
vmci_guest_remove_device(struct pci_dev * pdev)680*4882a593Smuzhiyun static void vmci_guest_remove_device(struct pci_dev *pdev)
681*4882a593Smuzhiyun {
682*4882a593Smuzhiyun 	struct vmci_guest_device *vmci_dev = pci_get_drvdata(pdev);
683*4882a593Smuzhiyun 	int vmci_err;
684*4882a593Smuzhiyun 
685*4882a593Smuzhiyun 	dev_dbg(&pdev->dev, "Removing device\n");
686*4882a593Smuzhiyun 
687*4882a593Smuzhiyun 	atomic_dec(&vmci_num_guest_devices);
688*4882a593Smuzhiyun 
689*4882a593Smuzhiyun 	vmci_qp_guest_endpoints_exit();
690*4882a593Smuzhiyun 
691*4882a593Smuzhiyun 	vmci_err = vmci_event_unsubscribe(ctx_update_sub_id);
692*4882a593Smuzhiyun 	if (vmci_err < VMCI_SUCCESS)
693*4882a593Smuzhiyun 		dev_warn(&pdev->dev,
694*4882a593Smuzhiyun 			 "Failed to unsubscribe from event (type=%d) with subscriber (ID=0x%x): %d\n",
695*4882a593Smuzhiyun 			 VMCI_EVENT_CTX_ID_UPDATE, ctx_update_sub_id, vmci_err);
696*4882a593Smuzhiyun 
697*4882a593Smuzhiyun 	spin_lock_irq(&vmci_dev_spinlock);
698*4882a593Smuzhiyun 	vmci_dev_g = NULL;
699*4882a593Smuzhiyun 	vmci_pdev = NULL;
700*4882a593Smuzhiyun 	spin_unlock_irq(&vmci_dev_spinlock);
701*4882a593Smuzhiyun 
702*4882a593Smuzhiyun 	dev_dbg(&pdev->dev, "Resetting vmci device\n");
703*4882a593Smuzhiyun 	iowrite32(VMCI_CONTROL_RESET, vmci_dev->iobase + VMCI_CONTROL_ADDR);
704*4882a593Smuzhiyun 
705*4882a593Smuzhiyun 	/*
706*4882a593Smuzhiyun 	 * Free IRQ and then disable MSI/MSI-X as appropriate.  For
707*4882a593Smuzhiyun 	 * MSI-X, we might have multiple vectors, each with their own
708*4882a593Smuzhiyun 	 * IRQ, which we must free too.
709*4882a593Smuzhiyun 	 */
710*4882a593Smuzhiyun 	if (vmci_dev->exclusive_vectors)
711*4882a593Smuzhiyun 		free_irq(pci_irq_vector(pdev, 1), vmci_dev);
712*4882a593Smuzhiyun 	free_irq(pci_irq_vector(pdev, 0), vmci_dev);
713*4882a593Smuzhiyun 	pci_free_irq_vectors(pdev);
714*4882a593Smuzhiyun 
715*4882a593Smuzhiyun 	tasklet_kill(&vmci_dev->datagram_tasklet);
716*4882a593Smuzhiyun 	tasklet_kill(&vmci_dev->bm_tasklet);
717*4882a593Smuzhiyun 
718*4882a593Smuzhiyun 	if (vmci_dev->notification_bitmap) {
719*4882a593Smuzhiyun 		/*
720*4882a593Smuzhiyun 		 * The device reset above cleared the bitmap state of the
721*4882a593Smuzhiyun 		 * device, so we can safely free it here.
722*4882a593Smuzhiyun 		 */
723*4882a593Smuzhiyun 
724*4882a593Smuzhiyun 		dma_free_coherent(&pdev->dev, PAGE_SIZE,
725*4882a593Smuzhiyun 				  vmci_dev->notification_bitmap,
726*4882a593Smuzhiyun 				  vmci_dev->notification_base);
727*4882a593Smuzhiyun 	}
728*4882a593Smuzhiyun 
729*4882a593Smuzhiyun 	vfree(vmci_dev->data_buffer);
730*4882a593Smuzhiyun 
731*4882a593Smuzhiyun 	/* The rest are managed resources and will be freed by PCI core */
732*4882a593Smuzhiyun }
733*4882a593Smuzhiyun 
734*4882a593Smuzhiyun static const struct pci_device_id vmci_ids[] = {
735*4882a593Smuzhiyun 	{ PCI_DEVICE(PCI_VENDOR_ID_VMWARE, PCI_DEVICE_ID_VMWARE_VMCI), },
736*4882a593Smuzhiyun 	{ 0 },
737*4882a593Smuzhiyun };
738*4882a593Smuzhiyun MODULE_DEVICE_TABLE(pci, vmci_ids);
739*4882a593Smuzhiyun 
740*4882a593Smuzhiyun static struct pci_driver vmci_guest_driver = {
741*4882a593Smuzhiyun 	.name		= KBUILD_MODNAME,
742*4882a593Smuzhiyun 	.id_table	= vmci_ids,
743*4882a593Smuzhiyun 	.probe		= vmci_guest_probe_device,
744*4882a593Smuzhiyun 	.remove		= vmci_guest_remove_device,
745*4882a593Smuzhiyun };
746*4882a593Smuzhiyun 
vmci_guest_init(void)747*4882a593Smuzhiyun int __init vmci_guest_init(void)
748*4882a593Smuzhiyun {
749*4882a593Smuzhiyun 	return pci_register_driver(&vmci_guest_driver);
750*4882a593Smuzhiyun }
751*4882a593Smuzhiyun 
vmci_guest_exit(void)752*4882a593Smuzhiyun void __exit vmci_guest_exit(void)
753*4882a593Smuzhiyun {
754*4882a593Smuzhiyun 	pci_unregister_driver(&vmci_guest_driver);
755*4882a593Smuzhiyun }
756