Commit 7055e687cd4cea5befefb2d8012e4e2574cfa9b3

Authored by Michael S. Tsirkin
Committed by Anthony Liguori
1 parent 54c96da7

qemu/virtio: virtio support for many interrupt vectors

Extend virtio to support many interrupt vectors, and rearrange code in
preparation for multi-vector support (mostly move reset out to bindings,
because we will have to reset the vectors in transport-specific code).
Actual bindings in pci, and use in net, to follow.
Load and save are not connected to bindings yet, so they are left
stubbed out for now.

Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
hw/syborg_virtio.c
@@ -134,7 +134,10 @@ static void syborg_virtio_writel(void *opaque, target_phys_addr_t offset, @@ -134,7 +134,10 @@ static void syborg_virtio_writel(void *opaque, target_phys_addr_t offset,
134 vdev->features = value; 134 vdev->features = value;
135 break; 135 break;
136 case SYBORG_VIRTIO_QUEUE_BASE: 136 case SYBORG_VIRTIO_QUEUE_BASE:
137 - virtio_queue_set_addr(vdev, vdev->queue_sel, value); 137 + if (value == 0)
  138 + virtio_reset(vdev);
  139 + else
  140 + virtio_queue_set_addr(vdev, vdev->queue_sel, value);
138 break; 141 break;
139 case SYBORG_VIRTIO_QUEUE_SEL: 142 case SYBORG_VIRTIO_QUEUE_SEL:
140 if (value < VIRTIO_PCI_QUEUE_MAX) 143 if (value < VIRTIO_PCI_QUEUE_MAX)
@@ -228,7 +231,7 @@ static CPUWriteMemoryFunc *syborg_virtio_writefn[] = { @@ -228,7 +231,7 @@ static CPUWriteMemoryFunc *syborg_virtio_writefn[] = {
228 syborg_virtio_writel 231 syborg_virtio_writel
229 }; 232 };
230 233
231 -static void syborg_virtio_update_irq(void *opaque) 234 +static void syborg_virtio_update_irq(void *opaque, uint16_t vector)
232 { 235 {
233 SyborgVirtIOProxy *proxy = opaque; 236 SyborgVirtIOProxy *proxy = opaque;
234 int level; 237 int level;
@@ -239,7 +242,7 @@ static void syborg_virtio_update_irq(void *opaque) @@ -239,7 +242,7 @@ static void syborg_virtio_update_irq(void *opaque)
239 } 242 }
240 243
241 static VirtIOBindings syborg_virtio_bindings = { 244 static VirtIOBindings syborg_virtio_bindings = {
242 - .update_irq = syborg_virtio_update_irq 245 + .notify = syborg_virtio_update_irq
243 }; 246 };
244 247
245 static void syborg_virtio_init(SyborgVirtIOProxy *proxy, VirtIODevice *vdev) 248 static void syborg_virtio_init(SyborgVirtIOProxy *proxy, VirtIODevice *vdev)
@@ -248,6 +251,8 @@ static void syborg_virtio_init(SyborgVirtIOProxy *proxy, VirtIODevice *vdev) @@ -248,6 +251,8 @@ static void syborg_virtio_init(SyborgVirtIOProxy *proxy, VirtIODevice *vdev)
248 251
249 proxy->vdev = vdev; 252 proxy->vdev = vdev;
250 253
  254 + /* Don't support multiple vectors */
  255 + proxy->vdev->nvectors = 0;
251 sysbus_init_irq(&proxy->busdev, &proxy->irq); 256 sysbus_init_irq(&proxy->busdev, &proxy->irq);
252 iomemtype = cpu_register_io_memory(syborg_virtio_readfn, 257 iomemtype = cpu_register_io_memory(syborg_virtio_readfn,
253 syborg_virtio_writefn, proxy); 258 syborg_virtio_writefn, proxy);
@@ -255,6 +260,8 @@ static void syborg_virtio_init(SyborgVirtIOProxy *proxy, VirtIODevice *vdev) @@ -255,6 +260,8 @@ static void syborg_virtio_init(SyborgVirtIOProxy *proxy, VirtIODevice *vdev)
255 260
256 proxy->id = ((uint32_t)0x1af4 << 16) | vdev->device_id; 261 proxy->id = ((uint32_t)0x1af4 << 16) | vdev->device_id;
257 262
  263 + qemu_register_reset(virtio_reset, 0, vdev);
  264 +
258 virtio_bind_device(vdev, &syborg_virtio_bindings, proxy); 265 virtio_bind_device(vdev, &syborg_virtio_bindings, proxy);
259 } 266 }
260 267
hw/virtio-pci.c
@@ -78,13 +78,19 @@ typedef struct { @@ -78,13 +78,19 @@ typedef struct {
78 78
79 /* virtio device */ 79 /* virtio device */
80 80
81 -static void virtio_pci_update_irq(void *opaque) 81 +static void virtio_pci_notify(void *opaque, uint16_t vector)
82 { 82 {
83 VirtIOPCIProxy *proxy = opaque; 83 VirtIOPCIProxy *proxy = opaque;
84 84
85 qemu_set_irq(proxy->pci_dev.irq[0], proxy->vdev->isr & 1); 85 qemu_set_irq(proxy->pci_dev.irq[0], proxy->vdev->isr & 1);
86 } 86 }
87 87
  88 +static void virtio_pci_reset(void *opaque)
  89 +{
  90 + VirtIOPCIProxy *proxy = opaque;
  91 + virtio_reset(proxy->vdev);
  92 +}
  93 +
88 static void virtio_ioport_write(void *opaque, uint32_t addr, uint32_t val) 94 static void virtio_ioport_write(void *opaque, uint32_t addr, uint32_t val)
89 { 95 {
90 VirtIOPCIProxy *proxy = opaque; 96 VirtIOPCIProxy *proxy = opaque;
@@ -108,7 +114,10 @@ static void virtio_ioport_write(void *opaque, uint32_t addr, uint32_t val) @@ -108,7 +114,10 @@ static void virtio_ioport_write(void *opaque, uint32_t addr, uint32_t val)
108 break; 114 break;
109 case VIRTIO_PCI_QUEUE_PFN: 115 case VIRTIO_PCI_QUEUE_PFN:
110 pa = (target_phys_addr_t)val << VIRTIO_PCI_QUEUE_ADDR_SHIFT; 116 pa = (target_phys_addr_t)val << VIRTIO_PCI_QUEUE_ADDR_SHIFT;
111 - virtio_queue_set_addr(vdev, vdev->queue_sel, pa); 117 + if (pa == 0)
  118 + virtio_pci_reset(proxy);
  119 + else
  120 + virtio_queue_set_addr(vdev, vdev->queue_sel, pa);
112 break; 121 break;
113 case VIRTIO_PCI_QUEUE_SEL: 122 case VIRTIO_PCI_QUEUE_SEL:
114 if (val < VIRTIO_PCI_QUEUE_MAX) 123 if (val < VIRTIO_PCI_QUEUE_MAX)
@@ -120,7 +129,7 @@ static void virtio_ioport_write(void *opaque, uint32_t addr, uint32_t val) @@ -120,7 +129,7 @@ static void virtio_ioport_write(void *opaque, uint32_t addr, uint32_t val)
120 case VIRTIO_PCI_STATUS: 129 case VIRTIO_PCI_STATUS:
121 vdev->status = val & 0xFF; 130 vdev->status = val & 0xFF;
122 if (vdev->status == 0) 131 if (vdev->status == 0)
123 - virtio_reset(vdev); 132 + virtio_pci_reset(proxy);
124 break; 133 break;
125 } 134 }
126 } 135 }
@@ -160,7 +169,7 @@ static uint32_t virtio_ioport_read(void *opaque, uint32_t addr) @@ -160,7 +169,7 @@ static uint32_t virtio_ioport_read(void *opaque, uint32_t addr)
160 /* reading from the ISR also clears it. */ 169 /* reading from the ISR also clears it. */
161 ret = vdev->isr; 170 ret = vdev->isr;
162 vdev->isr = 0; 171 vdev->isr = 0;
163 - virtio_update_irq(vdev); 172 + qemu_set_irq(proxy->pci_dev.irq[0], 0);
164 break; 173 break;
165 default: 174 default:
166 break; 175 break;
@@ -245,7 +254,7 @@ static void virtio_map(PCIDevice *pci_dev, int region_num, @@ -245,7 +254,7 @@ static void virtio_map(PCIDevice *pci_dev, int region_num,
245 } 254 }
246 255
247 static const VirtIOBindings virtio_pci_bindings = { 256 static const VirtIOBindings virtio_pci_bindings = {
248 - .update_irq = virtio_pci_update_irq 257 + .notify = virtio_pci_notify
249 }; 258 };
250 259
251 static void virtio_init_pci(VirtIOPCIProxy *proxy, VirtIODevice *vdev, 260 static void virtio_init_pci(VirtIOPCIProxy *proxy, VirtIODevice *vdev,
@@ -257,6 +266,9 @@ static void virtio_init_pci(VirtIOPCIProxy *proxy, VirtIODevice *vdev, @@ -257,6 +266,9 @@ static void virtio_init_pci(VirtIOPCIProxy *proxy, VirtIODevice *vdev,
257 266
258 proxy->vdev = vdev; 267 proxy->vdev = vdev;
259 268
  269 + /* No support for multiple vectors yet. */
  270 + proxy->vdev->nvectors = 0;
  271 +
260 config = proxy->pci_dev.config; 272 config = proxy->pci_dev.config;
261 pci_config_set_vendor_id(config, vendor); 273 pci_config_set_vendor_id(config, vendor);
262 pci_config_set_device_id(config, device); 274 pci_config_set_device_id(config, device);
@@ -281,6 +293,8 @@ static void virtio_init_pci(VirtIOPCIProxy *proxy, VirtIODevice *vdev, @@ -281,6 +293,8 @@ static void virtio_init_pci(VirtIOPCIProxy *proxy, VirtIODevice *vdev,
281 pci_register_bar(&proxy->pci_dev, 0, size, PCI_ADDRESS_SPACE_IO, 293 pci_register_bar(&proxy->pci_dev, 0, size, PCI_ADDRESS_SPACE_IO,
282 virtio_map); 294 virtio_map);
283 295
  296 + qemu_register_reset(virtio_pci_reset, 0, proxy);
  297 +
284 virtio_bind_device(vdev, &virtio_pci_bindings, proxy); 298 virtio_bind_device(vdev, &virtio_pci_bindings, proxy);
285 } 299 }
286 300
hw/virtio.c
@@ -68,6 +68,7 @@ struct VirtQueue @@ -68,6 +68,7 @@ struct VirtQueue
68 target_phys_addr_t pa; 68 target_phys_addr_t pa;
69 uint16_t last_avail_idx; 69 uint16_t last_avail_idx;
70 int inuse; 70 int inuse;
  71 + uint16_t vector;
71 void (*handle_output)(VirtIODevice *vdev, VirtQueue *vq); 72 void (*handle_output)(VirtIODevice *vdev, VirtQueue *vq);
72 }; 73 };
73 74
@@ -421,12 +422,16 @@ int virtqueue_pop(VirtQueue *vq, VirtQueueElement *elem) @@ -421,12 +422,16 @@ int virtqueue_pop(VirtQueue *vq, VirtQueueElement *elem)
421 } 422 }
422 423
423 /* virtio device */ 424 /* virtio device */
  425 +static void virtio_notify_vector(VirtIODevice *vdev, uint16_t vector)
  426 +{
  427 + if (vdev->binding->notify) {
  428 + vdev->binding->notify(vdev->binding_opaque, vector);
  429 + }
  430 +}
