]> git.proxmox.com Git - mirror_qemu.git/blame - hw/virtio-pci.c
softmmu: move include files to include/sysemu/
[mirror_qemu.git] / hw / virtio-pci.c
CommitLineData
53c25cea
PB
1/*
2 * Virtio PCI Bindings
3 *
4 * Copyright IBM, Corp. 2007
5 * Copyright (c) 2009 CodeSourcery
6 *
7 * Authors:
8 * Anthony Liguori <aliguori@us.ibm.com>
9 * Paul Brook <paul@codesourcery.com>
10 *
11 * This work is licensed under the terms of the GNU GPL, version 2. See
12 * the COPYING file in the top-level directory.
13 *
6b620ca3
PB
14 * Contributions after 2012-01-13 are licensed under the terms of the
15 * GNU GPL, version 2 or (at your option) any later version.
53c25cea
PB
16 */
17
18#include <inttypes.h>
19
20#include "virtio.h"
8172539d
MT
21#include "virtio-blk.h"
22#include "virtio-net.h"
6b331efb 23#include "virtio-serial.h"
973abc7f 24#include "virtio-scsi.h"
a2cb15b0 25#include "pci/pci.h"
1de7afc9 26#include "qemu/error-report.h"
a2cb15b0
MT
27#include "pci/msi.h"
28#include "pci/msix.h"
97b15621 29#include "loader.h"
9c17d615
PB
30#include "sysemu/kvm.h"
31#include "sysemu/blockdev.h"
9fe1ebeb 32#include "virtio-pci.h"
1de7afc9 33#include "qemu/range.h"
53c25cea
PB
34
35/* from Linux's linux/virtio_pci.h */
36
37/* A 32-bit r/o bitmask of the features supported by the host */
38#define VIRTIO_PCI_HOST_FEATURES 0
39
40/* A 32-bit r/w bitmask of features activated by the guest */
41#define VIRTIO_PCI_GUEST_FEATURES 4
42
43/* A 32-bit r/w PFN for the currently selected queue */
44#define VIRTIO_PCI_QUEUE_PFN 8
45
46/* A 16-bit r/o queue size for the currently selected queue */
47#define VIRTIO_PCI_QUEUE_NUM 12
48
49/* A 16-bit r/w queue selector */
50#define VIRTIO_PCI_QUEUE_SEL 14
51
52/* A 16-bit r/w queue notifier */
53#define VIRTIO_PCI_QUEUE_NOTIFY 16
54
55/* An 8-bit device status register. */
56#define VIRTIO_PCI_STATUS 18
57
58/* An 8-bit r/o interrupt status register. Reading the value will return the
59 * current contents of the ISR and will also clear it. This is effectively
60 * a read-and-acknowledge. */
61#define VIRTIO_PCI_ISR 19
62
aba800a3
MT
63/* MSI-X registers: only enabled if MSI-X is enabled. */
64/* A 16-bit vector for configuration changes. */
65#define VIRTIO_MSI_CONFIG_VECTOR 20
66/* A 16-bit vector for selected queue notifications. */
67#define VIRTIO_MSI_QUEUE_VECTOR 22
68
69/* Config space size */
70#define VIRTIO_PCI_CONFIG_NOMSI 20
71#define VIRTIO_PCI_CONFIG_MSI 24
72#define VIRTIO_PCI_REGION_SIZE(dev) (msix_present(dev) ? \
73 VIRTIO_PCI_CONFIG_MSI : \
74 VIRTIO_PCI_CONFIG_NOMSI)
75
76/* The remaining space is defined by each driver as the per-driver
77 * configuration space */
78#define VIRTIO_PCI_CONFIG(dev) (msix_enabled(dev) ? \
79 VIRTIO_PCI_CONFIG_MSI : \
80 VIRTIO_PCI_CONFIG_NOMSI)
53c25cea 81
53c25cea
PB
82/* How many bits to shift physical queue address written to QUEUE_PFN.
83 * 12 is historical, and due to x86 page size. */
84#define VIRTIO_PCI_QUEUE_ADDR_SHIFT 12
85
3dbca8e6
SH
86/* Flags track per-device state like workarounds for quirks in older guests. */
87#define VIRTIO_PCI_FLAG_BUS_MASTER_BUG (1 << 0)
c81131db 88
53c25cea
PB
89/* QEMU doesn't strictly need write barriers since everything runs in
90 * lock-step. We'll leave the calls to wmb() in though to make it obvious for
91 * KVM or if kqemu gets SMP support.
92 */
93#define wmb() do { } while (0)
94
82afa586
BH
95/* HACK for virtio to determine if it's running a big endian guest */
96bool virtio_is_big_endian(void);
97
53c25cea
PB
98/* virtio device */
99
7055e687 100static void virtio_pci_notify(void *opaque, uint16_t vector)
53c25cea
PB
101{
102 VirtIOPCIProxy *proxy = opaque;
aba800a3
MT
103 if (msix_enabled(&proxy->pci_dev))
104 msix_notify(&proxy->pci_dev, vector);
105 else
106 qemu_set_irq(proxy->pci_dev.irq[0], proxy->vdev->isr & 1);
53c25cea
PB
107}
108
ff24bd58
MT
109static void virtio_pci_save_config(void * opaque, QEMUFile *f)
110{
111 VirtIOPCIProxy *proxy = opaque;
112 pci_device_save(&proxy->pci_dev, f);
113 msix_save(&proxy->pci_dev, f);
114 if (msix_present(&proxy->pci_dev))
115 qemu_put_be16(f, proxy->vdev->config_vector);
116}
117
118static void virtio_pci_save_queue(void * opaque, int n, QEMUFile *f)
119{
120 VirtIOPCIProxy *proxy = opaque;
121 if (msix_present(&proxy->pci_dev))
122 qemu_put_be16(f, virtio_queue_vector(proxy->vdev, n));
123}
124
125static int virtio_pci_load_config(void * opaque, QEMUFile *f)
126{
127 VirtIOPCIProxy *proxy = opaque;
128 int ret;
129 ret = pci_device_load(&proxy->pci_dev, f);
e6da7680 130 if (ret) {
ff24bd58 131 return ret;
e6da7680 132 }
3cac001e 133 msix_unuse_all_vectors(&proxy->pci_dev);
ff24bd58 134 msix_load(&proxy->pci_dev, f);
e6da7680 135 if (msix_present(&proxy->pci_dev)) {
ff24bd58 136 qemu_get_be16s(f, &proxy->vdev->config_vector);
e6da7680
MT
137 } else {
138 proxy->vdev->config_vector = VIRTIO_NO_VECTOR;
139 }
140 if (proxy->vdev->config_vector != VIRTIO_NO_VECTOR) {
141 return msix_vector_use(&proxy->pci_dev, proxy->vdev->config_vector);
142 }
ff24bd58
MT
143 return 0;
144}
145
146static int virtio_pci_load_queue(void * opaque, int n, QEMUFile *f)
147{
148 VirtIOPCIProxy *proxy = opaque;
149 uint16_t vector;
e6da7680
MT
150 if (msix_present(&proxy->pci_dev)) {
151 qemu_get_be16s(f, &vector);
152 } else {
153 vector = VIRTIO_NO_VECTOR;
154 }
ff24bd58 155 virtio_queue_set_vector(proxy->vdev, n, vector);
e6da7680
MT
156 if (vector != VIRTIO_NO_VECTOR) {
157 return msix_vector_use(&proxy->pci_dev, vector);
158 }
ff24bd58
MT
159 return 0;
160}
161
25db9ebe 162static int virtio_pci_set_host_notifier_internal(VirtIOPCIProxy *proxy,
26b9b5fe 163 int n, bool assign, bool set_handler)
25db9ebe
SH
164{
165 VirtQueue *vq = virtio_get_queue(proxy->vdev, n);
166 EventNotifier *notifier = virtio_queue_get_host_notifier(vq);
da146d0a
AK
167 int r = 0;
168
25db9ebe
SH
169 if (assign) {
170 r = event_notifier_init(notifier, 1);
171 if (r < 0) {
b36e3914
MT
172 error_report("%s: unable to init event notifier: %d",
173 __func__, r);
25db9ebe
SH
174 return r;
175 }
26b9b5fe 176 virtio_queue_set_host_notifier_fd_handler(vq, true, set_handler);
da146d0a 177 memory_region_add_eventfd(&proxy->bar, VIRTIO_PCI_QUEUE_NOTIFY, 2,
753d5e14 178 true, n, notifier);
25db9ebe 179 } else {
da146d0a 180 memory_region_del_eventfd(&proxy->bar, VIRTIO_PCI_QUEUE_NOTIFY, 2,
753d5e14 181 true, n, notifier);
26b9b5fe 182 virtio_queue_set_host_notifier_fd_handler(vq, false, false);
25db9ebe
SH
183 event_notifier_cleanup(notifier);
184 }
185 return r;
186}
187
b36e3914 188static void virtio_pci_start_ioeventfd(VirtIOPCIProxy *proxy)
25db9ebe
SH
189{
190 int n, r;
191
192 if (!(proxy->flags & VIRTIO_PCI_FLAG_USE_IOEVENTFD) ||
193 proxy->ioeventfd_disabled ||
194 proxy->ioeventfd_started) {
b36e3914 195 return;
25db9ebe
SH
196 }
197
198 for (n = 0; n < VIRTIO_PCI_QUEUE_MAX; n++) {
199 if (!virtio_queue_get_num(proxy->vdev, n)) {
200 continue;
201 }
202
26b9b5fe 203 r = virtio_pci_set_host_notifier_internal(proxy, n, true, true);
25db9ebe
SH
204 if (r < 0) {
205 goto assign_error;
206 }
25db9ebe
SH
207 }
208 proxy->ioeventfd_started = true;
b36e3914 209 return;
25db9ebe
SH
210
211assign_error:
212 while (--n >= 0) {
213 if (!virtio_queue_get_num(proxy->vdev, n)) {
214 continue;
215 }
216
26b9b5fe 217 r = virtio_pci_set_host_notifier_internal(proxy, n, false, false);
b36e3914 218 assert(r >= 0);
25db9ebe
SH
219 }
220 proxy->ioeventfd_started = false;
b36e3914 221 error_report("%s: failed. Fallback to a userspace (slower).", __func__);
25db9ebe
SH
222}
223
b36e3914 224static void virtio_pci_stop_ioeventfd(VirtIOPCIProxy *proxy)
25db9ebe 225{
b36e3914 226 int r;
25db9ebe
SH
227 int n;
228
229 if (!proxy->ioeventfd_started) {
b36e3914 230 return;
25db9ebe
SH
231 }
232
233 for (n = 0; n < VIRTIO_PCI_QUEUE_MAX; n++) {
234 if (!virtio_queue_get_num(proxy->vdev, n)) {
235 continue;
236 }
237
26b9b5fe 238 r = virtio_pci_set_host_notifier_internal(proxy, n, false, false);
b36e3914 239 assert(r >= 0);
25db9ebe
SH
240 }
241 proxy->ioeventfd_started = false;
25db9ebe
SH
242}
243
8798d6c9 244void virtio_pci_reset(DeviceState *d)
7055e687 245{
e489030d 246 VirtIOPCIProxy *proxy = container_of(d, VirtIOPCIProxy, pci_dev.qdev);
25db9ebe 247 virtio_pci_stop_ioeventfd(proxy);
7055e687 248 virtio_reset(proxy->vdev);
3cac001e 249 msix_unuse_all_vectors(&proxy->pci_dev);
25db9ebe 250 proxy->flags &= ~VIRTIO_PCI_FLAG_BUS_MASTER_BUG;
7055e687
MT
251}
252
53c25cea
PB
253static void virtio_ioport_write(void *opaque, uint32_t addr, uint32_t val)
254{
255 VirtIOPCIProxy *proxy = opaque;
256 VirtIODevice *vdev = proxy->vdev;
a8170e5e 257 hwaddr pa;
53c25cea 258
53c25cea
PB
259 switch (addr) {
260 case VIRTIO_PCI_GUEST_FEATURES:
261 /* Guest does not negotiate properly? We have to assume nothing. */
262 if (val & (1 << VIRTIO_F_BAD_FEATURE)) {
ad0c9332 263 val = vdev->bad_features ? vdev->bad_features(vdev) : 0;
53c25cea 264 }
ad0c9332 265 virtio_set_features(vdev, val);
53c25cea
PB
266 break;
267 case VIRTIO_PCI_QUEUE_PFN:
a8170e5e 268 pa = (hwaddr)val << VIRTIO_PCI_QUEUE_ADDR_SHIFT;
1b8e9b27 269 if (pa == 0) {
25db9ebe 270 virtio_pci_stop_ioeventfd(proxy);
1b8e9b27
MT
271 virtio_reset(proxy->vdev);
272 msix_unuse_all_vectors(&proxy->pci_dev);
273 }
7055e687
MT
274 else
275 virtio_queue_set_addr(vdev, vdev->queue_sel, pa);
53c25cea
PB
276 break;
277 case VIRTIO_PCI_QUEUE_SEL:
278 if (val < VIRTIO_PCI_QUEUE_MAX)
279 vdev->queue_sel = val;
280 break;
281 case VIRTIO_PCI_QUEUE_NOTIFY:
7157e2e2
SH
282 if (val < VIRTIO_PCI_QUEUE_MAX) {
283 virtio_queue_notify(vdev, val);
284 }
53c25cea
PB
285 break;
286 case VIRTIO_PCI_STATUS:
25db9ebe
SH
287 if (!(val & VIRTIO_CONFIG_S_DRIVER_OK)) {
288 virtio_pci_stop_ioeventfd(proxy);
289 }
290
3e607cb5 291 virtio_set_status(vdev, val & 0xFF);
25db9ebe
SH
292
293 if (val & VIRTIO_CONFIG_S_DRIVER_OK) {
294 virtio_pci_start_ioeventfd(proxy);
295 }
296
1b8e9b27
MT
297 if (vdev->status == 0) {
298 virtio_reset(proxy->vdev);
299 msix_unuse_all_vectors(&proxy->pci_dev);
300 }
c81131db
AG
301
302 /* Linux before 2.6.34 sets the device as OK without enabling
303 the PCI device bus master bit. In this case we need to disable
304 some safety checks. */
305 if ((val & VIRTIO_CONFIG_S_DRIVER_OK) &&
306 !(proxy->pci_dev.config[PCI_COMMAND] & PCI_COMMAND_MASTER)) {
3dbca8e6 307 proxy->flags |= VIRTIO_PCI_FLAG_BUS_MASTER_BUG;
c81131db 308 }
53c25cea 309 break;
aba800a3
MT
310 case VIRTIO_MSI_CONFIG_VECTOR:
311 msix_vector_unuse(&proxy->pci_dev, vdev->config_vector);
312 /* Make it possible for guest to discover an error took place. */
313 if (msix_vector_use(&proxy->pci_dev, val) < 0)
314 val = VIRTIO_NO_VECTOR;
315 vdev->config_vector = val;
316 break;
317 case VIRTIO_MSI_QUEUE_VECTOR:
318 msix_vector_unuse(&proxy->pci_dev,
319 virtio_queue_vector(vdev, vdev->queue_sel));
320 /* Make it possible for guest to discover an error took place. */
321 if (msix_vector_use(&proxy->pci_dev, val) < 0)
322 val = VIRTIO_NO_VECTOR;
323 virtio_queue_set_vector(vdev, vdev->queue_sel, val);
324 break;
325 default:
4e02d460
SH
326 error_report("%s: unexpected address 0x%x value 0x%x",
327 __func__, addr, val);
aba800a3 328 break;
53c25cea
PB
329 }
330}
331
aba800a3 332static uint32_t virtio_ioport_read(VirtIOPCIProxy *proxy, uint32_t addr)
53c25cea 333{
53c25cea
PB
334 VirtIODevice *vdev = proxy->vdev;
335 uint32_t ret = 0xFFFFFFFF;
336
53c25cea
PB
337 switch (addr) {
338 case VIRTIO_PCI_HOST_FEATURES:
8172539d 339 ret = proxy->host_features;
53c25cea
PB
340 break;
341 case VIRTIO_PCI_GUEST_FEATURES:
704a76fc 342 ret = vdev->guest_features;
53c25cea
PB
343 break;
344 case VIRTIO_PCI_QUEUE_PFN:
345 ret = virtio_queue_get_addr(vdev, vdev->queue_sel)
346 >> VIRTIO_PCI_QUEUE_ADDR_SHIFT;
347 break;
348 case VIRTIO_PCI_QUEUE_NUM:
349 ret = virtio_queue_get_num(vdev, vdev->queue_sel);
350 break;
351 case VIRTIO_PCI_QUEUE_SEL:
352 ret = vdev->queue_sel;
353 break;
354 case VIRTIO_PCI_STATUS:
355 ret = vdev->status;
356 break;
357 case VIRTIO_PCI_ISR:
358 /* reading from the ISR also clears it. */
359 ret = vdev->isr;
360 vdev->isr = 0;
7055e687 361 qemu_set_irq(proxy->pci_dev.irq[0], 0);
53c25cea 362 break;
aba800a3
MT
363 case VIRTIO_MSI_CONFIG_VECTOR:
364 ret = vdev->config_vector;
365 break;
366 case VIRTIO_MSI_QUEUE_VECTOR:
367 ret = virtio_queue_vector(vdev, vdev->queue_sel);
368 break;
53c25cea
PB
369 default:
370 break;
371 }
372
373 return ret;
374}
375
df6db5b3
AG
376static uint64_t virtio_pci_config_read(void *opaque, hwaddr addr,
377 unsigned size)
53c25cea
PB
378{
379 VirtIOPCIProxy *proxy = opaque;
aba800a3 380 uint32_t config = VIRTIO_PCI_CONFIG(&proxy->pci_dev);
df6db5b3 381 uint64_t val = 0;
aba800a3 382 if (addr < config) {
df6db5b3 383 return virtio_ioport_read(proxy, addr);
aba800a3
MT
384 }
385 addr -= config;
53c25cea 386
df6db5b3
AG
387 switch (size) {
388 case 1:
389 val = virtio_config_readb(proxy->vdev, addr);
390 break;
391 case 2:
392 val = virtio_config_readw(proxy->vdev, addr);
393 if (virtio_is_big_endian()) {
394 val = bswap16(val);
395 }
396 break;
397 case 4:
398 val = virtio_config_readl(proxy->vdev, addr);
399 if (virtio_is_big_endian()) {
400 val = bswap32(val);
401 }
402 break;
82afa586 403 }
df6db5b3 404 return val;
53c25cea
PB
405}
406
df6db5b3
AG
407static void virtio_pci_config_write(void *opaque, hwaddr addr,
408 uint64_t val, unsigned size)
53c25cea
PB
409{
410 VirtIOPCIProxy *proxy = opaque;
aba800a3 411 uint32_t config = VIRTIO_PCI_CONFIG(&proxy->pci_dev);
aba800a3
MT
412 if (addr < config) {
413 virtio_ioport_write(proxy, addr, val);
414 return;
415 }
416 addr -= config;
df6db5b3
AG
417 /*
418 * Virtio-PCI is odd. Ioports are LE but config space is target native
419 * endian.
420 */
421 switch (size) {
422 case 1:
423 virtio_config_writeb(proxy->vdev, addr, val);
424 break;
425 case 2:
426 if (virtio_is_big_endian()) {
427 val = bswap16(val);
428 }
429 virtio_config_writew(proxy->vdev, addr, val);
430 break;
431 case 4:
432 if (virtio_is_big_endian()) {
433 val = bswap32(val);
434 }
435 virtio_config_writel(proxy->vdev, addr, val);
436 break;
82afa586 437 }
53c25cea
PB
438}
439
da146d0a 440static const MemoryRegionOps virtio_pci_config_ops = {
df6db5b3
AG
441 .read = virtio_pci_config_read,
442 .write = virtio_pci_config_write,
443 .impl = {
444 .min_access_size = 1,
445 .max_access_size = 4,
446 },
da146d0a
AK
447 .endianness = DEVICE_LITTLE_ENDIAN,
448};
aba800a3
MT
449
450static void virtio_write_config(PCIDevice *pci_dev, uint32_t address,
451 uint32_t val, int len)
452{
ed757e14
YV
453 VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
454
1129714f
MT
455 pci_default_write_config(pci_dev, address, val, len);
456
457 if (range_covers_byte(address, len, PCI_COMMAND) &&
458 !(pci_dev->config[PCI_COMMAND] & PCI_COMMAND_MASTER) &&
459 !(proxy->flags & VIRTIO_PCI_FLAG_BUS_MASTER_BUG)) {
460 virtio_pci_stop_ioeventfd(proxy);
461 virtio_set_status(proxy->vdev,
462 proxy->vdev->status & ~VIRTIO_CONFIG_S_DRIVER_OK);
ed757e14 463 }
53c25cea
PB
464}
465
6d74ca5a
MT
466static unsigned virtio_pci_get_features(void *opaque)
467{
8172539d
MT
468 VirtIOPCIProxy *proxy = opaque;
469 return proxy->host_features;
6d74ca5a
MT
470}
471
7d37d351
JK
472static int kvm_virtio_pci_vq_vector_use(VirtIOPCIProxy *proxy,
473 unsigned int queue_no,
474 unsigned int vector,
475 MSIMessage msg)
476{
477 VirtQueue *vq = virtio_get_queue(proxy->vdev, queue_no);
15b2bd18 478 EventNotifier *n = virtio_queue_get_guest_notifier(vq);
7d37d351 479 VirtIOIRQFD *irqfd = &proxy->vector_irqfd[vector];
15b2bd18 480 int ret;
7d37d351
JK
481
482 if (irqfd->users == 0) {
483 ret = kvm_irqchip_add_msi_route(kvm_state, msg);
484 if (ret < 0) {
485 return ret;
486 }
487 irqfd->virq = ret;
488 }
489 irqfd->users++;
490
b131c74a 491 ret = kvm_irqchip_add_irqfd_notifier(kvm_state, n, irqfd->virq);
7d37d351
JK
492 if (ret < 0) {
493 if (--irqfd->users == 0) {
494 kvm_irqchip_release_virq(kvm_state, irqfd->virq);
495 }
496 return ret;
497 }
498
15b2bd18 499 virtio_queue_set_guest_notifier_fd_handler(vq, true, true);
7d37d351
JK
500 return 0;
501}
502
503static void kvm_virtio_pci_vq_vector_release(VirtIOPCIProxy *proxy,
504 unsigned int queue_no,
505 unsigned int vector)
506{
507 VirtQueue *vq = virtio_get_queue(proxy->vdev, queue_no);
15b2bd18 508 EventNotifier *n = virtio_queue_get_guest_notifier(vq);
7d37d351 509 VirtIOIRQFD *irqfd = &proxy->vector_irqfd[vector];
15b2bd18 510 int ret;
7d37d351 511
b131c74a 512 ret = kvm_irqchip_remove_irqfd_notifier(kvm_state, n, irqfd->virq);
7d37d351
JK
513 assert(ret == 0);
514
515 if (--irqfd->users == 0) {
516 kvm_irqchip_release_virq(kvm_state, irqfd->virq);
517 }
518
15b2bd18 519 virtio_queue_set_guest_notifier_fd_handler(vq, true, false);
7d37d351
JK
520}
521
522static int kvm_virtio_pci_vector_use(PCIDevice *dev, unsigned vector,
523 MSIMessage msg)
524{
525 VirtIOPCIProxy *proxy = container_of(dev, VirtIOPCIProxy, pci_dev);
526 VirtIODevice *vdev = proxy->vdev;
527 int ret, queue_no;
528
529 for (queue_no = 0; queue_no < VIRTIO_PCI_QUEUE_MAX; queue_no++) {
530 if (!virtio_queue_get_num(vdev, queue_no)) {
531 break;
532 }
533 if (virtio_queue_vector(vdev, queue_no) != vector) {
534 continue;
535 }
536 ret = kvm_virtio_pci_vq_vector_use(proxy, queue_no, vector, msg);
537 if (ret < 0) {
538 goto undo;
539 }
540 }
541 return 0;
542
543undo:
544 while (--queue_no >= 0) {
545 if (virtio_queue_vector(vdev, queue_no) != vector) {
546 continue;
547 }
548 kvm_virtio_pci_vq_vector_release(proxy, queue_no, vector);
549 }
550 return ret;
551}
552
553static void kvm_virtio_pci_vector_release(PCIDevice *dev, unsigned vector)
554{
555 VirtIOPCIProxy *proxy = container_of(dev, VirtIOPCIProxy, pci_dev);
556 VirtIODevice *vdev = proxy->vdev;
557 int queue_no;
558
559 for (queue_no = 0; queue_no < VIRTIO_PCI_QUEUE_MAX; queue_no++) {
560 if (!virtio_queue_get_num(vdev, queue_no)) {
561 break;
562 }
563 if (virtio_queue_vector(vdev, queue_no) != vector) {
564 continue;
565 }
566 kvm_virtio_pci_vq_vector_release(proxy, queue_no, vector);
567 }
568}
569
ade80dc8
MT
570static int virtio_pci_set_guest_notifier(void *opaque, int n, bool assign)
571{
572 VirtIOPCIProxy *proxy = opaque;
573 VirtQueue *vq = virtio_get_queue(proxy->vdev, n);
574 EventNotifier *notifier = virtio_queue_get_guest_notifier(vq);
575
576 if (assign) {
577 int r = event_notifier_init(notifier, 0);
578 if (r < 0) {
579 return r;
580 }
15b2bd18 581 virtio_queue_set_guest_notifier_fd_handler(vq, true, false);
ade80dc8 582 } else {
15b2bd18 583 virtio_queue_set_guest_notifier_fd_handler(vq, false, false);
ade80dc8
MT
584 event_notifier_cleanup(notifier);
585 }
586
587 return 0;
588}
589
5430a28f
MT
590static bool virtio_pci_query_guest_notifiers(void *opaque)
591{
592 VirtIOPCIProxy *proxy = opaque;
593 return msix_enabled(&proxy->pci_dev);
594}
595
54dd9321
MT
596static int virtio_pci_set_guest_notifiers(void *opaque, bool assign)
597{
598 VirtIOPCIProxy *proxy = opaque;
599 VirtIODevice *vdev = proxy->vdev;
600 int r, n;
601
7d37d351 602 /* Must unset vector notifier while guest notifier is still assigned */
614e41bc 603 if (kvm_msi_via_irqfd_enabled() && !assign) {
7d37d351
JK
604 msix_unset_vector_notifiers(&proxy->pci_dev);
605 g_free(proxy->vector_irqfd);
606 proxy->vector_irqfd = NULL;
607 }
608
54dd9321
MT
609 for (n = 0; n < VIRTIO_PCI_QUEUE_MAX; n++) {
610 if (!virtio_queue_get_num(vdev, n)) {
611 break;
612 }
613
614 r = virtio_pci_set_guest_notifier(opaque, n, assign);
615 if (r < 0) {
616 goto assign_error;
617 }
618 }
619
7d37d351 620 /* Must set vector notifier after guest notifier has been assigned */
614e41bc 621 if (kvm_msi_via_irqfd_enabled() && assign) {
7d37d351
JK
622 proxy->vector_irqfd =
623 g_malloc0(sizeof(*proxy->vector_irqfd) *
624 msix_nr_vectors_allocated(&proxy->pci_dev));
625 r = msix_set_vector_notifiers(&proxy->pci_dev,
626 kvm_virtio_pci_vector_use,
627 kvm_virtio_pci_vector_release);
628 if (r < 0) {
629 goto assign_error;
630 }
631 }
632
54dd9321
MT
633 return 0;
634
635assign_error:
636 /* We get here on assignment failure. Recover by undoing for VQs 0 .. n. */
7d37d351 637 assert(assign);
54dd9321
MT
638 while (--n >= 0) {
639 virtio_pci_set_guest_notifier(opaque, n, !assign);
640 }
641 return r;
642}
643
ade80dc8
MT
644static int virtio_pci_set_host_notifier(void *opaque, int n, bool assign)
645{
646 VirtIOPCIProxy *proxy = opaque;
25db9ebe
SH
647
648 /* Stop using ioeventfd for virtqueue kick if the device starts using host
649 * notifiers. This makes it easy to avoid stepping on each others' toes.
650 */
651 proxy->ioeventfd_disabled = assign;
ade80dc8 652 if (assign) {
25db9ebe
SH
653 virtio_pci_stop_ioeventfd(proxy);
654 }
655 /* We don't need to start here: it's not needed because backend
656 * currently only stops on status change away from ok,
657 * reset, vmstop and such. If we do add code to start here,
658 * need to check vmstate, device state etc. */
26b9b5fe 659 return virtio_pci_set_host_notifier_internal(proxy, n, assign, false);
25db9ebe
SH
660}
661
662static void virtio_pci_vmstate_change(void *opaque, bool running)
663{
664 VirtIOPCIProxy *proxy = opaque;
665
666 if (running) {
89c473fd
MT
667 /* Try to find out if the guest has bus master disabled, but is
668 in ready state. Then we have a buggy guest OS. */
669 if ((proxy->vdev->status & VIRTIO_CONFIG_S_DRIVER_OK) &&
670 !(proxy->pci_dev.config[PCI_COMMAND] & PCI_COMMAND_MASTER)) {
671 proxy->flags |= VIRTIO_PCI_FLAG_BUS_MASTER_BUG;
672 }
25db9ebe 673 virtio_pci_start_ioeventfd(proxy);
ade80dc8 674 } else {
25db9ebe 675 virtio_pci_stop_ioeventfd(proxy);
ade80dc8 676 }
ade80dc8
MT
677}
678
53c25cea 679static const VirtIOBindings virtio_pci_bindings = {
ff24bd58
MT
680 .notify = virtio_pci_notify,
681 .save_config = virtio_pci_save_config,
682 .load_config = virtio_pci_load_config,
683 .save_queue = virtio_pci_save_queue,
684 .load_queue = virtio_pci_load_queue,
6d74ca5a 685 .get_features = virtio_pci_get_features,
5430a28f 686 .query_guest_notifiers = virtio_pci_query_guest_notifiers,
ade80dc8 687 .set_host_notifier = virtio_pci_set_host_notifier,
54dd9321 688 .set_guest_notifiers = virtio_pci_set_guest_notifiers,
25db9ebe 689 .vmstate_change = virtio_pci_vmstate_change,
53c25cea
PB
690};
691
befeac45 692void virtio_init_pci(VirtIOPCIProxy *proxy, VirtIODevice *vdev)
53c25cea
PB
693{
694 uint8_t *config;
695 uint32_t size;
696
697 proxy->vdev = vdev;
698
699 config = proxy->pci_dev.config;
53c25cea 700
e75ccf2c
IY
701 if (proxy->class_code) {
702 pci_config_set_class(config, proxy->class_code);
703 }
ad3d11e6
HKR
704 pci_set_word(config + PCI_SUBSYSTEM_VENDOR_ID,
705 pci_get_word(config + PCI_VENDOR_ID));
706 pci_set_word(config + PCI_SUBSYSTEM_ID, vdev->device_id);
707 config[PCI_INTERRUPT_PIN] = 1;
53c25cea 708
b2357c48
AW
709 if (vdev->nvectors &&
710 msix_init_exclusive_bar(&proxy->pci_dev, vdev->nvectors, 1)) {
aba800a3 711 vdev->nvectors = 0;
b2357c48 712 }
aba800a3 713
ed757e14
YV
714 proxy->pci_dev.config_write = virtio_write_config;
715
aba800a3 716 size = VIRTIO_PCI_REGION_SIZE(&proxy->pci_dev) + vdev->config_len;
53c25cea
PB
717 if (size & (size-1))
718 size = 1 << qemu_fls(size);
719
da146d0a
AK
720 memory_region_init_io(&proxy->bar, &virtio_pci_config_ops, proxy,
721 "virtio-pci", size);
e824b2cc
AK
722 pci_register_bar(&proxy->pci_dev, 0, PCI_BASE_ADDRESS_SPACE_IO,
723 &proxy->bar);
53c25cea 724
25db9ebe
SH
725 if (!kvm_has_many_ioeventfds()) {
726 proxy->flags &= ~VIRTIO_PCI_FLAG_USE_IOEVENTFD;
727 }
728
53c25cea 729 virtio_bind_device(vdev, &virtio_pci_bindings, proxy);
8172539d
MT
730 proxy->host_features |= 0x1 << VIRTIO_F_NOTIFY_ON_EMPTY;
731 proxy->host_features |= 0x1 << VIRTIO_F_BAD_FEATURE;
732 proxy->host_features = vdev->get_features(vdev, proxy->host_features);
53c25cea
PB
733}
734
81a322d4 735static int virtio_blk_init_pci(PCIDevice *pci_dev)
53c25cea
PB
736{
737 VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
738 VirtIODevice *vdev;
739
ab73ff29
GH
740 if (proxy->class_code != PCI_CLASS_STORAGE_SCSI &&
741 proxy->class_code != PCI_CLASS_STORAGE_OTHER)
742 proxy->class_code = PCI_CLASS_STORAGE_SCSI;
53c25cea 743
12c5674b 744 vdev = virtio_blk_init(&pci_dev->qdev, &proxy->blk);
ac0c14d7
MA
745 if (!vdev) {
746 return -1;
747 }
177539e0 748 vdev->nvectors = proxy->nvectors;
e75ccf2c 749 virtio_init_pci(proxy, vdev);
177539e0
GH
750 /* make the actual value visible */
751 proxy->nvectors = vdev->nvectors;
81a322d4 752 return 0;
21d58b57
MM
753}
754
f90c2bcd 755static void virtio_exit_pci(PCIDevice *pci_dev)
0f457d91 756{
da146d0a
AK
757 VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
758
759 memory_region_destroy(&proxy->bar);
b2357c48 760 msix_uninit_exclusive_bar(pci_dev);
0f457d91
MT
761}
762
f90c2bcd 763static void virtio_blk_exit_pci(PCIDevice *pci_dev)
56a14938
GH
764{
765 VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
766
25db9ebe 767 virtio_pci_stop_ioeventfd(proxy);
9d0d3138 768 virtio_blk_exit(proxy->vdev);
f90c2bcd 769 virtio_exit_pci(pci_dev);
56a14938
GH
770}
771
98b19252 772static int virtio_serial_init_pci(PCIDevice *pci_dev)
21d58b57 773{
d6beee99 774 VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
85c2c735
MM
775 VirtIODevice *vdev;
776
d6beee99
GH
777 if (proxy->class_code != PCI_CLASS_COMMUNICATION_OTHER &&
778 proxy->class_code != PCI_CLASS_DISPLAY_OTHER && /* qemu 0.10 */
779 proxy->class_code != PCI_CLASS_OTHERS) /* qemu-kvm */
780 proxy->class_code = PCI_CLASS_COMMUNICATION_OTHER;
781
6b331efb 782 vdev = virtio_serial_init(&pci_dev->qdev, &proxy->serial);
25fe3654
AS
783 if (!vdev) {
784 return -1;
785 }
573fb60c 786 vdev->nvectors = proxy->nvectors == DEV_NVECTORS_UNSPECIFIED
6b331efb 787 ? proxy->serial.max_virtserial_ports + 1
573fb60c 788 : proxy->nvectors;
e75ccf2c 789 virtio_init_pci(proxy, vdev);
a1829205 790 proxy->nvectors = vdev->nvectors;
81a322d4 791 return 0;
53c25cea
PB
792}
793
f90c2bcd 794static void virtio_serial_exit_pci(PCIDevice *pci_dev)
8b53a865
AS
795{
796 VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
797
32059220 798 virtio_pci_stop_ioeventfd(proxy);
8b53a865 799 virtio_serial_exit(proxy->vdev);
f90c2bcd 800 virtio_exit_pci(pci_dev);
8b53a865
AS
801}
802
81a322d4 803static int virtio_net_init_pci(PCIDevice *pci_dev)
53c25cea
PB
804{
805 VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
806 VirtIODevice *vdev;
807
f0c07c7c 808 vdev = virtio_net_init(&pci_dev->qdev, &proxy->nic, &proxy->net);
a1e0fea5 809
97b15621 810 vdev->nvectors = proxy->nvectors;
e75ccf2c 811 virtio_init_pci(proxy, vdev);
a1e0fea5
GH
812
813 /* make the actual value visible */
814 proxy->nvectors = vdev->nvectors;
81a322d4 815 return 0;
53c25cea
PB
816}
817
f90c2bcd 818static void virtio_net_exit_pci(PCIDevice *pci_dev)
97b15621
GH
819{
820 VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
821
25db9ebe 822 virtio_pci_stop_ioeventfd(proxy);
97b15621 823 virtio_net_exit(proxy->vdev);
f90c2bcd 824 virtio_exit_pci(pci_dev);
97b15621
GH
825}
826
81a322d4 827static int virtio_balloon_init_pci(PCIDevice *pci_dev)
53c25cea
PB
828{
829 VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
830 VirtIODevice *vdev;
831
2ba1d381
DG
832 if (proxy->class_code != PCI_CLASS_OTHERS &&
833 proxy->class_code != PCI_CLASS_MEMORY_RAM) { /* qemu < 1.1 */
834 proxy->class_code = PCI_CLASS_OTHERS;
835 }
836
53c25cea 837 vdev = virtio_balloon_init(&pci_dev->qdev);
f76f6655
AS
838 if (!vdev) {
839 return -1;
840 }
e75ccf2c 841 virtio_init_pci(proxy, vdev);
81a322d4 842 return 0;
53c25cea
PB
843}
844
f90c2bcd 845static void virtio_balloon_exit_pci(PCIDevice *pci_dev)
855d7e25
AS
846{
847 VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
848
849 virtio_pci_stop_ioeventfd(proxy);
850 virtio_balloon_exit(proxy->vdev);
f90c2bcd 851 virtio_exit_pci(pci_dev);
855d7e25
AS
852}
853
16c915ba
AS
854static int virtio_rng_init_pci(PCIDevice *pci_dev)
855{
856 VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
857 VirtIODevice *vdev;
858
500054f1
AL
859 if (proxy->rng.rng == NULL) {
860 proxy->rng.default_backend = RNG_RANDOM(object_new(TYPE_RNG_RANDOM));
861
862 object_property_add_child(OBJECT(pci_dev),
863 "default-backend",
864 OBJECT(proxy->rng.default_backend),
865 NULL);
866
867 object_property_set_link(OBJECT(pci_dev),
868 OBJECT(proxy->rng.default_backend),
869 "rng", NULL);
870 }
871
16c915ba
AS
872 vdev = virtio_rng_init(&pci_dev->qdev, &proxy->rng);
873 if (!vdev) {
874 return -1;
875 }
876 virtio_init_pci(proxy, vdev);
877 return 0;
878}
879
880static void virtio_rng_exit_pci(PCIDevice *pci_dev)
881{
882 VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
883
884 virtio_pci_stop_ioeventfd(proxy);
885 virtio_rng_exit(proxy->vdev);
886 virtio_exit_pci(pci_dev);
887}
888
40021f08
AL
889static Property virtio_blk_properties[] = {
890 DEFINE_PROP_HEX32("class", VirtIOPCIProxy, class_code, 0),
12c5674b 891 DEFINE_BLOCK_PROPERTIES(VirtIOPCIProxy, blk.conf),
e63e7fde 892 DEFINE_BLOCK_CHS_PROPERTIES(VirtIOPCIProxy, blk.conf),
12c5674b 893 DEFINE_PROP_STRING("serial", VirtIOPCIProxy, blk.serial),
a6c5c84a
PB
894#ifdef __linux__
895 DEFINE_PROP_BIT("scsi", VirtIOPCIProxy, blk.scsi, 0, true),
896#endif
40021f08
AL
897 DEFINE_PROP_BIT("ioeventfd", VirtIOPCIProxy, flags, VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, true),
898 DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, 2),
899 DEFINE_VIRTIO_BLK_FEATURES(VirtIOPCIProxy, host_features),
900 DEFINE_PROP_END_OF_LIST(),
e855761c
AL
901};
902
40021f08
AL
903static void virtio_blk_class_init(ObjectClass *klass, void *data)
904{
39bffca2 905 DeviceClass *dc = DEVICE_CLASS(klass);
40021f08
AL
906 PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
907
908 k->init = virtio_blk_init_pci;
909 k->exit = virtio_blk_exit_pci;
910 k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;
911 k->device_id = PCI_DEVICE_ID_VIRTIO_BLOCK;
912 k->revision = VIRTIO_PCI_ABI_VERSION;
913 k->class_id = PCI_CLASS_STORAGE_SCSI;
39bffca2
AL
914 dc->reset = virtio_pci_reset;
915 dc->props = virtio_blk_properties;
40021f08
AL
916}
917
39bffca2
AL
918static TypeInfo virtio_blk_info = {
919 .name = "virtio-blk-pci",
920 .parent = TYPE_PCI_DEVICE,
921 .instance_size = sizeof(VirtIOPCIProxy),
922 .class_init = virtio_blk_class_init,
40021f08
AL
923};
924
925static Property virtio_net_properties[] = {
926 DEFINE_PROP_BIT("ioeventfd", VirtIOPCIProxy, flags, VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, false),
927 DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, 3),
928 DEFINE_VIRTIO_NET_FEATURES(VirtIOPCIProxy, host_features),
929 DEFINE_NIC_PROPERTIES(VirtIOPCIProxy, nic),
930 DEFINE_PROP_UINT32("x-txtimer", VirtIOPCIProxy, net.txtimer, TX_TIMER_INTERVAL),
931 DEFINE_PROP_INT32("x-txburst", VirtIOPCIProxy, net.txburst, TX_BURST),
932 DEFINE_PROP_STRING("tx", VirtIOPCIProxy, net.tx),
933 DEFINE_PROP_END_OF_LIST(),
934};
935
936static void virtio_net_class_init(ObjectClass *klass, void *data)
937{
39bffca2 938 DeviceClass *dc = DEVICE_CLASS(klass);
40021f08
AL
939 PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
940
941 k->init = virtio_net_init_pci;
942 k->exit = virtio_net_exit_pci;
943 k->romfile = "pxe-virtio.rom";
944 k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;
945 k->device_id = PCI_DEVICE_ID_VIRTIO_NET;
946 k->revision = VIRTIO_PCI_ABI_VERSION;
947 k->class_id = PCI_CLASS_NETWORK_ETHERNET;
39bffca2
AL
948 dc->reset = virtio_pci_reset;
949 dc->props = virtio_net_properties;
40021f08
AL
950}
951
39bffca2
AL
952static TypeInfo virtio_net_info = {
953 .name = "virtio-net-pci",
954 .parent = TYPE_PCI_DEVICE,
955 .instance_size = sizeof(VirtIOPCIProxy),
956 .class_init = virtio_net_class_init,
e855761c
AL
957};
958
40021f08
AL
959static Property virtio_serial_properties[] = {
960 DEFINE_PROP_BIT("ioeventfd", VirtIOPCIProxy, flags, VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, true),
961 DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, DEV_NVECTORS_UNSPECIFIED),
962 DEFINE_PROP_HEX32("class", VirtIOPCIProxy, class_code, 0),
963 DEFINE_VIRTIO_COMMON_FEATURES(VirtIOPCIProxy, host_features),
964 DEFINE_PROP_UINT32("max_ports", VirtIOPCIProxy, serial.max_virtserial_ports, 31),
965 DEFINE_PROP_END_OF_LIST(),
e855761c
AL
966};
967
40021f08
AL
968static void virtio_serial_class_init(ObjectClass *klass, void *data)
969{
39bffca2 970 DeviceClass *dc = DEVICE_CLASS(klass);
40021f08
AL
971 PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
972
973 k->init = virtio_serial_init_pci;
974 k->exit = virtio_serial_exit_pci;
975 k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;
976 k->device_id = PCI_DEVICE_ID_VIRTIO_CONSOLE;
977 k->revision = VIRTIO_PCI_ABI_VERSION;
978 k->class_id = PCI_CLASS_COMMUNICATION_OTHER;
39bffca2
AL
979 dc->reset = virtio_pci_reset;
980 dc->props = virtio_serial_properties;
40021f08
AL
981}
982
39bffca2
AL
983static TypeInfo virtio_serial_info = {
984 .name = "virtio-serial-pci",
985 .parent = TYPE_PCI_DEVICE,
986 .instance_size = sizeof(VirtIOPCIProxy),
987 .class_init = virtio_serial_class_init,
40021f08
AL
988};
989
990static Property virtio_balloon_properties[] = {
991 DEFINE_VIRTIO_COMMON_FEATURES(VirtIOPCIProxy, host_features),
2ba1d381 992 DEFINE_PROP_HEX32("class", VirtIOPCIProxy, class_code, 0),
40021f08
AL
993 DEFINE_PROP_END_OF_LIST(),
994};
995
996static void virtio_balloon_class_init(ObjectClass *klass, void *data)
997{
39bffca2 998 DeviceClass *dc = DEVICE_CLASS(klass);
40021f08
AL
999 PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
1000
1001 k->init = virtio_balloon_init_pci;
1002 k->exit = virtio_balloon_exit_pci;
1003 k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;
1004 k->device_id = PCI_DEVICE_ID_VIRTIO_BALLOON;
1005 k->revision = VIRTIO_PCI_ABI_VERSION;
2ba1d381 1006 k->class_id = PCI_CLASS_OTHERS;
39bffca2
AL
1007 dc->reset = virtio_pci_reset;
1008 dc->props = virtio_balloon_properties;
40021f08
AL
1009}
1010
39bffca2
AL
1011static TypeInfo virtio_balloon_info = {
1012 .name = "virtio-balloon-pci",
1013 .parent = TYPE_PCI_DEVICE,
1014 .instance_size = sizeof(VirtIOPCIProxy),
1015 .class_init = virtio_balloon_class_init,
0aab0d3a
GH
1016};
1017
16c915ba
AS
1018static void virtio_rng_initfn(Object *obj)
1019{
1020 PCIDevice *pci_dev = PCI_DEVICE(obj);
1021 VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
1022
1023 object_property_add_link(obj, "rng", TYPE_RNG_BACKEND,
1024 (Object **)&proxy->rng.rng, NULL);
1025}
1026
1027static Property virtio_rng_properties[] = {
1028 DEFINE_VIRTIO_COMMON_FEATURES(VirtIOPCIProxy, host_features),
904d6f58
AL
1029 /* Set a default rate limit of 2^47 bytes per minute or roughly 2TB/s. If
1030 you have an entropy source capable of generating more entropy than this
1031 and you can pass it through via virtio-rng, then hats off to you. Until
1032 then, this is unlimited for all practical purposes.
1033 */
1034 DEFINE_PROP_UINT64("max-bytes", VirtIOPCIProxy, rng.max_bytes, INT64_MAX),
1035 DEFINE_PROP_UINT32("period", VirtIOPCIProxy, rng.period_ms, 1 << 16),
16c915ba
AS
1036 DEFINE_PROP_END_OF_LIST(),
1037};
1038
1039static void virtio_rng_class_init(ObjectClass *klass, void *data)
1040{
1041 DeviceClass *dc = DEVICE_CLASS(klass);
1042 PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
1043
1044 k->init = virtio_rng_init_pci;
1045 k->exit = virtio_rng_exit_pci;
1046 k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;
1047 k->device_id = PCI_DEVICE_ID_VIRTIO_RNG;
1048 k->revision = VIRTIO_PCI_ABI_VERSION;
1049 k->class_id = PCI_CLASS_OTHERS;
1050 dc->reset = virtio_pci_reset;
1051 dc->props = virtio_rng_properties;
1052}
1053
1054static TypeInfo virtio_rng_info = {
1055 .name = "virtio-rng-pci",
1056 .parent = TYPE_PCI_DEVICE,
1057 .instance_size = sizeof(VirtIOPCIProxy),
1058 .instance_init = virtio_rng_initfn,
1059 .class_init = virtio_rng_class_init,
1060};
1061
973abc7f
SH
1062static int virtio_scsi_init_pci(PCIDevice *pci_dev)
1063{
1064 VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
1065 VirtIODevice *vdev;
1066
1067 vdev = virtio_scsi_init(&pci_dev->qdev, &proxy->scsi);
1068 if (!vdev) {
1069 return -EINVAL;
1070 }
1071
4c205d0c
PB
1072 vdev->nvectors = proxy->nvectors == DEV_NVECTORS_UNSPECIFIED
1073 ? proxy->scsi.num_queues + 3
1074 : proxy->nvectors;
973abc7f
SH
1075 virtio_init_pci(proxy, vdev);
1076
1077 /* make the actual value visible */
1078 proxy->nvectors = vdev->nvectors;
1079 return 0;
1080}
1081
f90c2bcd 1082static void virtio_scsi_exit_pci(PCIDevice *pci_dev)
973abc7f
SH
1083{
1084 VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
1085
1086 virtio_scsi_exit(proxy->vdev);
f90c2bcd 1087 virtio_exit_pci(pci_dev);
973abc7f
SH
1088}
1089
1090static Property virtio_scsi_properties[] = {
3f910904 1091 DEFINE_PROP_BIT("ioeventfd", VirtIOPCIProxy, flags, VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, true),
4c205d0c 1092 DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, DEV_NVECTORS_UNSPECIFIED),
973abc7f
SH
1093 DEFINE_VIRTIO_SCSI_PROPERTIES(VirtIOPCIProxy, host_features, scsi),
1094 DEFINE_PROP_END_OF_LIST(),
1095};
1096
1097static void virtio_scsi_class_init(ObjectClass *klass, void *data)
1098{
1099 DeviceClass *dc = DEVICE_CLASS(klass);
1100 PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
1101
1102 k->init = virtio_scsi_init_pci;
1103 k->exit = virtio_scsi_exit_pci;
1104 k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;
1105 k->device_id = PCI_DEVICE_ID_VIRTIO_SCSI;
1106 k->revision = 0x00;
1107 k->class_id = PCI_CLASS_STORAGE_SCSI;
1108 dc->reset = virtio_pci_reset;
1109 dc->props = virtio_scsi_properties;
1110}
1111
1112static TypeInfo virtio_scsi_info = {
1113 .name = "virtio-scsi-pci",
1114 .parent = TYPE_PCI_DEVICE,
1115 .instance_size = sizeof(VirtIOPCIProxy),
1116 .class_init = virtio_scsi_class_init,
1117};
1118
83f7d43a 1119static void virtio_pci_register_types(void)
53c25cea 1120{
39bffca2 1121 type_register_static(&virtio_blk_info);
39bffca2 1122 type_register_static(&virtio_net_info);
39bffca2 1123 type_register_static(&virtio_serial_info);
39bffca2 1124 type_register_static(&virtio_balloon_info);
973abc7f 1125 type_register_static(&virtio_scsi_info);
16c915ba 1126 type_register_static(&virtio_rng_info);
53c25cea
PB
1127}
1128
83f7d43a 1129type_init(virtio_pci_register_types)