xref: /kvmtool/virtio/pci.c (revision 8ccc85497ca3136688b015fecaa956fd95b936a1)
1 #include "kvm/virtio-pci.h"
2 
3 #include "kvm/ioport.h"
4 #include "kvm/kvm.h"
5 #include "kvm/kvm-cpu.h"
6 #include "kvm/virtio-pci-dev.h"
7 #include "kvm/irq.h"
8 #include "kvm/virtio.h"
9 #include "kvm/ioeventfd.h"
10 
11 #include <sys/ioctl.h>
12 #include <linux/virtio_pci.h>
13 #include <linux/byteorder.h>
14 #include <string.h>
15 
16 static void virtio_pci__ioevent_callback(struct kvm *kvm, void *param)
17 {
18 	struct virtio_pci_ioevent_param *ioeventfd = param;
19 	struct virtio_pci *vpci = ioeventfd->vdev->virtio;
20 
21 	ioeventfd->vdev->ops->notify_vq(kvm, vpci->dev, ioeventfd->vq);
22 }
23 
24 static int virtio_pci__init_ioeventfd(struct kvm *kvm, struct virtio_device *vdev, u32 vq)
25 {
26 	struct ioevent ioevent;
27 	struct virtio_pci *vpci = vdev->virtio;
28 	int i, r, flags = 0;
29 	int fds[2];
30 
31 	vpci->ioeventfds[vq] = (struct virtio_pci_ioevent_param) {
32 		.vdev		= vdev,
33 		.vq		= vq,
34 	};
35 
36 	ioevent = (struct ioevent) {
37 		.fn		= virtio_pci__ioevent_callback,
38 		.fn_ptr		= &vpci->ioeventfds[vq],
39 		.datamatch	= vq,
40 		.fn_kvm		= kvm,
41 	};
42 
43 	/*
44 	 * Vhost will poll the eventfd in host kernel side, otherwise we
45 	 * need to poll in userspace.
46 	 */
47 	if (!vdev->use_vhost)
48 		flags |= IOEVENTFD_FLAG_USER_POLL;
49 
50 	/* ioport */
51 	ioevent.io_addr	= vpci->port_addr + VIRTIO_PCI_QUEUE_NOTIFY;
52 	ioevent.io_len	= sizeof(u16);
53 	ioevent.fd	= fds[0] = eventfd(0, 0);
54 	r = ioeventfd__add_event(&ioevent, flags | IOEVENTFD_FLAG_PIO);
55 	if (r)
56 		return r;
57 
58 	/* mmio */
59 	ioevent.io_addr	= vpci->mmio_addr + VIRTIO_PCI_QUEUE_NOTIFY;
60 	ioevent.io_len	= sizeof(u16);
61 	ioevent.fd	= fds[1] = eventfd(0, 0);
62 	r = ioeventfd__add_event(&ioevent, flags);
63 	if (r)
64 		goto free_ioport_evt;
65 
66 	if (vdev->ops->notify_vq_eventfd)
67 		for (i = 0; i < 2; ++i)
68 			vdev->ops->notify_vq_eventfd(kvm, vpci->dev, vq,
69 						     fds[i]);
70 	return 0;
71 
72 free_ioport_evt:
73 	ioeventfd__del_event(vpci->port_addr + VIRTIO_PCI_QUEUE_NOTIFY, vq);
74 	return r;
75 }
76 
77 static inline bool virtio_pci__msix_enabled(struct virtio_pci *vpci)
78 {
79 	return vpci->pci_hdr.msix.ctrl & cpu_to_le16(PCI_MSIX_FLAGS_ENABLE);
80 }
81 
82 static bool virtio_pci__specific_io_in(struct kvm *kvm, struct virtio_device *vdev, u16 port,
83 					void *data, int size, int offset)
84 {
85 	u32 config_offset;
86 	struct virtio_pci *vpci = vdev->virtio;
87 	int type = virtio__get_dev_specific_field(offset - 20,
88 							virtio_pci__msix_enabled(vpci),
89 							&config_offset);
90 	if (type == VIRTIO_PCI_O_MSIX) {
91 		switch (offset) {
92 		case VIRTIO_MSI_CONFIG_VECTOR:
93 			ioport__write16(data, vpci->config_vector);
94 			break;
95 		case VIRTIO_MSI_QUEUE_VECTOR:
96 			ioport__write16(data, vpci->vq_vector[vpci->queue_selector]);
97 			break;
98 		};
99 
100 		return true;
101 	} else if (type == VIRTIO_PCI_O_CONFIG) {
102 		u8 cfg;
103 
104 		cfg = vdev->ops->get_config(kvm, vpci->dev)[config_offset];
105 		ioport__write8(data, cfg);
106 		return true;
107 	}
108 
109 	return false;
110 }
111 
112 static bool virtio_pci__io_in(struct ioport *ioport, struct kvm_cpu *vcpu, u16 port, void *data, int size)
113 {
114 	unsigned long offset;
115 	bool ret = true;
116 	struct virtio_device *vdev;
117 	struct virtio_pci *vpci;
118 	struct kvm *kvm;
119 	u32 val;
120 
121 	kvm = vcpu->kvm;
122 	vdev = ioport->priv;
123 	vpci = vdev->virtio;
124 	offset = port - vpci->port_addr;
125 
126 	switch (offset) {
127 	case VIRTIO_PCI_HOST_FEATURES:
128 		val = vdev->ops->get_host_features(kvm, vpci->dev);
129 		ioport__write32(data, val);
130 		break;
131 	case VIRTIO_PCI_QUEUE_PFN:
132 		val = vdev->ops->get_pfn_vq(kvm, vpci->dev, vpci->queue_selector);
133 		ioport__write32(data, val);
134 		break;
135 	case VIRTIO_PCI_QUEUE_NUM:
136 		val = vdev->ops->get_size_vq(kvm, vpci->dev, vpci->queue_selector);
137 		ioport__write16(data, val);
138 		break;
139 	case VIRTIO_PCI_STATUS:
140 		ioport__write8(data, vpci->status);
141 		break;
142 	case VIRTIO_PCI_ISR:
143 		ioport__write8(data, vpci->isr);
144 		kvm__irq_line(kvm, vpci->legacy_irq_line, VIRTIO_IRQ_LOW);
145 		vpci->isr = VIRTIO_IRQ_LOW;
146 		break;
147 	default:
148 		ret = virtio_pci__specific_io_in(kvm, vdev, port, data, size, offset);
149 		break;
150 	};
151 
152 	return ret;
153 }
154 
155 static bool virtio_pci__specific_io_out(struct kvm *kvm, struct virtio_device *vdev, u16 port,
156 					void *data, int size, int offset)
157 {
158 	struct virtio_pci *vpci = vdev->virtio;
159 	u32 config_offset, vec;
160 	int gsi;
161 	int type = virtio__get_dev_specific_field(offset - 20, virtio_pci__msix_enabled(vpci),
162 							&config_offset);
163 	if (type == VIRTIO_PCI_O_MSIX) {
164 		switch (offset) {
165 		case VIRTIO_MSI_CONFIG_VECTOR:
166 			vec = vpci->config_vector = ioport__read16(data);
167 			if (vec == VIRTIO_MSI_NO_VECTOR)
168 				break;
169 
170 			gsi = irq__add_msix_route(kvm,
171 						  &vpci->msix_table[vec].msg);
172 			if (gsi >= 0)
173 				vpci->config_gsi = gsi;
174 			break;
175 		case VIRTIO_MSI_QUEUE_VECTOR:
176 			vec = ioport__read16(data);
177 			vpci->vq_vector[vpci->queue_selector] = vec;
178 
179 			if (vec == VIRTIO_MSI_NO_VECTOR)
180 				break;
181 
182 			gsi = irq__add_msix_route(kvm,
183 						  &vpci->msix_table[vec].msg);
184 			if (gsi < 0)
185 				break;
186 			vpci->gsis[vpci->queue_selector] = gsi;
187 			if (vdev->ops->notify_vq_gsi)
188 				vdev->ops->notify_vq_gsi(kvm, vpci->dev,
189 							 vpci->queue_selector,
190 							 gsi);
191 			break;
192 		};
193 
194 		return true;
195 	} else if (type == VIRTIO_PCI_O_CONFIG) {
196 		vdev->ops->get_config(kvm, vpci->dev)[config_offset] = *(u8 *)data;
197 
198 		return true;
199 	}
200 
201 	return false;
202 }
203 
204 static bool virtio_pci__io_out(struct ioport *ioport, struct kvm_cpu *vcpu, u16 port, void *data, int size)
205 {
206 	unsigned long offset;
207 	bool ret = true;
208 	struct virtio_device *vdev;
209 	struct virtio_pci *vpci;
210 	struct kvm *kvm;
211 	u32 val;
212 
213 	kvm = vcpu->kvm;
214 	vdev = ioport->priv;
215 	vpci = vdev->virtio;
216 	offset = port - vpci->port_addr;
217 
218 	switch (offset) {
219 	case VIRTIO_PCI_GUEST_FEATURES:
220 		val = ioport__read32(data);
221 		vdev->ops->set_guest_features(kvm, vpci->dev, val);
222 		break;
223 	case VIRTIO_PCI_QUEUE_PFN:
224 		val = ioport__read32(data);
225 		virtio_pci__init_ioeventfd(kvm, vdev, vpci->queue_selector);
226 		vdev->ops->init_vq(kvm, vpci->dev, vpci->queue_selector,
227 				   1 << VIRTIO_PCI_QUEUE_ADDR_SHIFT,
228 				   VIRTIO_PCI_VRING_ALIGN, val);
229 		break;
230 	case VIRTIO_PCI_QUEUE_SEL:
231 		vpci->queue_selector = ioport__read16(data);
232 		break;
233 	case VIRTIO_PCI_QUEUE_NOTIFY:
234 		val = ioport__read16(data);
235 		vdev->ops->notify_vq(kvm, vpci->dev, val);
236 		break;
237 	case VIRTIO_PCI_STATUS:
238 		vpci->status = ioport__read8(data);
239 		if (!vpci->status) /* Sample endianness on reset */
240 			vdev->endian = kvm_cpu__get_endianness(vcpu);
241 		if (vdev->ops->notify_status)
242 			vdev->ops->notify_status(kvm, vpci->dev, vpci->status);
243 		break;
244 	default:
245 		ret = virtio_pci__specific_io_out(kvm, vdev, port, data, size, offset);
246 		break;
247 	};
248 
249 	return ret;
250 }
251 
252 static struct ioport_operations virtio_pci__io_ops = {
253 	.io_in	= virtio_pci__io_in,
254 	.io_out	= virtio_pci__io_out,
255 };
256 
257 static void virtio_pci__msix_mmio_callback(struct kvm_cpu *vcpu,
258 					   u64 addr, u8 *data, u32 len,
259 					   u8 is_write, void *ptr)
260 {
261 	struct virtio_pci *vpci = ptr;
262 	void *table;
263 	u32 offset;
264 
265 	if (addr > vpci->msix_io_block + PCI_IO_SIZE) {
266 		table	= &vpci->msix_pba;
267 		offset	= vpci->msix_io_block + PCI_IO_SIZE;
268 	} else {
269 		table	= &vpci->msix_table;
270 		offset	= vpci->msix_io_block;
271 	}
272 
273 	if (is_write)
274 		memcpy(table + addr - offset, data, len);
275 	else
276 		memcpy(data, table + addr - offset, len);
277 }
278 
279 static void virtio_pci__signal_msi(struct kvm *kvm, struct virtio_pci *vpci, int vec)
280 {
281 	struct kvm_msi msi = {
282 		.address_lo = vpci->msix_table[vec].msg.address_lo,
283 		.address_hi = vpci->msix_table[vec].msg.address_hi,
284 		.data = vpci->msix_table[vec].msg.data,
285 	};
286 
287 	ioctl(kvm->vm_fd, KVM_SIGNAL_MSI, &msi);
288 }
289 
290 int virtio_pci__signal_vq(struct kvm *kvm, struct virtio_device *vdev, u32 vq)
291 {
292 	struct virtio_pci *vpci = vdev->virtio;
293 	int tbl = vpci->vq_vector[vq];
294 
295 	if (virtio_pci__msix_enabled(vpci) && tbl != VIRTIO_MSI_NO_VECTOR) {
296 		if (vpci->pci_hdr.msix.ctrl & cpu_to_le16(PCI_MSIX_FLAGS_MASKALL) ||
297 		    vpci->msix_table[tbl].ctrl & cpu_to_le16(PCI_MSIX_ENTRY_CTRL_MASKBIT)) {
298 
299 			vpci->msix_pba |= 1 << tbl;
300 			return 0;
301 		}
302 
303 		if (vpci->features & VIRTIO_PCI_F_SIGNAL_MSI)
304 			virtio_pci__signal_msi(kvm, vpci, vpci->vq_vector[vq]);
305 		else
306 			kvm__irq_trigger(kvm, vpci->gsis[vq]);
307 	} else {
308 		vpci->isr = VIRTIO_IRQ_HIGH;
309 		kvm__irq_trigger(kvm, vpci->legacy_irq_line);
310 	}
311 	return 0;
312 }
313 
314 int virtio_pci__signal_config(struct kvm *kvm, struct virtio_device *vdev)
315 {
316 	struct virtio_pci *vpci = vdev->virtio;
317 	int tbl = vpci->config_vector;
318 
319 	if (virtio_pci__msix_enabled(vpci) && tbl != VIRTIO_MSI_NO_VECTOR) {
320 		if (vpci->pci_hdr.msix.ctrl & cpu_to_le16(PCI_MSIX_FLAGS_MASKALL) ||
321 		    vpci->msix_table[tbl].ctrl & cpu_to_le16(PCI_MSIX_ENTRY_CTRL_MASKBIT)) {
322 
323 			vpci->msix_pba |= 1 << tbl;
324 			return 0;
325 		}
326 
327 		if (vpci->features & VIRTIO_PCI_F_SIGNAL_MSI)
328 			virtio_pci__signal_msi(kvm, vpci, tbl);
329 		else
330 			kvm__irq_trigger(kvm, vpci->config_gsi);
331 	} else {
332 		vpci->isr = VIRTIO_PCI_ISR_CONFIG;
333 		kvm__irq_trigger(kvm, vpci->legacy_irq_line);
334 	}
335 
336 	return 0;
337 }
338 
339 static void virtio_pci__io_mmio_callback(struct kvm_cpu *vcpu,
340 					 u64 addr, u8 *data, u32 len,
341 					 u8 is_write, void *ptr)
342 {
343 	struct virtio_pci *vpci = ptr;
344 	int direction = is_write ? KVM_EXIT_IO_OUT : KVM_EXIT_IO_IN;
345 	u16 port = vpci->port_addr + (addr & (IOPORT_SIZE - 1));
346 
347 	kvm__emulate_io(vcpu, port, data, direction, len, 1);
348 }
349 
350 int virtio_pci__init(struct kvm *kvm, void *dev, struct virtio_device *vdev,
351 		     int device_id, int subsys_id, int class)
352 {
353 	struct virtio_pci *vpci = vdev->virtio;
354 	int r;
355 
356 	vpci->kvm = kvm;
357 	vpci->dev = dev;
358 
359 	r = ioport__register(kvm, IOPORT_EMPTY, &virtio_pci__io_ops, IOPORT_SIZE, vdev);
360 	if (r < 0)
361 		return r;
362 	vpci->port_addr = (u16)r;
363 
364 	vpci->mmio_addr = pci_get_io_space_block(IOPORT_SIZE);
365 	r = kvm__register_mmio(kvm, vpci->mmio_addr, IOPORT_SIZE, false,
366 			       virtio_pci__io_mmio_callback, vpci);
367 	if (r < 0)
368 		goto free_ioport;
369 
370 	vpci->msix_io_block = pci_get_io_space_block(PCI_IO_SIZE * 2);
371 	r = kvm__register_mmio(kvm, vpci->msix_io_block, PCI_IO_SIZE * 2, false,
372 			       virtio_pci__msix_mmio_callback, vpci);
373 	if (r < 0)
374 		goto free_mmio;
375 
376 	vpci->pci_hdr = (struct pci_device_header) {
377 		.vendor_id		= cpu_to_le16(PCI_VENDOR_ID_REDHAT_QUMRANET),
378 		.device_id		= cpu_to_le16(device_id),
379 		.command		= PCI_COMMAND_IO | PCI_COMMAND_MEMORY,
380 		.header_type		= PCI_HEADER_TYPE_NORMAL,
381 		.revision_id		= 0,
382 		.class[0]		= class & 0xff,
383 		.class[1]		= (class >> 8) & 0xff,
384 		.class[2]		= (class >> 16) & 0xff,
385 		.subsys_vendor_id	= cpu_to_le16(PCI_SUBSYSTEM_VENDOR_ID_REDHAT_QUMRANET),
386 		.subsys_id		= cpu_to_le16(subsys_id),
387 		.bar[0]			= cpu_to_le32(vpci->mmio_addr
388 							| PCI_BASE_ADDRESS_SPACE_MEMORY),
389 		.bar[1]			= cpu_to_le32(vpci->port_addr
390 							| PCI_BASE_ADDRESS_SPACE_IO),
391 		.bar[2]			= cpu_to_le32(vpci->msix_io_block
392 							| PCI_BASE_ADDRESS_SPACE_MEMORY),
393 		.status			= cpu_to_le16(PCI_STATUS_CAP_LIST),
394 		.capabilities		= (void *)&vpci->pci_hdr.msix - (void *)&vpci->pci_hdr,
395 		.bar_size[0]		= cpu_to_le32(IOPORT_SIZE),
396 		.bar_size[1]		= cpu_to_le32(IOPORT_SIZE),
397 		.bar_size[2]		= cpu_to_le32(PCI_IO_SIZE*2),
398 	};
399 
400 	vpci->dev_hdr = (struct device_header) {
401 		.bus_type		= DEVICE_BUS_PCI,
402 		.data			= &vpci->pci_hdr,
403 	};
404 
405 	vpci->pci_hdr.msix.cap = PCI_CAP_ID_MSIX;
406 	vpci->pci_hdr.msix.next = 0;
407 	/*
408 	 * We at most have VIRTIO_PCI_MAX_VQ entries for virt queue,
409 	 * VIRTIO_PCI_MAX_CONFIG entries for config.
410 	 *
411 	 * To quote the PCI spec:
412 	 *
413 	 * System software reads this field to determine the
414 	 * MSI-X Table Size N, which is encoded as N-1.
415 	 * For example, a returned value of "00000000011"
416 	 * indicates a table size of 4.
417 	 */
418 	vpci->pci_hdr.msix.ctrl = cpu_to_le16(VIRTIO_PCI_MAX_VQ + VIRTIO_PCI_MAX_CONFIG - 1);
419 
420 	/* Both table and PBA are mapped to the same BAR (2) */
421 	vpci->pci_hdr.msix.table_offset = cpu_to_le32(2);
422 	vpci->pci_hdr.msix.pba_offset = cpu_to_le32(2 | PCI_IO_SIZE);
423 	vpci->config_vector = 0;
424 
425 	if (kvm__supports_extension(kvm, KVM_CAP_SIGNAL_MSI))
426 		vpci->features |= VIRTIO_PCI_F_SIGNAL_MSI;
427 
428 	r = device__register(&vpci->dev_hdr);
429 	if (r < 0)
430 		goto free_msix_mmio;
431 
432 	/* save the IRQ that device__register() has allocated */
433 	vpci->legacy_irq_line = vpci->pci_hdr.irq_line;
434 
435 	return 0;
436 
437 free_msix_mmio:
438 	kvm__deregister_mmio(kvm, vpci->msix_io_block);
439 free_mmio:
440 	kvm__deregister_mmio(kvm, vpci->mmio_addr);
441 free_ioport:
442 	ioport__unregister(kvm, vpci->port_addr);
443 	return r;
444 }
445 
446 int virtio_pci__exit(struct kvm *kvm, struct virtio_device *vdev)
447 {
448 	struct virtio_pci *vpci = vdev->virtio;
449 	int i;
450 
451 	kvm__deregister_mmio(kvm, vpci->mmio_addr);
452 	kvm__deregister_mmio(kvm, vpci->msix_io_block);
453 	ioport__unregister(kvm, vpci->port_addr);
454 
455 	for (i = 0; i < VIRTIO_PCI_MAX_VQ; i++) {
456 		ioeventfd__del_event(vpci->port_addr + VIRTIO_PCI_QUEUE_NOTIFY, i);
457 		ioeventfd__del_event(vpci->mmio_addr + VIRTIO_PCI_QUEUE_NOTIFY, i);
458 	}
459 
460 	return 0;
461 }
462