424 431
425 void virtio_update_irq(VirtIODevice *vdev) 432 void virtio_update_irq(VirtIODevice *vdev)
426 { 433 {
427 - if (vdev->binding->update_irq) {  
428 - vdev->binding->update_irq(vdev->binding_opaque);  
429 - } 434 + virtio_notify_vector(vdev, VIRTIO_NO_VECTOR);
430 } 435 }
431 436
432 void virtio_reset(void *opaque) 437 void virtio_reset(void *opaque)
@@ -441,7 +446,8 @@ void virtio_reset(void *opaque) @@ -441,7 +446,8 @@ void virtio_reset(void *opaque)
441 vdev->queue_sel = 0; 446 vdev->queue_sel = 0;
442 vdev->status = 0; 447 vdev->status = 0;
443 vdev->isr = 0; 448 vdev->isr = 0;
444 - virtio_update_irq(vdev); 449 + vdev->config_vector = VIRTIO_NO_VECTOR;
  450 + virtio_notify_vector(vdev, vdev->config_vector);
445 451
446 for(i = 0; i < VIRTIO_PCI_QUEUE_MAX; i++) { 452 for(i = 0; i < VIRTIO_PCI_QUEUE_MAX; i++) {
447 vdev->vq[i].vring.desc = 0; 453 vdev->vq[i].vring.desc = 0;
@@ -449,6 +455,7 @@ void virtio_reset(void *opaque) @@ -449,6 +455,7 @@ void virtio_reset(void *opaque)
449 vdev->vq[i].vring.used = 0; 455 vdev->vq[i].vring.used = 0;
450 vdev->vq[i].last_avail_idx = 0; 456 vdev->vq[i].last_avail_idx = 0;
451 vdev->vq[i].pa = 0; 457 vdev->vq[i].pa = 0;
  458 + vdev->vq[i].vector = VIRTIO_NO_VECTOR;
452 } 459 }
453 } 460 }
454 461
@@ -532,12 +539,8 @@ void virtio_config_writel(VirtIODevice *vdev, uint32_t addr, uint32_t data) @@ -532,12 +539,8 @@ void virtio_config_writel(VirtIODevice *vdev, uint32_t addr, uint32_t data)
532 539
533 void virtio_queue_set_addr(VirtIODevice *vdev, int n, target_phys_addr_t addr) 540 void virtio_queue_set_addr(VirtIODevice *vdev, int n, target_phys_addr_t addr)
534 { 541 {
535 - if (addr == 0) {  
536 - virtio_reset(vdev);  
537 - } else {  
538 - vdev->vq[n].pa = addr;  
539 - virtqueue_init(&vdev->vq[n]);  
540 - } 542 + vdev->vq[n].pa = addr;
  543 + virtqueue_init(&vdev->vq[n]);
541 } 544 }
542 545
543 target_phys_addr_t virtio_queue_get_addr(VirtIODevice *vdev, int n) 546 target_phys_addr_t virtio_queue_get_addr(VirtIODevice *vdev, int n)
@@ -557,6 +560,18 @@ void virtio_queue_notify(VirtIODevice *vdev, int n) @@ -557,6 +560,18 @@ void virtio_queue_notify(VirtIODevice *vdev, int n)
557 } 560 }
558 } 561 }
559 562
  563 +uint16_t virtio_queue_vector(VirtIODevice *vdev, int n)
  564 +{
  565 + return n < VIRTIO_PCI_QUEUE_MAX ? vdev->vq[n].vector :
  566 + VIRTIO_NO_VECTOR;
  567 +}
  568 +
  569 +void virtio_queue_set_vector(VirtIODevice *vdev, int n, uint16_t vector)
  570 +{
  571 + if (n < VIRTIO_PCI_QUEUE_MAX)
  572 + vdev->vq[n].vector = vector;
  573 +}
  574 +
