xref: /OK3568_Linux_fs/kernel/drivers/virtio/virtio_pci_common.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-or-later
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * Virtio PCI driver - common functionality for all device versions
4*4882a593Smuzhiyun  *
5*4882a593Smuzhiyun  * This module allows virtio devices to be used over a virtual PCI device.
6*4882a593Smuzhiyun  * This can be used with QEMU based VMMs like KVM or Xen.
7*4882a593Smuzhiyun  *
8*4882a593Smuzhiyun  * Copyright IBM Corp. 2007
9*4882a593Smuzhiyun  * Copyright Red Hat, Inc. 2014
10*4882a593Smuzhiyun  *
11*4882a593Smuzhiyun  * Authors:
12*4882a593Smuzhiyun  *  Anthony Liguori  <aliguori@us.ibm.com>
13*4882a593Smuzhiyun  *  Rusty Russell <rusty@rustcorp.com.au>
14*4882a593Smuzhiyun  *  Michael S. Tsirkin <mst@redhat.com>
15*4882a593Smuzhiyun  */
16*4882a593Smuzhiyun 
17*4882a593Smuzhiyun #include "virtio_pci_common.h"
18*4882a593Smuzhiyun 
19*4882a593Smuzhiyun static bool force_legacy = false;
20*4882a593Smuzhiyun 
21*4882a593Smuzhiyun #if IS_ENABLED(CONFIG_VIRTIO_PCI_LEGACY)
22*4882a593Smuzhiyun module_param(force_legacy, bool, 0444);
23*4882a593Smuzhiyun MODULE_PARM_DESC(force_legacy,
24*4882a593Smuzhiyun 		 "Force legacy mode for transitional virtio 1 devices");
25*4882a593Smuzhiyun #endif
26*4882a593Smuzhiyun 
27*4882a593Smuzhiyun /* wait for pending irq handlers */
vp_synchronize_vectors(struct virtio_device * vdev)28*4882a593Smuzhiyun void vp_synchronize_vectors(struct virtio_device *vdev)
29*4882a593Smuzhiyun {
30*4882a593Smuzhiyun 	struct virtio_pci_device *vp_dev = to_vp_device(vdev);
31*4882a593Smuzhiyun 	int i;
32*4882a593Smuzhiyun 
33*4882a593Smuzhiyun 	if (vp_dev->intx_enabled)
34*4882a593Smuzhiyun 		synchronize_irq(vp_dev->pci_dev->irq);
35*4882a593Smuzhiyun 
36*4882a593Smuzhiyun 	for (i = 0; i < vp_dev->msix_vectors; ++i)
37*4882a593Smuzhiyun 		synchronize_irq(pci_irq_vector(vp_dev->pci_dev, i));
38*4882a593Smuzhiyun }
39*4882a593Smuzhiyun 
40*4882a593Smuzhiyun /* the notify function used when creating a virt queue */
vp_notify(struct virtqueue * vq)41*4882a593Smuzhiyun bool vp_notify(struct virtqueue *vq)
42*4882a593Smuzhiyun {
43*4882a593Smuzhiyun 	/* we write the queue's selector into the notification register to
44*4882a593Smuzhiyun 	 * signal the other end */
45*4882a593Smuzhiyun 	iowrite16(vq->index, (void __iomem *)vq->priv);
46*4882a593Smuzhiyun 	return true;
47*4882a593Smuzhiyun }
48*4882a593Smuzhiyun 
49*4882a593Smuzhiyun /* Handle a configuration change: Tell driver if it wants to know. */
vp_config_changed(int irq,void * opaque)50*4882a593Smuzhiyun static irqreturn_t vp_config_changed(int irq, void *opaque)
51*4882a593Smuzhiyun {
52*4882a593Smuzhiyun 	struct virtio_pci_device *vp_dev = opaque;
53*4882a593Smuzhiyun 
54*4882a593Smuzhiyun 	virtio_config_changed(&vp_dev->vdev);
55*4882a593Smuzhiyun 	return IRQ_HANDLED;
56*4882a593Smuzhiyun }
57*4882a593Smuzhiyun 
58*4882a593Smuzhiyun /* Notify all virtqueues on an interrupt. */
vp_vring_interrupt(int irq,void * opaque)59*4882a593Smuzhiyun static irqreturn_t vp_vring_interrupt(int irq, void *opaque)
60*4882a593Smuzhiyun {
61*4882a593Smuzhiyun 	struct virtio_pci_device *vp_dev = opaque;
62*4882a593Smuzhiyun 	struct virtio_pci_vq_info *info;
63*4882a593Smuzhiyun 	irqreturn_t ret = IRQ_NONE;
64*4882a593Smuzhiyun 	unsigned long flags;
65*4882a593Smuzhiyun 
66*4882a593Smuzhiyun 	spin_lock_irqsave(&vp_dev->lock, flags);
67*4882a593Smuzhiyun 	list_for_each_entry(info, &vp_dev->virtqueues, node) {
68*4882a593Smuzhiyun 		if (vring_interrupt(irq, info->vq) == IRQ_HANDLED)
69*4882a593Smuzhiyun 			ret = IRQ_HANDLED;
70*4882a593Smuzhiyun 	}
71*4882a593Smuzhiyun 	spin_unlock_irqrestore(&vp_dev->lock, flags);
72*4882a593Smuzhiyun 
73*4882a593Smuzhiyun 	return ret;
74*4882a593Smuzhiyun }
75*4882a593Smuzhiyun 
76*4882a593Smuzhiyun /* A small wrapper to also acknowledge the interrupt when it's handled.
77*4882a593Smuzhiyun  * I really need an EIO hook for the vring so I can ack the interrupt once we
78*4882a593Smuzhiyun  * know that we'll be handling the IRQ but before we invoke the callback since
79*4882a593Smuzhiyun  * the callback may notify the host which results in the host attempting to
80*4882a593Smuzhiyun  * raise an interrupt that we would then mask once we acknowledged the
81*4882a593Smuzhiyun  * interrupt. */
vp_interrupt(int irq,void * opaque)82*4882a593Smuzhiyun static irqreturn_t vp_interrupt(int irq, void *opaque)
83*4882a593Smuzhiyun {
84*4882a593Smuzhiyun 	struct virtio_pci_device *vp_dev = opaque;
85*4882a593Smuzhiyun 	u8 isr;
86*4882a593Smuzhiyun 
87*4882a593Smuzhiyun 	/* reading the ISR has the effect of also clearing it so it's very
88*4882a593Smuzhiyun 	 * important to save off the value. */
89*4882a593Smuzhiyun 	isr = ioread8(vp_dev->isr);
90*4882a593Smuzhiyun 
91*4882a593Smuzhiyun 	/* It's definitely not us if the ISR was not high */
92*4882a593Smuzhiyun 	if (!isr)
93*4882a593Smuzhiyun 		return IRQ_NONE;
94*4882a593Smuzhiyun 
95*4882a593Smuzhiyun 	/* Configuration change?  Tell driver if it wants to know. */
96*4882a593Smuzhiyun 	if (isr & VIRTIO_PCI_ISR_CONFIG)
97*4882a593Smuzhiyun 		vp_config_changed(irq, opaque);
98*4882a593Smuzhiyun 
99*4882a593Smuzhiyun 	return vp_vring_interrupt(irq, opaque);
100*4882a593Smuzhiyun }
101*4882a593Smuzhiyun 
vp_request_msix_vectors(struct virtio_device * vdev,int nvectors,bool per_vq_vectors,struct irq_affinity * desc)102*4882a593Smuzhiyun static int vp_request_msix_vectors(struct virtio_device *vdev, int nvectors,
103*4882a593Smuzhiyun 				   bool per_vq_vectors, struct irq_affinity *desc)
104*4882a593Smuzhiyun {
105*4882a593Smuzhiyun 	struct virtio_pci_device *vp_dev = to_vp_device(vdev);
106*4882a593Smuzhiyun 	const char *name = dev_name(&vp_dev->vdev.dev);
107*4882a593Smuzhiyun 	unsigned flags = PCI_IRQ_MSIX;
108*4882a593Smuzhiyun 	unsigned i, v;
109*4882a593Smuzhiyun 	int err = -ENOMEM;
110*4882a593Smuzhiyun 
111*4882a593Smuzhiyun 	vp_dev->msix_vectors = nvectors;
112*4882a593Smuzhiyun 
113*4882a593Smuzhiyun 	vp_dev->msix_names = kmalloc_array(nvectors,
114*4882a593Smuzhiyun 					   sizeof(*vp_dev->msix_names),
115*4882a593Smuzhiyun 					   GFP_KERNEL);
116*4882a593Smuzhiyun 	if (!vp_dev->msix_names)
117*4882a593Smuzhiyun 		goto error;
118*4882a593Smuzhiyun 	vp_dev->msix_affinity_masks
119*4882a593Smuzhiyun 		= kcalloc(nvectors, sizeof(*vp_dev->msix_affinity_masks),
120*4882a593Smuzhiyun 			  GFP_KERNEL);
121*4882a593Smuzhiyun 	if (!vp_dev->msix_affinity_masks)
122*4882a593Smuzhiyun 		goto error;
123*4882a593Smuzhiyun 	for (i = 0; i < nvectors; ++i)
124*4882a593Smuzhiyun 		if (!alloc_cpumask_var(&vp_dev->msix_affinity_masks[i],
125*4882a593Smuzhiyun 					GFP_KERNEL))
126*4882a593Smuzhiyun 			goto error;
127*4882a593Smuzhiyun 
128*4882a593Smuzhiyun 	if (desc) {
129*4882a593Smuzhiyun 		flags |= PCI_IRQ_AFFINITY;
130*4882a593Smuzhiyun 		desc->pre_vectors++; /* virtio config vector */
131*4882a593Smuzhiyun 	}
132*4882a593Smuzhiyun 
133*4882a593Smuzhiyun 	err = pci_alloc_irq_vectors_affinity(vp_dev->pci_dev, nvectors,
134*4882a593Smuzhiyun 					     nvectors, flags, desc);
135*4882a593Smuzhiyun 	if (err < 0)
136*4882a593Smuzhiyun 		goto error;
137*4882a593Smuzhiyun 	vp_dev->msix_enabled = 1;
138*4882a593Smuzhiyun 
139*4882a593Smuzhiyun 	/* Set the vector used for configuration */
140*4882a593Smuzhiyun 	v = vp_dev->msix_used_vectors;
141*4882a593Smuzhiyun 	snprintf(vp_dev->msix_names[v], sizeof *vp_dev->msix_names,
142*4882a593Smuzhiyun 		 "%s-config", name);
143*4882a593Smuzhiyun 	err = request_irq(pci_irq_vector(vp_dev->pci_dev, v),
144*4882a593Smuzhiyun 			  vp_config_changed, 0, vp_dev->msix_names[v],
145*4882a593Smuzhiyun 			  vp_dev);
146*4882a593Smuzhiyun 	if (err)
147*4882a593Smuzhiyun 		goto error;
148*4882a593Smuzhiyun 	++vp_dev->msix_used_vectors;
149*4882a593Smuzhiyun 
150*4882a593Smuzhiyun 	v = vp_dev->config_vector(vp_dev, v);
151*4882a593Smuzhiyun 	/* Verify we had enough resources to assign the vector */
152*4882a593Smuzhiyun 	if (v == VIRTIO_MSI_NO_VECTOR) {
153*4882a593Smuzhiyun 		err = -EBUSY;
154*4882a593Smuzhiyun 		goto error;
155*4882a593Smuzhiyun 	}
156*4882a593Smuzhiyun 
157*4882a593Smuzhiyun 	if (!per_vq_vectors) {
158*4882a593Smuzhiyun 		/* Shared vector for all VQs */
159*4882a593Smuzhiyun 		v = vp_dev->msix_used_vectors;
160*4882a593Smuzhiyun 		snprintf(vp_dev->msix_names[v], sizeof *vp_dev->msix_names,
161*4882a593Smuzhiyun 			 "%s-virtqueues", name);
162*4882a593Smuzhiyun 		err = request_irq(pci_irq_vector(vp_dev->pci_dev, v),
163*4882a593Smuzhiyun 				  vp_vring_interrupt, 0, vp_dev->msix_names[v],
164*4882a593Smuzhiyun 				  vp_dev);
165*4882a593Smuzhiyun 		if (err)
166*4882a593Smuzhiyun 			goto error;
167*4882a593Smuzhiyun 		++vp_dev->msix_used_vectors;
168*4882a593Smuzhiyun 	}
169*4882a593Smuzhiyun 	return 0;
170*4882a593Smuzhiyun error:
171*4882a593Smuzhiyun 	return err;
172*4882a593Smuzhiyun }
173*4882a593Smuzhiyun 
vp_setup_vq(struct virtio_device * vdev,unsigned index,void (* callback)(struct virtqueue * vq),const char * name,bool ctx,u16 msix_vec)174*4882a593Smuzhiyun static struct virtqueue *vp_setup_vq(struct virtio_device *vdev, unsigned index,
175*4882a593Smuzhiyun 				     void (*callback)(struct virtqueue *vq),
176*4882a593Smuzhiyun 				     const char *name,
177*4882a593Smuzhiyun 				     bool ctx,
178*4882a593Smuzhiyun 				     u16 msix_vec)
179*4882a593Smuzhiyun {
180*4882a593Smuzhiyun 	struct virtio_pci_device *vp_dev = to_vp_device(vdev);
181*4882a593Smuzhiyun 	struct virtio_pci_vq_info *info = kmalloc(sizeof *info, GFP_KERNEL);
182*4882a593Smuzhiyun 	struct virtqueue *vq;
183*4882a593Smuzhiyun 	unsigned long flags;
184*4882a593Smuzhiyun 
185*4882a593Smuzhiyun 	/* fill out our structure that represents an active queue */
186*4882a593Smuzhiyun 	if (!info)
187*4882a593Smuzhiyun 		return ERR_PTR(-ENOMEM);
188*4882a593Smuzhiyun 
189*4882a593Smuzhiyun 	vq = vp_dev->setup_vq(vp_dev, info, index, callback, name, ctx,
190*4882a593Smuzhiyun 			      msix_vec);
191*4882a593Smuzhiyun 	if (IS_ERR(vq))
192*4882a593Smuzhiyun 		goto out_info;
193*4882a593Smuzhiyun 
194*4882a593Smuzhiyun 	info->vq = vq;
195*4882a593Smuzhiyun 	if (callback) {
196*4882a593Smuzhiyun 		spin_lock_irqsave(&vp_dev->lock, flags);
197*4882a593Smuzhiyun 		list_add(&info->node, &vp_dev->virtqueues);
198*4882a593Smuzhiyun 		spin_unlock_irqrestore(&vp_dev->lock, flags);
199*4882a593Smuzhiyun 	} else {
200*4882a593Smuzhiyun 		INIT_LIST_HEAD(&info->node);
201*4882a593Smuzhiyun 	}
202*4882a593Smuzhiyun 
203*4882a593Smuzhiyun 	vp_dev->vqs[index] = info;
204*4882a593Smuzhiyun 	return vq;
205*4882a593Smuzhiyun 
206*4882a593Smuzhiyun out_info:
207*4882a593Smuzhiyun 	kfree(info);
208*4882a593Smuzhiyun 	return vq;
209*4882a593Smuzhiyun }
210*4882a593Smuzhiyun 
vp_del_vq(struct virtqueue * vq)211*4882a593Smuzhiyun static void vp_del_vq(struct virtqueue *vq)
212*4882a593Smuzhiyun {
213*4882a593Smuzhiyun 	struct virtio_pci_device *vp_dev = to_vp_device(vq->vdev);
214*4882a593Smuzhiyun 	struct virtio_pci_vq_info *info = vp_dev->vqs[vq->index];
215*4882a593Smuzhiyun 	unsigned long flags;
216*4882a593Smuzhiyun 
217*4882a593Smuzhiyun 	spin_lock_irqsave(&vp_dev->lock, flags);
218*4882a593Smuzhiyun 	list_del(&info->node);
219*4882a593Smuzhiyun 	spin_unlock_irqrestore(&vp_dev->lock, flags);
220*4882a593Smuzhiyun 
221*4882a593Smuzhiyun 	vp_dev->del_vq(info);
222*4882a593Smuzhiyun 	kfree(info);
223*4882a593Smuzhiyun }
224*4882a593Smuzhiyun 
225*4882a593Smuzhiyun /* the config->del_vqs() implementation */
vp_del_vqs(struct virtio_device * vdev)226*4882a593Smuzhiyun void vp_del_vqs(struct virtio_device *vdev)
227*4882a593Smuzhiyun {
228*4882a593Smuzhiyun 	struct virtio_pci_device *vp_dev = to_vp_device(vdev);
229*4882a593Smuzhiyun 	struct virtqueue *vq, *n;
230*4882a593Smuzhiyun 	int i;
231*4882a593Smuzhiyun 
232*4882a593Smuzhiyun 	list_for_each_entry_safe(vq, n, &vdev->vqs, list) {
233*4882a593Smuzhiyun 		if (vp_dev->per_vq_vectors) {
234*4882a593Smuzhiyun 			int v = vp_dev->vqs[vq->index]->msix_vector;
235*4882a593Smuzhiyun 
236*4882a593Smuzhiyun 			if (v != VIRTIO_MSI_NO_VECTOR) {
237*4882a593Smuzhiyun 				int irq = pci_irq_vector(vp_dev->pci_dev, v);
238*4882a593Smuzhiyun 
239*4882a593Smuzhiyun 				irq_set_affinity_hint(irq, NULL);
240*4882a593Smuzhiyun 				free_irq(irq, vq);
241*4882a593Smuzhiyun 			}
242*4882a593Smuzhiyun 		}
243*4882a593Smuzhiyun 		vp_del_vq(vq);
244*4882a593Smuzhiyun 	}
245*4882a593Smuzhiyun 	vp_dev->per_vq_vectors = false;
246*4882a593Smuzhiyun 
247*4882a593Smuzhiyun 	if (vp_dev->intx_enabled) {
248*4882a593Smuzhiyun 		free_irq(vp_dev->pci_dev->irq, vp_dev);
249*4882a593Smuzhiyun 		vp_dev->intx_enabled = 0;
250*4882a593Smuzhiyun 	}
251*4882a593Smuzhiyun 
252*4882a593Smuzhiyun 	for (i = 0; i < vp_dev->msix_used_vectors; ++i)
253*4882a593Smuzhiyun 		free_irq(pci_irq_vector(vp_dev->pci_dev, i), vp_dev);
254*4882a593Smuzhiyun 
255*4882a593Smuzhiyun 	if (vp_dev->msix_affinity_masks) {
256*4882a593Smuzhiyun 		for (i = 0; i < vp_dev->msix_vectors; i++)
257*4882a593Smuzhiyun 			free_cpumask_var(vp_dev->msix_affinity_masks[i]);
258*4882a593Smuzhiyun 	}
259*4882a593Smuzhiyun 
260*4882a593Smuzhiyun 	if (vp_dev->msix_enabled) {
261*4882a593Smuzhiyun 		/* Disable the vector used for configuration */
262*4882a593Smuzhiyun 		vp_dev->config_vector(vp_dev, VIRTIO_MSI_NO_VECTOR);
263*4882a593Smuzhiyun 
264*4882a593Smuzhiyun 		pci_free_irq_vectors(vp_dev->pci_dev);
265*4882a593Smuzhiyun 		vp_dev->msix_enabled = 0;
266*4882a593Smuzhiyun 	}
267*4882a593Smuzhiyun 
268*4882a593Smuzhiyun 	vp_dev->msix_vectors = 0;
269*4882a593Smuzhiyun 	vp_dev->msix_used_vectors = 0;
270*4882a593Smuzhiyun 	kfree(vp_dev->msix_names);
271*4882a593Smuzhiyun 	vp_dev->msix_names = NULL;
272*4882a593Smuzhiyun 	kfree(vp_dev->msix_affinity_masks);
273*4882a593Smuzhiyun 	vp_dev->msix_affinity_masks = NULL;
274*4882a593Smuzhiyun 	kfree(vp_dev->vqs);
275*4882a593Smuzhiyun 	vp_dev->vqs = NULL;
276*4882a593Smuzhiyun }
277*4882a593Smuzhiyun 
vp_find_vqs_msix(struct virtio_device * vdev,unsigned nvqs,struct virtqueue * vqs[],vq_callback_t * callbacks[],const char * const names[],bool per_vq_vectors,const bool * ctx,struct irq_affinity * desc)278*4882a593Smuzhiyun static int vp_find_vqs_msix(struct virtio_device *vdev, unsigned nvqs,
279*4882a593Smuzhiyun 		struct virtqueue *vqs[], vq_callback_t *callbacks[],
280*4882a593Smuzhiyun 		const char * const names[], bool per_vq_vectors,
281*4882a593Smuzhiyun 		const bool *ctx,
282*4882a593Smuzhiyun 		struct irq_affinity *desc)
283*4882a593Smuzhiyun {
284*4882a593Smuzhiyun 	struct virtio_pci_device *vp_dev = to_vp_device(vdev);
285*4882a593Smuzhiyun 	u16 msix_vec;
286*4882a593Smuzhiyun 	int i, err, nvectors, allocated_vectors, queue_idx = 0;
287*4882a593Smuzhiyun 
288*4882a593Smuzhiyun 	vp_dev->vqs = kcalloc(nvqs, sizeof(*vp_dev->vqs), GFP_KERNEL);
289*4882a593Smuzhiyun 	if (!vp_dev->vqs)
290*4882a593Smuzhiyun 		return -ENOMEM;
291*4882a593Smuzhiyun 
292*4882a593Smuzhiyun 	if (per_vq_vectors) {
293*4882a593Smuzhiyun 		/* Best option: one for change interrupt, one per vq. */
294*4882a593Smuzhiyun 		nvectors = 1;
295*4882a593Smuzhiyun 		for (i = 0; i < nvqs; ++i)
296*4882a593Smuzhiyun 			if (names[i] && callbacks[i])
297*4882a593Smuzhiyun 				++nvectors;
298*4882a593Smuzhiyun 	} else {
299*4882a593Smuzhiyun 		/* Second best: one for change, shared for all vqs. */
300*4882a593Smuzhiyun 		nvectors = 2;
301*4882a593Smuzhiyun 	}
302*4882a593Smuzhiyun 
303*4882a593Smuzhiyun 	err = vp_request_msix_vectors(vdev, nvectors, per_vq_vectors,
304*4882a593Smuzhiyun 				      per_vq_vectors ? desc : NULL);
305*4882a593Smuzhiyun 	if (err)
306*4882a593Smuzhiyun 		goto error_find;
307*4882a593Smuzhiyun 
308*4882a593Smuzhiyun 	vp_dev->per_vq_vectors = per_vq_vectors;
309*4882a593Smuzhiyun 	allocated_vectors = vp_dev->msix_used_vectors;
310*4882a593Smuzhiyun 	for (i = 0; i < nvqs; ++i) {
311*4882a593Smuzhiyun 		if (!names[i]) {
312*4882a593Smuzhiyun 			vqs[i] = NULL;
313*4882a593Smuzhiyun 			continue;
314*4882a593Smuzhiyun 		}
315*4882a593Smuzhiyun 
316*4882a593Smuzhiyun 		if (!callbacks[i])
317*4882a593Smuzhiyun 			msix_vec = VIRTIO_MSI_NO_VECTOR;
318*4882a593Smuzhiyun 		else if (vp_dev->per_vq_vectors)
319*4882a593Smuzhiyun 			msix_vec = allocated_vectors++;
320*4882a593Smuzhiyun 		else
321*4882a593Smuzhiyun 			msix_vec = VP_MSIX_VQ_VECTOR;
322*4882a593Smuzhiyun 		vqs[i] = vp_setup_vq(vdev, queue_idx++, callbacks[i], names[i],
323*4882a593Smuzhiyun 				     ctx ? ctx[i] : false,
324*4882a593Smuzhiyun 				     msix_vec);
325*4882a593Smuzhiyun 		if (IS_ERR(vqs[i])) {
326*4882a593Smuzhiyun 			err = PTR_ERR(vqs[i]);
327*4882a593Smuzhiyun 			goto error_find;
328*4882a593Smuzhiyun 		}
329*4882a593Smuzhiyun 
330*4882a593Smuzhiyun 		if (!vp_dev->per_vq_vectors || msix_vec == VIRTIO_MSI_NO_VECTOR)
331*4882a593Smuzhiyun 			continue;
332*4882a593Smuzhiyun 
333*4882a593Smuzhiyun 		/* allocate per-vq irq if available and necessary */
334*4882a593Smuzhiyun 		snprintf(vp_dev->msix_names[msix_vec],
335*4882a593Smuzhiyun 			 sizeof *vp_dev->msix_names,
336*4882a593Smuzhiyun 			 "%s-%s",
337*4882a593Smuzhiyun 			 dev_name(&vp_dev->vdev.dev), names[i]);
338*4882a593Smuzhiyun 		err = request_irq(pci_irq_vector(vp_dev->pci_dev, msix_vec),
339*4882a593Smuzhiyun 				  vring_interrupt, 0,
340*4882a593Smuzhiyun 				  vp_dev->msix_names[msix_vec],
341*4882a593Smuzhiyun 				  vqs[i]);
342*4882a593Smuzhiyun 		if (err)
343*4882a593Smuzhiyun 			goto error_find;
344*4882a593Smuzhiyun 	}
345*4882a593Smuzhiyun 	return 0;
346*4882a593Smuzhiyun 
347*4882a593Smuzhiyun error_find:
348*4882a593Smuzhiyun 	vp_del_vqs(vdev);
349*4882a593Smuzhiyun 	return err;
350*4882a593Smuzhiyun }
351*4882a593Smuzhiyun 
vp_find_vqs_intx(struct virtio_device * vdev,unsigned nvqs,struct virtqueue * vqs[],vq_callback_t * callbacks[],const char * const names[],const bool * ctx)352*4882a593Smuzhiyun static int vp_find_vqs_intx(struct virtio_device *vdev, unsigned nvqs,
353*4882a593Smuzhiyun 		struct virtqueue *vqs[], vq_callback_t *callbacks[],
354*4882a593Smuzhiyun 		const char * const names[], const bool *ctx)
355*4882a593Smuzhiyun {
356*4882a593Smuzhiyun 	struct virtio_pci_device *vp_dev = to_vp_device(vdev);
357*4882a593Smuzhiyun 	int i, err, queue_idx = 0;
358*4882a593Smuzhiyun 
359*4882a593Smuzhiyun 	vp_dev->vqs = kcalloc(nvqs, sizeof(*vp_dev->vqs), GFP_KERNEL);
360*4882a593Smuzhiyun 	if (!vp_dev->vqs)
361*4882a593Smuzhiyun 		return -ENOMEM;
362*4882a593Smuzhiyun 
363*4882a593Smuzhiyun 	err = request_irq(vp_dev->pci_dev->irq, vp_interrupt, IRQF_SHARED,
364*4882a593Smuzhiyun 			dev_name(&vdev->dev), vp_dev);
365*4882a593Smuzhiyun 	if (err)
366*4882a593Smuzhiyun 		goto out_del_vqs;
367*4882a593Smuzhiyun 
368*4882a593Smuzhiyun 	vp_dev->intx_enabled = 1;
369*4882a593Smuzhiyun 	vp_dev->per_vq_vectors = false;
370*4882a593Smuzhiyun 	for (i = 0; i < nvqs; ++i) {
371*4882a593Smuzhiyun 		if (!names[i]) {
372*4882a593Smuzhiyun 			vqs[i] = NULL;
373*4882a593Smuzhiyun 			continue;
374*4882a593Smuzhiyun 		}
375*4882a593Smuzhiyun 		vqs[i] = vp_setup_vq(vdev, queue_idx++, callbacks[i], names[i],
376*4882a593Smuzhiyun 				     ctx ? ctx[i] : false,
377*4882a593Smuzhiyun 				     VIRTIO_MSI_NO_VECTOR);
378*4882a593Smuzhiyun 		if (IS_ERR(vqs[i])) {
379*4882a593Smuzhiyun 			err = PTR_ERR(vqs[i]);
380*4882a593Smuzhiyun 			goto out_del_vqs;
381*4882a593Smuzhiyun 		}
382*4882a593Smuzhiyun 	}
383*4882a593Smuzhiyun 
384*4882a593Smuzhiyun 	return 0;
385*4882a593Smuzhiyun out_del_vqs:
386*4882a593Smuzhiyun 	vp_del_vqs(vdev);
387*4882a593Smuzhiyun 	return err;
388*4882a593Smuzhiyun }
389*4882a593Smuzhiyun 
390*4882a593Smuzhiyun /* the config->find_vqs() implementation */
vp_find_vqs(struct virtio_device * vdev,unsigned nvqs,struct virtqueue * vqs[],vq_callback_t * callbacks[],const char * const names[],const bool * ctx,struct irq_affinity * desc)391*4882a593Smuzhiyun int vp_find_vqs(struct virtio_device *vdev, unsigned nvqs,
392*4882a593Smuzhiyun 		struct virtqueue *vqs[], vq_callback_t *callbacks[],
393*4882a593Smuzhiyun 		const char * const names[], const bool *ctx,
394*4882a593Smuzhiyun 		struct irq_affinity *desc)
395*4882a593Smuzhiyun {
396*4882a593Smuzhiyun 	int err;
397*4882a593Smuzhiyun 
398*4882a593Smuzhiyun 	/* Try MSI-X with one vector per queue. */
399*4882a593Smuzhiyun 	err = vp_find_vqs_msix(vdev, nvqs, vqs, callbacks, names, true, ctx, desc);
400*4882a593Smuzhiyun 	if (!err)
401*4882a593Smuzhiyun 		return 0;
402*4882a593Smuzhiyun 	/* Fallback: MSI-X with one vector for config, one shared for queues. */
403*4882a593Smuzhiyun 	err = vp_find_vqs_msix(vdev, nvqs, vqs, callbacks, names, false, ctx, desc);
404*4882a593Smuzhiyun 	if (!err)
405*4882a593Smuzhiyun 		return 0;
406*4882a593Smuzhiyun 	/* Finally fall back to regular interrupts. */
407*4882a593Smuzhiyun 	return vp_find_vqs_intx(vdev, nvqs, vqs, callbacks, names, ctx);
408*4882a593Smuzhiyun }
409*4882a593Smuzhiyun 
vp_bus_name(struct virtio_device * vdev)410*4882a593Smuzhiyun const char *vp_bus_name(struct virtio_device *vdev)
411*4882a593Smuzhiyun {
412*4882a593Smuzhiyun 	struct virtio_pci_device *vp_dev = to_vp_device(vdev);
413*4882a593Smuzhiyun 
414*4882a593Smuzhiyun 	return pci_name(vp_dev->pci_dev);
415*4882a593Smuzhiyun }
416*4882a593Smuzhiyun 
417*4882a593Smuzhiyun /* Setup the affinity for a virtqueue:
418*4882a593Smuzhiyun  * - force the affinity for per vq vector
419*4882a593Smuzhiyun  * - OR over all affinities for shared MSI
420*4882a593Smuzhiyun  * - ignore the affinity request if we're using INTX
421*4882a593Smuzhiyun  */
vp_set_vq_affinity(struct virtqueue * vq,const struct cpumask * cpu_mask)422*4882a593Smuzhiyun int vp_set_vq_affinity(struct virtqueue *vq, const struct cpumask *cpu_mask)
423*4882a593Smuzhiyun {
424*4882a593Smuzhiyun 	struct virtio_device *vdev = vq->vdev;
425*4882a593Smuzhiyun 	struct virtio_pci_device *vp_dev = to_vp_device(vdev);
426*4882a593Smuzhiyun 	struct virtio_pci_vq_info *info = vp_dev->vqs[vq->index];
427*4882a593Smuzhiyun 	struct cpumask *mask;
428*4882a593Smuzhiyun 	unsigned int irq;
429*4882a593Smuzhiyun 
430*4882a593Smuzhiyun 	if (!vq->callback)
431*4882a593Smuzhiyun 		return -EINVAL;
432*4882a593Smuzhiyun 
433*4882a593Smuzhiyun 	if (vp_dev->msix_enabled) {
434*4882a593Smuzhiyun 		mask = vp_dev->msix_affinity_masks[info->msix_vector];
435*4882a593Smuzhiyun 		irq = pci_irq_vector(vp_dev->pci_dev, info->msix_vector);
436*4882a593Smuzhiyun 		if (!cpu_mask)
437*4882a593Smuzhiyun 			irq_set_affinity_hint(irq, NULL);
438*4882a593Smuzhiyun 		else {
439*4882a593Smuzhiyun 			cpumask_copy(mask, cpu_mask);
440*4882a593Smuzhiyun 			irq_set_affinity_hint(irq, mask);
441*4882a593Smuzhiyun 		}
442*4882a593Smuzhiyun 	}
443*4882a593Smuzhiyun 	return 0;
444*4882a593Smuzhiyun }
445*4882a593Smuzhiyun 
vp_get_vq_affinity(struct virtio_device * vdev,int index)446*4882a593Smuzhiyun const struct cpumask *vp_get_vq_affinity(struct virtio_device *vdev, int index)
447*4882a593Smuzhiyun {
448*4882a593Smuzhiyun 	struct virtio_pci_device *vp_dev = to_vp_device(vdev);
449*4882a593Smuzhiyun 
450*4882a593Smuzhiyun 	if (!vp_dev->per_vq_vectors ||
451*4882a593Smuzhiyun 	    vp_dev->vqs[index]->msix_vector == VIRTIO_MSI_NO_VECTOR)
452*4882a593Smuzhiyun 		return NULL;
453*4882a593Smuzhiyun 
454*4882a593Smuzhiyun 	return pci_irq_get_affinity(vp_dev->pci_dev,
455*4882a593Smuzhiyun 				    vp_dev->vqs[index]->msix_vector);
456*4882a593Smuzhiyun }
457*4882a593Smuzhiyun 
458*4882a593Smuzhiyun #ifdef CONFIG_PM_SLEEP
virtio_pci_freeze(struct device * dev)459*4882a593Smuzhiyun static int virtio_pci_freeze(struct device *dev)
460*4882a593Smuzhiyun {
461*4882a593Smuzhiyun 	struct pci_dev *pci_dev = to_pci_dev(dev);
462*4882a593Smuzhiyun 	struct virtio_pci_device *vp_dev = pci_get_drvdata(pci_dev);
463*4882a593Smuzhiyun 	int ret;
464*4882a593Smuzhiyun 
465*4882a593Smuzhiyun 	ret = virtio_device_freeze(&vp_dev->vdev);
466*4882a593Smuzhiyun 
467*4882a593Smuzhiyun 	if (!ret)
468*4882a593Smuzhiyun 		pci_disable_device(pci_dev);
469*4882a593Smuzhiyun 	return ret;
470*4882a593Smuzhiyun }
471*4882a593Smuzhiyun 
virtio_pci_restore(struct device * dev)472*4882a593Smuzhiyun static int virtio_pci_restore(struct device *dev)
473*4882a593Smuzhiyun {
474*4882a593Smuzhiyun 	struct pci_dev *pci_dev = to_pci_dev(dev);
475*4882a593Smuzhiyun 	struct virtio_pci_device *vp_dev = pci_get_drvdata(pci_dev);
476*4882a593Smuzhiyun 	int ret;
477*4882a593Smuzhiyun 
478*4882a593Smuzhiyun 	ret = pci_enable_device(pci_dev);
479*4882a593Smuzhiyun 	if (ret)
480*4882a593Smuzhiyun 		return ret;
481*4882a593Smuzhiyun 
482*4882a593Smuzhiyun 	pci_set_master(pci_dev);
483*4882a593Smuzhiyun 	return virtio_device_restore(&vp_dev->vdev);
484*4882a593Smuzhiyun }
485*4882a593Smuzhiyun 
486*4882a593Smuzhiyun static const struct dev_pm_ops virtio_pci_pm_ops = {
487*4882a593Smuzhiyun 	SET_SYSTEM_SLEEP_PM_OPS(virtio_pci_freeze, virtio_pci_restore)
488*4882a593Smuzhiyun };
489*4882a593Smuzhiyun #endif
490*4882a593Smuzhiyun 
491*4882a593Smuzhiyun 
492*4882a593Smuzhiyun /* Qumranet donated their vendor ID for devices 0x1000 thru 0x10FF. */
493*4882a593Smuzhiyun static const struct pci_device_id virtio_pci_id_table[] = {
494*4882a593Smuzhiyun 	{ PCI_DEVICE(PCI_VENDOR_ID_REDHAT_QUMRANET, PCI_ANY_ID) },
495*4882a593Smuzhiyun 	{ 0 }
496*4882a593Smuzhiyun };
497*4882a593Smuzhiyun 
498*4882a593Smuzhiyun MODULE_DEVICE_TABLE(pci, virtio_pci_id_table);
499*4882a593Smuzhiyun 
virtio_pci_release_dev(struct device * _d)500*4882a593Smuzhiyun static void virtio_pci_release_dev(struct device *_d)
501*4882a593Smuzhiyun {
502*4882a593Smuzhiyun 	struct virtio_device *vdev = dev_to_virtio(_d);
503*4882a593Smuzhiyun 	struct virtio_pci_device *vp_dev = to_vp_device(vdev);
504*4882a593Smuzhiyun 
505*4882a593Smuzhiyun 	/* As struct device is a kobject, it's not safe to
506*4882a593Smuzhiyun 	 * free the memory (including the reference counter itself)
507*4882a593Smuzhiyun 	 * until it's release callback. */
508*4882a593Smuzhiyun 	kfree(vp_dev);
509*4882a593Smuzhiyun }
510*4882a593Smuzhiyun 
virtio_pci_probe(struct pci_dev * pci_dev,const struct pci_device_id * id)511*4882a593Smuzhiyun static int virtio_pci_probe(struct pci_dev *pci_dev,
512*4882a593Smuzhiyun 			    const struct pci_device_id *id)
513*4882a593Smuzhiyun {
514*4882a593Smuzhiyun 	struct virtio_pci_device *vp_dev, *reg_dev = NULL;
515*4882a593Smuzhiyun 	int rc;
516*4882a593Smuzhiyun 
517*4882a593Smuzhiyun 	/* allocate our structure and fill it out */
518*4882a593Smuzhiyun 	vp_dev = kzalloc(sizeof(struct virtio_pci_device), GFP_KERNEL);
519*4882a593Smuzhiyun 	if (!vp_dev)
520*4882a593Smuzhiyun 		return -ENOMEM;
521*4882a593Smuzhiyun 
522*4882a593Smuzhiyun 	pci_set_drvdata(pci_dev, vp_dev);
523*4882a593Smuzhiyun 	vp_dev->vdev.dev.parent = &pci_dev->dev;
524*4882a593Smuzhiyun 	vp_dev->vdev.dev.release = virtio_pci_release_dev;
525*4882a593Smuzhiyun 	vp_dev->pci_dev = pci_dev;
526*4882a593Smuzhiyun 	INIT_LIST_HEAD(&vp_dev->virtqueues);
527*4882a593Smuzhiyun 	spin_lock_init(&vp_dev->lock);
528*4882a593Smuzhiyun 
529*4882a593Smuzhiyun 	/* enable the device */
530*4882a593Smuzhiyun 	rc = pci_enable_device(pci_dev);
531*4882a593Smuzhiyun 	if (rc)
532*4882a593Smuzhiyun 		goto err_enable_device;
533*4882a593Smuzhiyun 
534*4882a593Smuzhiyun 	if (force_legacy) {
535*4882a593Smuzhiyun 		rc = virtio_pci_legacy_probe(vp_dev);
536*4882a593Smuzhiyun 		/* Also try modern mode if we can't map BAR0 (no IO space). */
537*4882a593Smuzhiyun 		if (rc == -ENODEV || rc == -ENOMEM)
538*4882a593Smuzhiyun 			rc = virtio_pci_modern_probe(vp_dev);
539*4882a593Smuzhiyun 		if (rc)
540*4882a593Smuzhiyun 			goto err_probe;
541*4882a593Smuzhiyun 	} else {
542*4882a593Smuzhiyun 		rc = virtio_pci_modern_probe(vp_dev);
543*4882a593Smuzhiyun 		if (rc == -ENODEV)
544*4882a593Smuzhiyun 			rc = virtio_pci_legacy_probe(vp_dev);
545*4882a593Smuzhiyun 		if (rc)
546*4882a593Smuzhiyun 			goto err_probe;
547*4882a593Smuzhiyun 	}
548*4882a593Smuzhiyun 
549*4882a593Smuzhiyun 	pci_set_master(pci_dev);
550*4882a593Smuzhiyun 
551*4882a593Smuzhiyun 	rc = register_virtio_device(&vp_dev->vdev);
552*4882a593Smuzhiyun 	reg_dev = vp_dev;
553*4882a593Smuzhiyun 	if (rc)
554*4882a593Smuzhiyun 		goto err_register;
555*4882a593Smuzhiyun 
556*4882a593Smuzhiyun 	return 0;
557*4882a593Smuzhiyun 
558*4882a593Smuzhiyun err_register:
559*4882a593Smuzhiyun 	if (vp_dev->ioaddr)
560*4882a593Smuzhiyun 	     virtio_pci_legacy_remove(vp_dev);
561*4882a593Smuzhiyun 	else
562*4882a593Smuzhiyun 	     virtio_pci_modern_remove(vp_dev);
563*4882a593Smuzhiyun err_probe:
564*4882a593Smuzhiyun 	pci_disable_device(pci_dev);
565*4882a593Smuzhiyun err_enable_device:
566*4882a593Smuzhiyun 	if (reg_dev)
567*4882a593Smuzhiyun 		put_device(&vp_dev->vdev.dev);
568*4882a593Smuzhiyun 	else
569*4882a593Smuzhiyun 		kfree(vp_dev);
570*4882a593Smuzhiyun 	return rc;
571*4882a593Smuzhiyun }
572*4882a593Smuzhiyun 
virtio_pci_remove(struct pci_dev * pci_dev)573*4882a593Smuzhiyun static void virtio_pci_remove(struct pci_dev *pci_dev)
574*4882a593Smuzhiyun {
575*4882a593Smuzhiyun 	struct virtio_pci_device *vp_dev = pci_get_drvdata(pci_dev);
576*4882a593Smuzhiyun 	struct device *dev = get_device(&vp_dev->vdev.dev);
577*4882a593Smuzhiyun 
578*4882a593Smuzhiyun 	/*
579*4882a593Smuzhiyun 	 * Device is marked broken on surprise removal so that virtio upper
580*4882a593Smuzhiyun 	 * layers can abort any ongoing operation.
581*4882a593Smuzhiyun 	 */
582*4882a593Smuzhiyun 	if (!pci_device_is_present(pci_dev))
583*4882a593Smuzhiyun 		virtio_break_device(&vp_dev->vdev);
584*4882a593Smuzhiyun 
585*4882a593Smuzhiyun 	pci_disable_sriov(pci_dev);
586*4882a593Smuzhiyun 
587*4882a593Smuzhiyun 	unregister_virtio_device(&vp_dev->vdev);
588*4882a593Smuzhiyun 
589*4882a593Smuzhiyun 	if (vp_dev->ioaddr)
590*4882a593Smuzhiyun 		virtio_pci_legacy_remove(vp_dev);
591*4882a593Smuzhiyun 	else
592*4882a593Smuzhiyun 		virtio_pci_modern_remove(vp_dev);
593*4882a593Smuzhiyun 
594*4882a593Smuzhiyun 	pci_disable_device(pci_dev);
595*4882a593Smuzhiyun 	put_device(dev);
596*4882a593Smuzhiyun }
597*4882a593Smuzhiyun 
virtio_pci_sriov_configure(struct pci_dev * pci_dev,int num_vfs)598*4882a593Smuzhiyun static int virtio_pci_sriov_configure(struct pci_dev *pci_dev, int num_vfs)
599*4882a593Smuzhiyun {
600*4882a593Smuzhiyun 	struct virtio_pci_device *vp_dev = pci_get_drvdata(pci_dev);
601*4882a593Smuzhiyun 	struct virtio_device *vdev = &vp_dev->vdev;
602*4882a593Smuzhiyun 	int ret;
603*4882a593Smuzhiyun 
604*4882a593Smuzhiyun 	if (!(vdev->config->get_status(vdev) & VIRTIO_CONFIG_S_DRIVER_OK))
605*4882a593Smuzhiyun 		return -EBUSY;
606*4882a593Smuzhiyun 
607*4882a593Smuzhiyun 	if (!__virtio_test_bit(vdev, VIRTIO_F_SR_IOV))
608*4882a593Smuzhiyun 		return -EINVAL;
609*4882a593Smuzhiyun 
610*4882a593Smuzhiyun 	if (pci_vfs_assigned(pci_dev))
611*4882a593Smuzhiyun 		return -EPERM;
612*4882a593Smuzhiyun 
613*4882a593Smuzhiyun 	if (num_vfs == 0) {
614*4882a593Smuzhiyun 		pci_disable_sriov(pci_dev);
615*4882a593Smuzhiyun 		return 0;
616*4882a593Smuzhiyun 	}
617*4882a593Smuzhiyun 
618*4882a593Smuzhiyun 	ret = pci_enable_sriov(pci_dev, num_vfs);
619*4882a593Smuzhiyun 	if (ret < 0)
620*4882a593Smuzhiyun 		return ret;
621*4882a593Smuzhiyun 
622*4882a593Smuzhiyun 	return num_vfs;
623*4882a593Smuzhiyun }
624*4882a593Smuzhiyun 
625*4882a593Smuzhiyun static struct pci_driver virtio_pci_driver = {
626*4882a593Smuzhiyun 	.name		= "virtio-pci",
627*4882a593Smuzhiyun 	.id_table	= virtio_pci_id_table,
628*4882a593Smuzhiyun 	.probe		= virtio_pci_probe,
629*4882a593Smuzhiyun 	.remove		= virtio_pci_remove,
630*4882a593Smuzhiyun #ifdef CONFIG_PM_SLEEP
631*4882a593Smuzhiyun 	.driver.pm	= &virtio_pci_pm_ops,
632*4882a593Smuzhiyun #endif
633*4882a593Smuzhiyun 	.sriov_configure = virtio_pci_sriov_configure,
634*4882a593Smuzhiyun };
635*4882a593Smuzhiyun 
636*4882a593Smuzhiyun module_pci_driver(virtio_pci_driver);
637*4882a593Smuzhiyun 
638*4882a593Smuzhiyun MODULE_AUTHOR("Anthony Liguori <aliguori@us.ibm.com>");
639*4882a593Smuzhiyun MODULE_DESCRIPTION("virtio-pci");
640*4882a593Smuzhiyun MODULE_LICENSE("GPL");
641*4882a593Smuzhiyun MODULE_VERSION("1");
642