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