560 VirtQueue *virtio_add_queue(VirtIODevice *vdev, int queue_size, 575 VirtQueue *virtio_add_queue(VirtIODevice *vdev, int queue_size,
561 void (*handle_output)(VirtIODevice *, VirtQueue *)) 576 void (*handle_output)(VirtIODevice *, VirtQueue *))
562 { 577 {
@@ -585,7 +600,7 @@ void virtio_notify(VirtIODevice *vdev, VirtQueue *vq) @@ -585,7 +600,7 @@ void virtio_notify(VirtIODevice *vdev, VirtQueue *vq)
585 return; 600 return;
586 601
587 vdev->isr |= 0x01; 602 vdev->isr |= 0x01;
588 - virtio_update_irq(vdev); 603 + virtio_notify_vector(vdev, vq->vector);
589 } 604 }
590 605
591 void virtio_notify_config(VirtIODevice *vdev) 606 void virtio_notify_config(VirtIODevice *vdev)
@@ -594,7 +609,7 @@ void virtio_notify_config(VirtIODevice *vdev) @@ -594,7 +609,7 @@ void virtio_notify_config(VirtIODevice *vdev)
594 return; 609 return;
595 610
596 vdev->isr |= 0x03; 611 vdev->isr |= 0x03;
597 - virtio_update_irq(vdev); 612 + virtio_notify_vector(vdev, vdev->config_vector);
598 } 613 }
599 614
600 void virtio_save(VirtIODevice *vdev, QEMUFile *f) 615 void virtio_save(VirtIODevice *vdev, QEMUFile *f)
@@ -603,6 +618,7 @@ void virtio_save(VirtIODevice *vdev, QEMUFile *f) @@ -603,6 +618,7 @@ void virtio_save(VirtIODevice *vdev, QEMUFile *f)
603 618
604 /* FIXME: load/save binding. */ 619 /* FIXME: load/save binding. */
605 //pci_device_save(&vdev->pci_dev, f); 620 //pci_device_save(&vdev->pci_dev, f);
  621 + //msix_save(&vdev->pci_dev, f);
606 622
607 qemu_put_8s(f, &vdev->status); 623 qemu_put_8s(f, &vdev->status);
608 qemu_put_8s(f, &vdev->isr); 624 qemu_put_8s(f, &vdev->isr);
@@ -611,6 +627,9 @@ void virtio_save(VirtIODevice *vdev, QEMUFile *f) @@ -611,6 +627,9 @@ void virtio_save(VirtIODevice *vdev, QEMUFile *f)
611 qemu_put_be32(f, vdev->config_len); 627 qemu_put_be32(f, vdev->config_len);
612 qemu_put_buffer(f, vdev->config, vdev->config_len); 628 qemu_put_buffer(f, vdev->config, vdev->config_len);
613 629
  630 + if (vdev->nvectors)
  631 + qemu_put_be16s(f, &vdev->config_vector);
  632 +
614 for (i = 0; i < VIRTIO_PCI_QUEUE_MAX; i++) { 633 for (i = 0; i < VIRTIO_PCI_QUEUE_MAX; i++) {
615 if (vdev->vq[i].vring.num == 0) 634 if (vdev->vq[i].vring.num == 0)
616 break; 635 break;
@@ -625,6 +644,8 @@ void virtio_save(VirtIODevice *vdev, QEMUFile *f) @@ -625,6 +644,8 @@ void virtio_save(VirtIODevice *vdev, QEMUFile *f)
625 qemu_put_be32(f, vdev->vq[i].vring.num); 644 qemu_put_be32(f, vdev->vq[i].vring.num);
626 qemu_put_be64(f, vdev->vq[i].pa); 645 qemu_put_be64(f, vdev->vq[i].pa);
627 qemu_put_be16s(f, &vdev->vq[i].last_avail_idx); 646 qemu_put_be16s(f, &vdev->vq[i].last_avail_idx);
  647 + if (vdev->nvectors)
  648 + qemu_put_be16s(f, &vdev->vq[i].vector);
628 } 649 }
629 } 650 }
630 651
@@ -634,6 +655,7 @@ void virtio_load(VirtIODevice *vdev, QEMUFile *f) @@ -634,6 +655,7 @@ void virtio_load(VirtIODevice *vdev, QEMUFile *f)
634 655
635 /* FIXME: load/save binding. */ 656 /* FIXME: load/save binding. */
636 //pci_device_load(&vdev->pci_dev, f); 657 //pci_device_load(&vdev->pci_dev, f);
  658 + //r = msix_load(&vdev->pci_dev, f);
637 659
638 qemu_get_8s(f, &vdev->status); 660 qemu_get_8s(f, &vdev->status);
639 qemu_get_8s(f, &vdev->isr); 661 qemu_get_8s(f, &vdev->isr);
@@ -642,6 +664,10 @@ void virtio_load(VirtIODevice *vdev, QEMUFile *f) @@ -642,6 +664,10 @@ void virtio_load(VirtIODevice *vdev, QEMUFile *f)
642 vdev->config_len = qemu_get_be32(f); 664 vdev->config_len = qemu_get_be32(f);
643 qemu_get_buffer(f, vdev->config, vdev->config_len); 665 qemu_get_buffer(f, vdev->config, vdev->config_len);
644 666
  667 + if (vdev->nvectors) {
  668 + qemu_get_be16s(f, &vdev->config_vector);
  669 + //msix_vector_use(&vdev->pci_dev, vdev->config_vector);
  670 + }
645 num = qemu_get_be32(f); 671 num = qemu_get_be32(f);
646 672
647 for (i = 0; i < num; i++) { 673 for (i = 0; i < num; i++) {
@@ -652,9 +678,13 @@ void virtio_load(VirtIODevice *vdev, QEMUFile *f) @@ -652,9 +678,13 @@ void virtio_load(VirtIODevice *vdev, QEMUFile *f)
652 if (vdev->vq[i].pa) { 678 if (vdev->vq[i].pa) {
653 virtqueue_init(&vdev->vq[i]); 679 virtqueue_init(&vdev->vq[i]);
654 } 680 }
  681 + if (vdev->nvectors) {
  682 + qemu_get_be16s(f, &vdev->vq[i].vector);
  683 + //msix_vector_use(&vdev->pci_dev, vdev->config_vector);
  684 + }
655 } 685 }
656 686
657 - virtio_update_irq(vdev); 687 + virtio_notify_vector(vdev, VIRTIO_NO_VECTOR);
658 } 688 }
659 689
660 void virtio_cleanup(VirtIODevice *vdev) 690 void virtio_cleanup(VirtIODevice *vdev)
@@ -675,6 +705,7 @@ VirtIODevice *virtio_common_init(const char *name, uint16_t device_id, @@ -675,6 +705,7 @@ VirtIODevice *virtio_common_init(const char *name, uint16_t device_id,
675 vdev->status = 0; 705 vdev->status = 0;
676 vdev->isr = 0; 706 vdev->isr = 0;
677 vdev->queue_sel = 0; 707 vdev->queue_sel = 0;
  708 + vdev->config_vector = VIRTIO_NO_VECTOR;
678 vdev->vq = qemu_mallocz(sizeof(VirtQueue) * VIRTIO_PCI_QUEUE_MAX); 709 vdev->vq = qemu_mallocz(sizeof(VirtQueue) * VIRTIO_PCI_QUEUE_MAX);
679 710
680 vdev->name = name; 711 vdev->name = name;
@@ -684,8 +715,6 @@ VirtIODevice *virtio_common_init(const char *name, uint16_t device_id, @@ -684,8 +715,6 @@ VirtIODevice *virtio_common_init(const char *name, uint16_t device_id,
684 else 715 else
685 vdev->config = NULL; 716 vdev->config = NULL;
686 717
687 - qemu_register_reset(virtio_reset, 0, vdev);  
688 -  
689 return vdev; 718 return vdev;
690 } 719 }
691 720
hw/virtio.h
@@ -75,11 +75,13 @@ typedef struct VirtQueueElement @@ -75,11 +75,13 @@ typedef struct VirtQueueElement
75 } VirtQueueElement; 75 } VirtQueueElement;
76 76
77 typedef struct { 77 typedef struct {
78 - void (*update_irq)(void * opaque); 78 + void (*notify)(void * opaque, uint16_t vector);
79 } VirtIOBindings; 79 } VirtIOBindings;
80 80
81 #define VIRTIO_PCI_QUEUE_MAX 16 81 #define VIRTIO_PCI_QUEUE_MAX 16
82 82
  83 +#define VIRTIO_NO_VECTOR 0xffff
  84 +
83 struct VirtIODevice 85 struct VirtIODevice
84 { 86 {
85 const char *name; 87 const char *name;
@@ -89,6 +91,8 @@ struct VirtIODevice @@ -89,6 +91,8 @@ struct VirtIODevice
89 uint32_t features; 91 uint32_t features;
90 size_t config_len; 92 size_t config_len;
91 void *config; 93 void *config;
  94 + uint16_t config_vector;
  95 + int nvectors;
92 uint32_t (*get_features)(VirtIODevice *vdev); 96 uint32_t (*get_features)(VirtIODevice *vdev);
93 uint32_t (*bad_features)(VirtIODevice *vdev); 97 uint32_t (*bad_features)(VirtIODevice *vdev);
94 void (*set_features)(VirtIODevice *vdev, uint32_t val); 98 void (*set_features)(VirtIODevice *vdev, uint32_t val);
@@ -118,7 +122,7 @@ void virtio_notify(VirtIODevice *vdev, VirtQueue *vq); @@ -118,7 +122,7 @@ void virtio_notify(VirtIODevice *vdev, VirtQueue *vq);
118 122
119 void virtio_save(VirtIODevice *vdev, QEMUFile *f); 123 void virtio_save(VirtIODevice *vdev, QEMUFile *f);
120 124
121 -void virtio_load(VirtIODevice *vdev, QEMUFile *f); 125 +int virtio_load(VirtIODevice *vdev, QEMUFile *f);
122 126
123 void virtio_cleanup(VirtIODevice *vdev); 127 void virtio_cleanup(VirtIODevice *vdev);
124 128
@@ -144,6 +148,8 @@ void virtio_queue_set_addr(VirtIODevice *vdev, int n, target_phys_addr_t addr); @@ -144,6 +148,8 @@ void virtio_queue_set_addr(VirtIODevice *vdev, int n, target_phys_addr_t addr);
144 target_phys_addr_t virtio_queue_get_addr(VirtIODevice *vdev, int n); 148 target_phys_addr_t virtio_queue_get_addr(VirtIODevice *vdev, int n);
145 int virtio_queue_get_num(VirtIODevice *vdev, int n); 149 int virtio_queue_get_num(VirtIODevice *vdev, int n);
146 void virtio_queue_notify(VirtIODevice *vdev, int n); 150 void virtio_queue_notify(VirtIODevice *vdev, int n);
  151 +uint16_t virtio_queue_vector(VirtIODevice *vdev, int n);
  152 +void virtio_queue_set_vector(VirtIODevice *vdev, int n, uint16_t vector);
147 void virtio_reset(void *opaque); 153 void virtio_reset(void *opaque);
148 void virtio_update_irq(VirtIODevice *vdev); 154 void virtio_update_irq(VirtIODevice *vdev);
149 155